killbill-memoizeit

tenant: add multitenant support Api secret generation is

10/1/2012 9:03:46 PM

Changes

jaxrs/pom.xml 6(+5 -1)

junction/src/test/java/com/ning/billing/junction/blocking/MockBlockingChecker.java 56(+0 -56)

payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithEmbeddedDb.java 59(+0 -59)

pom.xml 21(+21 -0)

README.md 61(+61 -0)

server/pom.xml 14(+13 -1)

tenant/pom.xml 120(+120 -0)

Details

diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
index 4c7f93b..69dcc9e 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
@@ -20,9 +20,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTimeZone;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.account.api.AccountData;
@@ -30,6 +27,10 @@ import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.account.api.DefaultBillCycleDay;
 import com.ning.billing.catalog.api.Currency;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultAccountCreationEvent implements AccountCreationEvent {
 
     private final UUID userToken;
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index 4af997c..10c4f7e 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -23,7 +23,6 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -37,16 +36,24 @@ import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.account.dao.AccountEmailDao;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
+import com.google.inject.Inject;
+
 public class DefaultAccountUserApi implements AccountUserApi {
-    private final CallContextFactory factory;
+
+    private final CallContextFactory callContextFactory;
+    private final InternalCallContextFactory internalCallContextFactory;
     private final AccountDao accountDao;
     private final AccountEmailDao accountEmailDao;
 
     @Inject
-    public DefaultAccountUserApi(final CallContextFactory factory, final AccountDao accountDao, final AccountEmailDao accountEmailDao) {
-        this.factory = factory;
+    public DefaultAccountUserApi(final CallContextFactory callContextFactory, final InternalCallContextFactory internalCallContextFactory,
+                                 final AccountDao accountDao, final AccountEmailDao accountEmailDao) {
+        this.callContextFactory = callContextFactory;
+        this.internalCallContextFactory = internalCallContextFactory;
         this.accountDao = accountDao;
         this.accountEmailDao = accountEmailDao;
     }
@@ -56,7 +63,7 @@ public class DefaultAccountUserApi implements AccountUserApi {
         final Account account = new DefaultAccount(data);
 
         try {
-            accountDao.create(account, context);
+            accountDao.create(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
         } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, ErrorCode.ACCOUNT_CREATION_FAILED);
         }
@@ -65,8 +72,8 @@ public class DefaultAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public Account getAccountByKey(final String key) throws AccountApiException {
-        final Account account = accountDao.getAccountByKey(key);
+    public Account getAccountByKey(final String key, final TenantContext context) throws AccountApiException {
+        final Account account = accountDao.getAccountByKey(key, internalCallContextFactory.createInternalTenantContext(context));
         if (account == null) {
             throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, key);
         }
@@ -74,8 +81,8 @@ public class DefaultAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public Account getAccountById(final UUID id) throws AccountApiException {
-        final Account account = accountDao.getById(id);
+    public Account getAccountById(final UUID id, final TenantContext context) throws AccountApiException {
+        final Account account = accountDao.getById(id, internalCallContextFactory.createInternalTenantContext(id, context));
         if (account == null) {
             throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, id);
         }
@@ -83,19 +90,19 @@ public class DefaultAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public List<Account> getAccounts() {
-        return accountDao.get();
+    public List<Account> getAccounts(final TenantContext context) {
+        return accountDao.get(internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public UUID getIdFromKey(final String externalKey) throws AccountApiException {
-        return accountDao.getIdFromKey(externalKey);
+    public UUID getIdFromKey(final String externalKey, final TenantContext context) throws AccountApiException {
+        return accountDao.getIdFromKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
     public void updateAccount(final Account account, final CallContext context) throws AccountApiException {
         try {
-            accountDao.update(account, context);
+            accountDao.update(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
         } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
         }
@@ -107,7 +114,7 @@ public class DefaultAccountUserApi implements AccountUserApi {
         final Account account = new DefaultAccount(accountId, accountData);
 
         try {
-            accountDao.update(account, context);
+            accountDao.update(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
         } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, e.getCode(), e.getMessage());
         }
@@ -115,7 +122,7 @@ public class DefaultAccountUserApi implements AccountUserApi {
 
     @Override
     public void updateAccount(final String externalKey, final AccountData accountData, final CallContext context) throws AccountApiException {
-        final UUID accountId = getIdFromKey(externalKey);
+        final UUID accountId = getIdFromKey(externalKey, context);
         if (accountId == null) {
             throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
         }
@@ -127,12 +134,12 @@ public class DefaultAccountUserApi implements AccountUserApi {
             throws AccountApiException {
         final DateTime createdDate = data.getCreatedDate() == null ? context.getCreatedDate() : data.getCreatedDate();
         final DateTime updatedDate = data.getUpdatedDate() == null ? context.getUpdatedDate() : data.getUpdatedDate();
-        final CallContext migrationContext = factory.toMigrationCallContext(context, createdDate, updatedDate);
+        final CallContext migrationContext = callContextFactory.toMigrationCallContext(context, createdDate, updatedDate);
         final Account account = new DefaultAccount(data);
 
         try {
-            accountDao.create(account, migrationContext);
-            for (String cur : data.getAdditionalContactEmails()) {
+            accountDao.create(account, internalCallContextFactory.createInternalCallContext(account.getId(), migrationContext));
+            for (final String cur : data.getAdditionalContactEmails()) {
                 addEmail(account.getId(), new DefaultAccountEmail(account.getId(), cur), migrationContext);
             }
         } catch (EntityPersistenceException e) {
@@ -143,23 +150,23 @@ public class DefaultAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public List<AccountEmail> getEmails(final UUID accountId) {
-        return accountEmailDao.getEmails(accountId);
+    public List<AccountEmail> getEmails(final UUID accountId, final TenantContext context) {
+        return accountEmailDao.getEmails(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
     public void saveEmails(final UUID accountId, final List<AccountEmail> newEmails, final CallContext context) {
-        accountEmailDao.saveEmails(accountId, newEmails, context);
+        accountEmailDao.saveEmails(accountId, newEmails, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
     public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
-        accountEmailDao.addEmail(accountId, email, context);
+        accountEmailDao.addEmail(accountId, email, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
     public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
-        accountEmailDao.removeEmail(accountId, email, context);
+        accountEmailDao.removeEmail(accountId, email, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
@@ -167,12 +174,11 @@ public class DefaultAccountUserApi implements AccountUserApi {
         updatePaymentMethod(accountId, null, context);
     }
 
-
     @Override
     public void updatePaymentMethod(final UUID accountId, @Nullable final UUID paymentMethodId, final CallContext context) throws AccountApiException {
         try {
-            accountDao.updatePaymentMethod(accountId, paymentMethodId, context);
-        }  catch (EntityPersistenceException e) {
+            accountDao.updatePaymentMethod(accountId, paymentMethodId, internalCallContextFactory.createInternalCallContext(accountId, context));
+        } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, e.getCode(), e.getMessage());
         }
     }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index 0eb7907..c7dd36f 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -20,24 +20,23 @@ import java.util.UUID;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.entity.dao.UpdatableEntityDao;
 
 public interface AccountDao extends UpdatableEntityDao<Account> {
-    public Account getAccountByKey(String key);
+
+    public Account getAccountByKey(String key, InternalTenantContext context);
 
     /**
-     * @param externalKey
-     * @return
      * @throws AccountApiException when externalKey is null
      */
-    public UUID getIdFromKey(String externalKey) throws AccountApiException;
+    public UUID getIdFromKey(String externalKey, InternalTenantContext context) throws AccountApiException;
 
     /**
-     *
-     * @param accountId the id of the account
+     * @param accountId       the id of the account
      * @param paymentMethodId the is of the current default paymentMethod
      */
-    public void updatePaymentMethod(UUID accountId, UUID paymentMethodId, final CallContext context) throws EntityPersistenceException;
+    public void updatePaymentMethod(UUID accountId, UUID paymentMethodId, InternalCallContext context) throws EntityPersistenceException;
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
index 09f2cda..2abcbbb 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
@@ -20,10 +20,13 @@ import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.entity.dao.EntityDao;
 
-public interface AccountEmailDao {
-    public List<AccountEmail> getEmails(UUID accountId);
+public interface AccountEmailDao extends EntityDao<AccountEmail> {
+
+    public List<AccountEmail> getEmails(UUID accountId, InternalTenantContext context);
 
     /**
      * Add, remove or update the list of emails in this account.
@@ -32,11 +35,9 @@ public interface AccountEmailDao {
      * @param emails    the final list of emails
      * @param context   the call context
      */
-    public void saveEmails(UUID accountId, List<AccountEmail> emails, CallContext context);
-
-    public void addEmail(UUID accountId, AccountEmail email, CallContext context);
+    public void saveEmails(UUID accountId, List<AccountEmail> emails, InternalCallContext context);
 
-    public void removeEmail(UUID accountId, AccountEmail email, CallContext context);
+    public void addEmail(UUID accountId, AccountEmail email, InternalCallContext context);
 
-    public void test();
+    public void removeEmail(UUID accountId, AccountEmail email, InternalCallContext context);
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
index 589a028..2f3b02d 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
@@ -27,8 +27,8 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.ObjectTypeBinder;
@@ -37,31 +37,32 @@ import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlD
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(AccountEmailMapper.class)
 public interface AccountEmailSqlDao extends UpdatableEntityCollectionSqlDao<AccountEmail>, Transactional<AccountEmailSqlDao>, Transmogrifier {
+
     @Override
     @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void addHistoryFromTransaction(@Bind("objectId") final String objectId,
                                           @ObjectTypeBinder final ObjectType objectType,
                                           @AccountEmailHistoryBinder final List<EntityHistory<AccountEmail>> entities,
-                                          @CallContextBinder final CallContext context);
+                                          @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index 8afc174..aa08ee5 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -27,8 +27,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.UuidMapper;
 import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
@@ -36,25 +37,32 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper({UuidMapper.class, AccountMapper.class})
 public interface AccountSqlDao extends UpdatableEntitySqlDao<Account>, Transactional<AccountSqlDao>, Transmogrifier {
+
     @SqlQuery
-    public Account getAccountByKey(@Bind("externalKey") final String key);
+    public Account getAccountByKey(@Bind("externalKey") final String key,
+                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public UUID getIdFromKey(@Bind("externalKey") final String key);
+    public UUID getIdFromKey(@Bind("externalKey") final String key,
+                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
-    public void create(@AccountBinder Account account, @CallContextBinder final CallContext context);
+    public void create(@AccountBinder Account account,
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlUpdate
-    public void update(@AccountBinder Account account, @CallContextBinder final CallContext context);
+    public void update(@AccountBinder Account account,
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void updatePaymentMethod(@Bind("id") String accountId, @Bind("paymentMethodId") String paymentMethodId, @CallContextBinder final CallContext context);
+    public void updatePaymentMethod(@Bind("id") String accountId,
+                                    @Bind("paymentMethodId") String paymentMethodId,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlUpdate
     public void insertHistoryFromTransaction(@AccountHistoryBinder final EntityHistory<Account> account,
-                                             @CallContextBinder final CallContext context);
+                                             @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
index 3384230..b770d14 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
@@ -26,7 +26,6 @@ import org.skife.jdbi.v2.TransactionStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -37,13 +36,17 @@ import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.TableName;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
+import com.google.inject.Inject;
+
 public class AuditedAccountDao implements AccountDao {
+
     private static final Logger log = LoggerFactory.getLogger(AuditedAccountDao.class);
 
     private final AccountSqlDao accountSqlDao;
@@ -56,36 +59,41 @@ public class AuditedAccountDao implements AccountDao {
     }
 
     @Override
-    public Account getAccountByKey(final String key) {
-        return accountSqlDao.getAccountByKey(key);
+    public Account getAccountByKey(final String key, final InternalTenantContext context) {
+        return accountSqlDao.getAccountByKey(key, context);
     }
 
     @Override
-    public UUID getIdFromKey(final String externalKey) throws AccountApiException {
+    public UUID getIdFromKey(final String externalKey, final InternalTenantContext context) throws AccountApiException {
         if (externalKey == null) {
             throw new AccountApiException(ErrorCode.ACCOUNT_CANNOT_MAP_NULL_KEY, "");
         }
-        return accountSqlDao.getIdFromKey(externalKey);
+        return accountSqlDao.getIdFromKey(externalKey, context);
+    }
+
+    @Override
+    public Account getById(final UUID id, final InternalTenantContext context) {
+        return accountSqlDao.getById(id.toString(), context);
     }
 
     @Override
-    public Account getById(final UUID id) {
-        return accountSqlDao.getById(id.toString());
+    public List<Account> get(final InternalTenantContext context) {
+        return accountSqlDao.get(context);
     }
 
     @Override
-    public List<Account> get() {
-        return accountSqlDao.get();
+    public Long getRecordId(final UUID id, final InternalTenantContext context) {
+        return accountSqlDao.getRecordId(id.toString(), context);
     }
 
     @Override
-    public void create(final Account account, final CallContext context) throws EntityPersistenceException {
+    public void create(final Account account, final InternalCallContext context) throws EntityPersistenceException {
         final String key = account.getExternalKey();
         try {
             accountSqlDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
                 @Override
                 public Void inTransaction(final AccountSqlDao transactionalDao, final TransactionStatus status) throws AccountApiException, Bus.EventBusException {
-                    final Account currentAccount = transactionalDao.getAccountByKey(key);
+                    final Account currentAccount = transactionalDao.getAccountByKey(key, context);
                     if (currentAccount != null) {
                         throw new AccountApiException(ErrorCode.ACCOUNT_ALREADY_EXISTS, key);
                     }
@@ -93,12 +101,12 @@ public class AuditedAccountDao implements AccountDao {
                     transactionalDao.create(account, context);
 
                     // Insert history
-                    final Long recordId = accountSqlDao.getRecordId(account.getId().toString());
+                    final Long recordId = accountSqlDao.getRecordId(account.getId().toString(), context);
                     final EntityHistory<Account> history = new EntityHistory<Account>(account.getId(), recordId, account, ChangeType.INSERT);
                     accountSqlDao.insertHistoryFromTransaction(history, context);
 
                     // Insert audit
-                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
+                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId, context);
                     final EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.INSERT);
                     accountSqlDao.insertAuditFromTransaction(audit, context);
 
@@ -123,13 +131,13 @@ public class AuditedAccountDao implements AccountDao {
     }
 
     @Override
-    public void update(final Account specifiedAccount, final CallContext context) throws EntityPersistenceException {
+    public void update(final Account specifiedAccount, final InternalCallContext context) throws EntityPersistenceException {
         try {
             accountSqlDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
                 @Override
                 public Void inTransaction(final AccountSqlDao transactional, final TransactionStatus status) throws EntityPersistenceException, Bus.EventBusException {
                     final UUID accountId = specifiedAccount.getId();
-                    final Account currentAccount = transactional.getById(accountId.toString());
+                    final Account currentAccount = transactional.getById(accountId.toString(), context);
                     if (currentAccount == null) {
                         throw new EntityPersistenceException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
                     }
@@ -139,11 +147,11 @@ public class AuditedAccountDao implements AccountDao {
 
                     transactional.update(account, context);
 
-                    final Long recordId = accountSqlDao.getRecordId(accountId.toString());
+                    final Long recordId = accountSqlDao.getRecordId(accountId.toString(), context);
                     final EntityHistory<Account> history = new EntityHistory<Account>(accountId, recordId, account, ChangeType.UPDATE);
                     accountSqlDao.insertHistoryFromTransaction(history, context);
 
-                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
+                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId, context);
                     final EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.UPDATE);
                     accountSqlDao.insertAuditFromTransaction(audit, context);
 
@@ -168,31 +176,31 @@ public class AuditedAccountDao implements AccountDao {
     }
 
     @Override
-    public void test() {
-        accountSqlDao.test();
+    public void test(final InternalTenantContext context) {
+        accountSqlDao.test(context);
     }
 
     @Override
-    public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, final CallContext context) throws EntityPersistenceException {
+    public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, final InternalCallContext context) throws EntityPersistenceException {
         try {
             accountSqlDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
                 @Override
                 public Void inTransaction(final AccountSqlDao transactional, final TransactionStatus status) throws EntityPersistenceException, Bus.EventBusException {
 
-                    final Account currentAccount = transactional.getById(accountId.toString());
+                    final Account currentAccount = transactional.getById(accountId.toString(), context);
                     if (currentAccount == null) {
                         throw new EntityPersistenceException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
                     }
                     final String thePaymentMethodId = paymentMethodId != null ? paymentMethodId.toString() : null;
                     transactional.updatePaymentMethod(accountId.toString(), thePaymentMethodId, context);
 
-                    final Account account = transactional.getById(accountId.toString());
+                    final Account account = transactional.getById(accountId.toString(), context);
 
-                    final Long recordId = accountSqlDao.getRecordId(accountId.toString());
+                    final Long recordId = accountSqlDao.getRecordId(accountId.toString(), context);
                     final EntityHistory<Account> history = new EntityHistory<Account>(accountId, recordId, account, ChangeType.UPDATE);
                     accountSqlDao.insertHistoryFromTransaction(history, context);
 
-                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
+                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId, context);
                     final EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.UPDATE);
                     accountSqlDao.insertAuditFromTransaction(audit, context);
 
diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
index ef66d03..a3428f4 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
@@ -27,17 +27,21 @@ import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.google.common.collect.ImmutableList;
-import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountEmail;
 import com.ning.billing.account.api.DefaultAccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.AuditedCollectionDaoBase;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.TableName;
+import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlDao;
 
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+
 public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmail, AccountEmail> implements AccountEmailDao {
+
     private final AccountEmailSqlDao accountEmailSqlDao;
 
     @Inject
@@ -46,28 +50,48 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
     }
 
     @Override
+    public void create(final AccountEmail entity, final InternalCallContext context) throws EntityPersistenceException {
+        saveEmails(entity.getAccountId(), ImmutableList.<AccountEmail>of(entity), context);
+    }
+
+    @Override
+    public Long getRecordId(final UUID id, final InternalTenantContext context) {
+        return accountEmailSqlDao.getRecordId(id.toString(), context);
+    }
+
+    @Override
+    public AccountEmail getById(final UUID id, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AccountEmail> get(final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     protected AccountEmail getEquivalenceObjectFor(final AccountEmail obj) {
         return obj;
     }
 
     @Override
-    public List<AccountEmail> getEmails(final UUID accountId) {
-        return new ArrayList<AccountEmail>(super.loadEntities(accountId, ObjectType.ACCOUNT_EMAIL).values());
+    public List<AccountEmail> getEmails(final UUID accountId, final InternalTenantContext context) {
+        return new ArrayList<AccountEmail>(super.loadEntities(accountId, ObjectType.ACCOUNT_EMAIL, context).values());
     }
 
     @Override
-    public void saveEmails(final UUID accountId, final List<AccountEmail> emails, final CallContext context) {
+    public void saveEmails(final UUID accountId, final List<AccountEmail> emails, final InternalCallContext context) {
         super.saveEntities(accountId, ObjectType.ACCOUNT_EMAIL, emails, context);
     }
 
     @Override
-    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+    public void addEmail(final UUID accountId, final AccountEmail email, final InternalCallContext context) {
         accountEmailSqlDao.inTransaction(new Transaction<Object, AccountEmailSqlDao>() {
             @Override
             public Object inTransaction(final AccountEmailSqlDao transactional, final TransactionStatus status) throws Exception {
                 // Compute the final list of emails by looking up the current ones and adding the new one
                 // We can use a simple set here as the supplied email may not have its id field populated
-                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL);
+                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL, context);
                 final Map<String, AccountEmail> newEmails = new HashMap<String, AccountEmail>();
                 for (final AccountEmail currentEmail : currentEmails) {
                     newEmails.put(currentEmail.getEmail(), currentEmail);
@@ -77,7 +101,7 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
                 // here and will confuse AuditedCollectionDaoBase).
                 newEmails.put(email.getEmail(), new DefaultAccountEmail(email.getAccountId(), email.getEmail()));
 
-                saveEntitiesFromTransaction(getSqlDao(), accountId, ObjectType.ACCOUNT_EMAIL,
+                saveEntitiesFromTransaction(getSqlDao(context), accountId, ObjectType.ACCOUNT_EMAIL,
                                             ImmutableList.<AccountEmail>copyOf(newEmails.values()), context);
 
                 return null;
@@ -86,20 +110,20 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
     }
 
     @Override
-    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+    public void removeEmail(final UUID accountId, final AccountEmail email, final InternalCallContext context) {
         accountEmailSqlDao.inTransaction(new Transaction<Object, AccountEmailSqlDao>() {
             @Override
             public Object inTransaction(final AccountEmailSqlDao transactional, final TransactionStatus status) throws Exception {
                 // Compute the final list of emails by looking up the current ones and removing the new one
                 // We can use a simple set here as the supplied email may not have its id field populated
-                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL);
+                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL, context);
                 final Map<String, AccountEmail> newEmails = new HashMap<String, AccountEmail>();
                 for (final AccountEmail currentEmail : currentEmails) {
                     newEmails.put(currentEmail.getEmail(), currentEmail);
                 }
                 newEmails.remove(email.getEmail());
 
-                saveEntitiesFromTransaction(getSqlDao(), accountId, ObjectType.ACCOUNT_EMAIL,
+                saveEntitiesFromTransaction(getSqlDao(context), accountId, ObjectType.ACCOUNT_EMAIL,
                                             ImmutableList.<AccountEmail>copyOf(newEmails.values()), context);
 
                 return null;
@@ -108,27 +132,27 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
     }
 
     @Override
-    public String getKey(final AccountEmail entity) {
+    public String getKey(final AccountEmail entity, final InternalTenantContext context) {
         return entity.getEmail();
     }
 
     @Override
-    public void test() {
-        accountEmailSqlDao.test();
+    public void test(final InternalTenantContext context) {
+        accountEmailSqlDao.test(context);
     }
 
     @Override
-    protected TableName getTableName() {
+    protected TableName getTableName(final InternalTenantContext context) {
         return TableName.ACCOUNT_EMAIL_HISTORY;
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<AccountEmail> transmogrifyDao(final Transmogrifier transactionalDao) {
+    protected UpdatableEntityCollectionSqlDao<AccountEmail> transmogrifyDao(final Transmogrifier transactionalDao, final InternalTenantContext context) {
         return transactionalDao.become(AccountEmailSqlDao.class);
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<AccountEmail> getSqlDao() {
+    protected UpdatableEntityCollectionSqlDao<AccountEmail> getSqlDao(final InternalTenantContext context) {
         return accountEmailSqlDao;
     }
 }
diff --git a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
index 956d878..e6458d0 100644
--- a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
+++ b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.account.glue;
 
-
-import com.google.inject.AbstractModule;
 import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.account.api.DefaultAccountService;
@@ -28,6 +26,8 @@ import com.ning.billing.account.dao.AuditedAccountDao;
 import com.ning.billing.account.dao.AuditedAccountEmailDao;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.AbstractModule;
+
 public class AccountModule extends AbstractModule {
     private void installConfig() {
     }
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountEmailSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountEmailSqlDao.sql.stg
index e867533..6ded4ea 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountEmailSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountEmailSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group account_emails;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>id,
     <prefix>account_id,
@@ -7,61 +10,64 @@ fields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertFromTransaction() ::= <<
     INSERT INTO account_emails(<fields()>)
-    VALUES (:id, :accountId, :email, :userName, :createdDate, :userName, :updatedDate);
+    VALUES (:id, :accountId, :email, :userName, :createdDate, :userName, :updatedDate, :accountRecordId, :tenantRecordId);
 >>
 
 updateFromTransaction() ::= <<
     UPDATE account_emails
     SET email = :email, updated_by = :userName, updated_date = :updatedDate
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 deleteFromTransaction() ::= <<
     DELETE FROM account_emails
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 addHistoryFromTransaction() ::= <<
-    INSERT INTO account_email_history(record_id, id, account_id, email, change_type, updated_by, date)
-    VALUES (:recordId, :id, :accountId, :email, :changeType, :userName, :updatedDate);
+    INSERT INTO account_email_history(record_id, id, account_id, email, change_type, updated_by, date, account_record_id, tenant_record_id)
+    VALUES (:recordId, :id, :accountId, :email, :changeType, :userName, :updatedDate, :accountRecordId, :tenantRecordId);
 >>
 
 load() ::= <<
-    SELECT <fields()> FROM account_emails WHERE account_id = :objectId;
+    SELECT <fields()> FROM account_emails WHERE account_id = :objectId <AND_CHECK_TENANT()>;
 >>
 
 getRecordIds() ::= <<
     SELECT record_id, id
     FROM account_emails
-    WHERE account_id = :objectId;
+    WHERE account_id = :objectId <AND_CHECK_TENANT()>;
 >>
 
 getMaxHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
-    FROM account_email_history;
+    FROM account_email_history
+    WHERE <CHECK_TENANT()>;
 >>
 
 getHistoryRecordIds() ::= <<
     SELECT history_record_id, record_id
     FROM account_email_history
-    WHERE history_record_id > :maxHistoryRecordId;
+    WHERE history_record_id > :maxHistoryRecordId <AND_CHECK_TENANT()>;
 >>
 
 getById() ::= <<
-    SELECT <fields()> FROM account_emails WHERE id = :id;
+    SELECT <fields()> FROM account_emails WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 get() ::= <<
-    SELECT <fields()> FROM account_emails;
+    SELECT <fields()> FROM account_emails WHERE <CHECK_TENANT()>;
 >>
 
 getByAccountId() ::= <<
-    SELECT <fields()> FROM account_emails WHERE account_id = :accountId;
+    SELECT <fields()> FROM account_emails WHERE account_id = :accountId <AND_CHECK_TENANT()>;
 >>
 
 auditFields(prefix) ::= <<
@@ -72,14 +78,16 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
-    SELECT 1 FROM account_emails;
->>
\ No newline at end of file
+    SELECT 1 FROM account_emails where <CHECK_TENANT()>;
+>>
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
index 8a8c0ce..bcf42ef 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group AccountDaoSql;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 accountFields(prefix) ::= <<
     <prefix>id,
     <prefix>external_key,
@@ -25,7 +28,8 @@ accountFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>tenant_record_id
 >>
 
 create() ::= <<
@@ -34,8 +38,8 @@ create() ::= <<
     VALUES
       (:id, :externalKey, :email, :name, :firstNameLength, :currency, :billingCycleDayLocal,
        :billingCycleDayUTC, :paymentMethodId, :timeZone, :locale,
-      :address1, :address2, :companyName, :city, :stateOrProvince, :country, :postalCode, :phone,
-      :migrated, :isNotifiedForInvoices, :userName, :createdDate, :userName, :updatedDate);
+       :address1, :address2, :companyName, :city, :stateOrProvince, :country, :postalCode, :phone,
+       :migrated, :isNotifiedForInvoices, :userName, :createdDate, :userName, :updatedDate, :tenantRecordId);
 >>
 
 update() ::= <<
@@ -46,7 +50,7 @@ update() ::= <<
         address1 = :address1, address2 = :address2, company_name = :companyName, city = :city, state_or_province = :stateOrProvince,
         country = :country, postal_code = :postalCode, phone = :phone,
         is_notified_for_invoices = :isNotifiedForInvoices, updated_date = :updatedDate, updated_by = :userName
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 
@@ -55,7 +59,7 @@ updatePaymentMethod() ::= <<
     SET payment_method_id = :paymentMethodId
     , updated_date = :updatedDate
     , updated_by = :userName
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 
@@ -84,19 +88,20 @@ historyFields() ::= <<
     is_notified_for_invoices,
     change_type,
     updated_by,
-    date
+    date,
+    tenant_record_id
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM accounts
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 getHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
     FROM account_history
-    WHERE record_id = :recordId;
+    WHERE record_id = :recordId <AND_CHECK_TENANT()>;
 >>
 
 insertHistoryFromTransaction() ::= <<
@@ -105,30 +110,31 @@ insertHistoryFromTransaction() ::= <<
     (:recordId, :id, :externalKey, :email, :name, :firstNameLength, :currency,
      :billingCycleDayLocal, :billingCycleDayUTC, :paymentMethodId, :timeZone, :locale,
      :address1, :address2, :companyName, :city, :stateOrProvince,
-     :country, :postalCode, :phone, :migrated, :isNotifiedForInvoices, :changeType, :userName, :createdDate);
+     :country, :postalCode, :phone, :migrated, :isNotifiedForInvoices, :changeType, :userName, :createdDate, :tenantRecordId);
 >>
 
 getAccountByKey() ::= <<
     select <accountFields()>
     from accounts
-    where external_key = :externalKey;
+    where external_key = :externalKey <AND_CHECK_TENANT()>;
 >>
 
 getById() ::= <<
     SELECT <accountFields()>
     FROM accounts
-    WHERE id = :id;
+    WHERE id = :id <AND_CHECK_TENANT()>;
 >>
 
 get() ::= <<
     SELECT <accountFields()>
-    FROM accounts;
+    FROM accounts
+    WHERE <CHECK_TENANT()>;
 >>
 
 getIdFromKey() ::= <<
     SELECT id
     FROM accounts
-    WHERE external_key = :externalKey;
+    WHERE external_key = :externalKey <AND_CHECK_TENANT()>;
 >>
 
 auditFields(prefix) ::= <<
@@ -139,15 +145,16 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :tenantRecordId);
 >>
 
 test() ::= <<
-    SELECT 1 FROM accounts;
+    SELECT 1 FROM accounts WHERE <CHECK_TENANT()>;
 >>
 ;
diff --git a/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java b/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
index 06ea212..ed1ad17 100644
--- a/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
+++ b/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
@@ -39,11 +39,15 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public class TestDefaultAccountUserApi extends AccountTestSuite {
 
     private final CallContextFactory factory = Mockito.mock(CallContextFactory.class);
+    private final InternalCallContextFactory internalFactory = Mockito.mock(InternalCallContextFactory.class);
     private final CallContext callContext = Mockito.mock(CallContext.class);
+    private final InternalTenantContext tenantContext = Mockito.mock(InternalTenantContext.class);
 
     private AccountDao accountDao;
     private AccountEmailDao accountEmailDao;
@@ -53,7 +57,7 @@ public class TestDefaultAccountUserApi extends AccountTestSuite {
     public void setUp() throws Exception {
         accountDao = new MockAccountDao(Mockito.mock(Bus.class));
         accountEmailDao = new MockAccountEmailDao();
-        accountUserApi = new DefaultAccountUserApi(factory, accountDao, accountEmailDao);
+        accountUserApi = new DefaultAccountUserApi(factory, internalFactory, accountDao, accountEmailDao);
     }
 
     @Test(groups = "fast")
@@ -84,7 +88,7 @@ public class TestDefaultAccountUserApi extends AccountTestSuite {
 
         accountUserApi.createAccount(data, callContext);
 
-        final Account account = accountDao.getAccountByKey(externalKey);
+        final Account account = accountDao.getAccountByKey(externalKey, tenantContext);
         Assert.assertEquals(account.getExternalKey(), externalKey);
         Assert.assertEquals(account.getEmail(), email);
         Assert.assertEquals(account.getName(), name);
@@ -111,20 +115,20 @@ public class TestDefaultAccountUserApi extends AccountTestSuite {
         final UUID accountId = UUID.randomUUID();
 
         // Verify the initial state
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, tenantContext).size(), 0);
 
         // Add the first email
         final String email1 = UUID.randomUUID().toString();
         accountUserApi.addEmail(accountId, new DefaultAccountEmail(accountId, email1), callContext);
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, tenantContext).size(), 1);
 
         // Add a second one
         final String email2 = UUID.randomUUID().toString();
         accountUserApi.addEmail(accountId, new DefaultAccountEmail(accountId, email2), callContext);
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 2);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, tenantContext).size(), 2);
 
         // Remove the first second one
         accountUserApi.removeEmail(accountId, new DefaultAccountEmail(accountId, email1), callContext);
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, tenantContext).size(), 1);
     }
 }
diff --git a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
index 463afe7..cb4e87f 100644
--- a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
@@ -26,24 +26,18 @@ import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.bus.InMemoryBus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 
 import static org.testng.Assert.fail;
 
 public abstract class AccountDaoTestBase extends AccountTestSuiteWithEmbeddedDB {
+
     protected final TagEventBuilder tagEventBuilder = new TagEventBuilder();
 
     protected AccountDao accountDao;
     protected AccountEmailDao accountEmailDao;
     protected IDBI dbi;
     protected Bus bus;
-    protected CallContext context;
 
     @BeforeClass(groups = "slow")
     protected void setup() throws IOException {
@@ -56,14 +50,11 @@ public abstract class AccountDaoTestBase extends AccountTestSuiteWithEmbeddedDB 
 
             accountDao = new AuditedAccountDao(dbi, bus);
             // Health check test to make sure MySQL is setup properly
-            accountDao.test();
+            accountDao.test(internalCallContext);
 
             accountEmailDao = new AuditedAccountEmailDao(dbi);
             // Health check test to make sure MySQL is setup properly
-            accountEmailDao.test();
-
-            final Clock clock = new ClockMock();
-            context = new DefaultCallContextFactory(clock).createCallContext("Account Dao Tests", CallOrigin.TEST, UserType.TEST);
+            accountEmailDao.test(internalCallContext);
         } catch (Throwable t) {
             fail(t.toString());
         }
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index e525957..9aff9e2 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -22,17 +22,20 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.user.DefaultAccountChangeEvent;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
+import com.google.inject.Inject;
+
 public class MockAccountDao implements AccountDao {
+
     private final Bus eventBus;
     private final Map<UUID, Account> accounts = new ConcurrentHashMap<UUID, Account>();
 
@@ -42,7 +45,12 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public void create(final Account account, final CallContext context) {
+    public Long getRecordId(final UUID id, final InternalTenantContext context) {
+        return 1L;
+    }
+
+    @Override
+    public void create(final Account account, final InternalCallContext context) {
         accounts.put(account.getId(), account);
 
         try {
@@ -53,21 +61,21 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public Account getById(final UUID id) {
+    public Account getById(final UUID id, final InternalTenantContext context) {
         return accounts.get(id);
     }
 
     @Override
-    public List<Account> get() {
+    public List<Account> get(final InternalTenantContext context) {
         return new ArrayList<Account>(accounts.values());
     }
 
     @Override
-    public void test() {
+    public void test(final InternalTenantContext context) {
     }
 
     @Override
-    public Account getAccountByKey(final String externalKey) {
+    public Account getAccountByKey(final String externalKey, final InternalTenantContext context) {
         for (final Account account : accounts.values()) {
             if (externalKey.equals(account.getExternalKey())) {
                 return account;
@@ -77,13 +85,13 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public UUID getIdFromKey(final String externalKey) {
-        final Account account = getAccountByKey(externalKey);
+    public UUID getIdFromKey(final String externalKey, final InternalTenantContext context) {
+        final Account account = getAccountByKey(externalKey, context);
         return account == null ? null : account.getId();
     }
 
     @Override
-    public void update(final Account account, final CallContext context) {
+    public void update(final Account account, final InternalCallContext context) {
         final Account currentAccount = accounts.put(account.getId(), account);
 
         final AccountChangeEvent changeEvent = new DefaultAccountChangeEvent(account.getId(), null, currentAccount, account);
@@ -97,9 +105,6 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public void updatePaymentMethod(UUID accountId, UUID paymentMethodId,
-            CallContext context) throws EntityPersistenceException {
-        // TODO Auto-generated method stub
-
+    public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, final InternalCallContext context) throws EntityPersistenceException {
     }
 }
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java
index 933ca54..e6951ae 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java
@@ -23,15 +23,39 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+import com.google.common.collect.ImmutableList;
 
 public class MockAccountEmailDao implements AccountEmailDao {
+
     private final Map<UUID, Set<AccountEmail>> emails = new ConcurrentHashMap<UUID, Set<AccountEmail>>();
 
     @Override
-    public List<AccountEmail> getEmails(final UUID accountId) {
+    public void create(final AccountEmail entity, final InternalCallContext context) throws EntityPersistenceException {
+        saveEmails(entity.getAccountId(), ImmutableList.<AccountEmail>of(entity), context);
+    }
+
+    @Override
+    public Long getRecordId(final UUID id, final InternalTenantContext context) {
+        return 1L;
+    }
+
+    @Override
+    public AccountEmail getById(final UUID id, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AccountEmail> get(final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AccountEmail> getEmails(final UUID accountId, final InternalTenantContext context) {
         final Set<AccountEmail> accountEmails = emails.get(accountId);
         if (accountEmails == null) {
             return ImmutableList.<AccountEmail>of();
@@ -41,7 +65,7 @@ public class MockAccountEmailDao implements AccountEmailDao {
     }
 
     @Override
-    public void saveEmails(final UUID accountId, final List<AccountEmail> newEmails, final CallContext context) {
+    public void saveEmails(final UUID accountId, final List<AccountEmail> newEmails, final InternalCallContext context) {
         if (emails.get(accountId) == null) {
             emails.put(accountId, new HashSet<AccountEmail>());
         }
@@ -50,7 +74,7 @@ public class MockAccountEmailDao implements AccountEmailDao {
     }
 
     @Override
-    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+    public void addEmail(final UUID accountId, final AccountEmail email, final InternalCallContext context) {
         if (emails.get(accountId) == null) {
             emails.put(accountId, new HashSet<AccountEmail>());
         }
@@ -59,7 +83,7 @@ public class MockAccountEmailDao implements AccountEmailDao {
     }
 
     @Override
-    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+    public void removeEmail(final UUID accountId, final AccountEmail email, final InternalCallContext context) {
         if (emails.get(accountId) == null) {
             emails.put(accountId, new HashSet<AccountEmail>());
         }
@@ -68,6 +92,6 @@ public class MockAccountEmailDao implements AccountEmailDao {
     }
 
     @Override
-    public void test() {
+    public void test(final InternalTenantContext context) {
     }
 }
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index 82c1a62..0b9f8e7 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -87,18 +87,18 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow")
     public void testBasic() throws EntityPersistenceException {
         final Account a = createTestAccount(5);
-        accountDao.create(a, context);
+        accountDao.create(a, internalCallContext);
         final String key = a.getExternalKey();
 
-        Account r = accountDao.getAccountByKey(key);
+        Account r = accountDao.getAccountByKey(key, internalCallContext);
         assertNotNull(r);
         assertEquals(r.getExternalKey(), a.getExternalKey());
 
-        r = accountDao.getById(r.getId());
+        r = accountDao.getById(r.getId(), internalCallContext);
         assertNotNull(r);
         assertEquals(r.getExternalKey(), a.getExternalKey());
 
-        final List<Account> all = accountDao.get();
+        final List<Account> all = accountDao.get(internalCallContext);
         assertNotNull(all);
         assertTrue(all.size() >= 1);
     }
@@ -107,9 +107,9 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow")
     public void testLongPhoneNumber() throws EntityPersistenceException {
         final Account account = createTestAccount(1, "123456789012345678901234");
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
-        final Account saved = accountDao.getAccountByKey(account.getExternalKey());
+        final Account saved = accountDao.getAccountByKey(account.getExternalKey(), internalCallContext);
         assertNotNull(saved);
     }
 
@@ -117,7 +117,7 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow", expectedExceptions = EntityPersistenceException.class)
     public void testOverlyLongPhoneNumber() throws EntityPersistenceException {
         final Account account = createTestAccount(1, "12345678901234567890123456");
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
     }
 
     @Test(groups = "slow")
@@ -128,9 +128,9 @@ public class TestAccountDao extends AccountDaoTestBase {
         final String name = account.getName();
         final Integer firstNameLength = account.getFirstNameLength();
 
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
-        account = accountDao.getById(id);
+        account = accountDao.getById(id, internalCallContext);
         assertNotNull(account);
         assertEquals(account.getId(), id);
         assertEquals(account.getExternalKey(), key);
@@ -147,9 +147,9 @@ public class TestAccountDao extends AccountDaoTestBase {
         final List<CustomField> customFields = new ArrayList<CustomField>();
         customFields.add(new StringCustomField(fieldName, fieldValue));
         final CustomFieldDao customFieldDao = new AuditedCustomFieldDao(dbi);
-        customFieldDao.saveEntities(accountId, ObjectType.ACCOUNT, customFields, context);
+        customFieldDao.saveEntities(accountId, ObjectType.ACCOUNT, customFields, internalCallContext);
 
-        final Map<String, CustomField> customFieldMap = customFieldDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, CustomField> customFieldMap = customFieldDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(customFieldMap.size(), 1);
         final CustomField customField = customFieldMap.get(fieldName);
         assertEquals(customField.getName(), fieldName);
@@ -161,12 +161,12 @@ public class TestAccountDao extends AccountDaoTestBase {
         final Account account = createTestAccount(1);
         final TagDefinition definition = new DefaultTagDefinition("Test Tag", "For testing only", false);
         final TagDefinitionSqlDao tagDescriptionDao = dbi.onDemand(TagDefinitionSqlDao.class);
-        tagDescriptionDao.create(definition, context);
+        tagDescriptionDao.create(definition, internalCallContext);
 
         final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
-        tagDao.insertTag(account.getId(), ObjectType.ACCOUNT, definition.getId(), context);
+        tagDao.insertTag(account.getId(), ObjectType.ACCOUNT, definition.getId(), internalCallContext);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(account.getId(), ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(account.getId(), ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 1);
 
         assertEquals(tagMap.values().iterator().next().getTagDefinitionId(), definition.getId());
@@ -175,10 +175,10 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow")
     public void testGetIdFromKey() throws EntityPersistenceException {
         final Account account = createTestAccount(1);
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         try {
-            final UUID accountId = accountDao.getIdFromKey(account.getExternalKey());
+            final UUID accountId = accountDao.getIdFromKey(account.getExternalKey(), internalCallContext);
             assertEquals(accountId, account.getId());
         } catch (AccountApiException a) {
             fail("Retrieving account failed.");
@@ -188,13 +188,13 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow", expectedExceptions = AccountApiException.class)
     public void testGetIdFromKeyForNullKey() throws AccountApiException {
         final String key = null;
-        accountDao.getIdFromKey(key);
+        accountDao.getIdFromKey(key, internalCallContext);
     }
 
     @Test(groups = "slow")
     public void testUpdate() throws Exception {
         final Account account = createTestAccount(1);
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final AccountData accountData = new MockAccountBuilder(account).migrated(false)
                                                                        .isNotifiedForInvoices(false)
@@ -203,9 +203,9 @@ public class TestAccountDao extends AccountDaoTestBase {
                                                                        .build();
 
         final Account updatedAccount = new DefaultAccount(account.getId(), accountData);
-        accountDao.update(updatedAccount, context);
+        accountDao.update(updatedAccount, internalCallContext);
 
-        final Account savedAccount = accountDao.getAccountByKey(account.getExternalKey());
+        final Account savedAccount = accountDao.getAccountByKey(account.getExternalKey(), internalCallContext);
 
         assertNotNull(savedAccount);
         assertEquals(savedAccount.getName(), updatedAccount.getName());
@@ -227,18 +227,18 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow")
     public void testUpdatePaymentMethod() throws Exception {
         final Account account = createTestAccount(1);
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final UUID newPaymentMethodId = UUID.randomUUID();
-        accountDao.updatePaymentMethod(account.getId(), newPaymentMethodId, context);
+        accountDao.updatePaymentMethod(account.getId(), newPaymentMethodId, internalCallContext);
 
-        final Account newAccount = accountDao.getById(account.getId());
+        final Account newAccount = accountDao.getById(account.getId(), internalCallContext);
         assertEquals(newAccount.getPaymentMethodId(), newPaymentMethodId);
 
         // And then set it to null
-        accountDao.updatePaymentMethod(account.getId(), null, context);
+        accountDao.updatePaymentMethod(account.getId(), null, internalCallContext);
 
-        final Account newAccountWithPMNull = accountDao.getById(account.getId());
+        final Account newAccountWithPMNull = accountDao.getById(account.getId(), internalCallContext);
         assertNull(newAccountWithPMNull.getPaymentMethodId());
 
     }
@@ -250,7 +250,7 @@ public class TestAccountDao extends AccountDaoTestBase {
                                                           "John Smith", 4, Currency.USD, new DefaultBillCycleDay(15), null,
                                                           DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
                                                           null, null, null, null, null, null, null, null, false, false);
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final String address1 = "123 address 1";
         final String address2 = "456 address 2";
@@ -267,9 +267,9 @@ public class TestAccountDao extends AccountDaoTestBase {
                                                                  address1, address2, companyName, city, stateOrProvince, country,
                                                                  postalCode, phone, false, false);
 
-        accountDao.update(updatedAccount, context);
+        accountDao.update(updatedAccount, internalCallContext);
 
-        final Account savedAccount = accountDao.getById(accountId);
+        final Account savedAccount = accountDao.getById(accountId, internalCallContext);
 
         assertNotNull(savedAccount);
         assertEquals(savedAccount.getId(), accountId);
@@ -286,29 +286,29 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow", expectedExceptions = IllegalArgumentException.class)
     public void testShouldntBeAbleToUpdateExternalKey() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         otherAccount.setExternalKey(UUID.randomUUID().toString());
 
-        accountDao.update(new DefaultAccount(account.getId(), otherAccount), context);
+        accountDao.update(new DefaultAccount(account.getId(), otherAccount), internalCallContext);
     }
 
     @Test(groups = "slow", expectedExceptions = IllegalArgumentException.class)
     public void testShouldntBeAbleToUpdateCurrency() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         otherAccount.setCurrency(Currency.GBP);
 
-        accountDao.update(new DefaultAccount(account.getId(), otherAccount), context);
+        accountDao.update(new DefaultAccount(account.getId(), otherAccount), internalCallContext);
     }
 
     @Test(groups = "slow", expectedExceptions = IllegalArgumentException.class)
     public void testShouldntBeAbleToUpdateBillCycleDay() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         otherAccount.setBillCycleDay(new BillCycleDay() {
@@ -323,28 +323,28 @@ public class TestAccountDao extends AccountDaoTestBase {
             }
         });
 
-        accountDao.update(new DefaultAccount(account.getId(), otherAccount), context);
+        accountDao.update(new DefaultAccount(account.getId(), otherAccount), internalCallContext);
     }
 
     @Test(groups = "slow")
     public void testShouldBeAbleToUpdateSomeFields() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         otherAccount.setAddress1(UUID.randomUUID().toString());
         otherAccount.setEmail(UUID.randomUUID().toString());
 
         final DefaultAccount newAccount = new DefaultAccount(account.getId(), otherAccount);
-        accountDao.update(newAccount, context);
+        accountDao.update(newAccount, internalCallContext);
 
-        Assert.assertEquals(accountDao.getById(account.getId()), newAccount);
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext), newAccount);
     }
 
     @Test(groups = "slow")
     public void testShouldBeAbleToPassNullForSomeFieldsToAvoidUpdate() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         // Update the address and leave other fields null
         final MutableAccountData mutableAccountData = new DefaultMutableAccountData(null, null, null, 0, null, null, null,
@@ -354,19 +354,19 @@ public class TestAccountDao extends AccountDaoTestBase {
         mutableAccountData.setAddress1(newAddress1);
 
         final DefaultAccount newAccount = new DefaultAccount(account.getId(), mutableAccountData);
-        accountDao.update(newAccount, context);
+        accountDao.update(newAccount, internalCallContext);
 
-        Assert.assertEquals(accountDao.getById(account.getId()).getAddress1(), newAddress1);
-        Assert.assertEquals(accountDao.getById(account.getId()).getAddress2(), account.getAddress2());
-        Assert.assertEquals(accountDao.getById(account.getId()).getCurrency(), account.getCurrency());
-        Assert.assertEquals(accountDao.getById(account.getId()).getExternalKey(), account.getExternalKey());
-        Assert.assertEquals(accountDao.getById(account.getId()).getBillCycleDay(), account.getBillCycleDay());
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext).getAddress1(), newAddress1);
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext).getAddress2(), account.getAddress2());
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext).getCurrency(), account.getCurrency());
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext).getExternalKey(), account.getExternalKey());
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext).getBillCycleDay(), account.getBillCycleDay());
     }
 
     @Test(groups = "slow")
     public void testShouldBeAbleToHandleOtherBCDClass() throws Exception {
         final Account account = createTestAccount();
-        accountDao.create(account, context);
+        accountDao.create(account, internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         otherAccount.setAddress1(UUID.randomUUID().toString());
@@ -385,9 +385,9 @@ public class TestAccountDao extends AccountDaoTestBase {
         });
 
         final DefaultAccount newAccount = new DefaultAccount(account.getId(), otherAccount);
-        accountDao.update(newAccount, context);
+        accountDao.update(newAccount, internalCallContext);
 
-        final Account newFetchedAccount = accountDao.getById(account.getId());
+        final Account newFetchedAccount = accountDao.getById(account.getId(), internalCallContext);
         Assert.assertEquals(newFetchedAccount.getAddress1(), newAccount.getAddress1());
         Assert.assertEquals(newFetchedAccount.getEmail(), newAccount.getEmail());
         // Same BCD
@@ -397,31 +397,31 @@ public class TestAccountDao extends AccountDaoTestBase {
     @Test(groups = "slow")
     public void testShouldBeAbleToHandleBCDOfZeroZero() throws Exception {
         final Account account = createTestAccount(0);
-        accountDao.create(account, context);
-        final Account fetchedAccount = accountDao.getById(account.getId());
+        accountDao.create(account, internalCallContext);
+        final Account fetchedAccount = accountDao.getById(account.getId(), internalCallContext);
 
         final MutableAccountData otherAccount = account.toMutableAccountData();
         // Set BCD to null
         otherAccount.setBillCycleDay(null);
 
         final DefaultAccount newAccount = new DefaultAccount(account.getId(), otherAccount);
-        accountDao.update(newAccount, context);
+        accountDao.update(newAccount, internalCallContext);
 
         // Same BCD (zero/zero)
-        Assert.assertEquals(accountDao.getById(account.getId()), fetchedAccount);
+        Assert.assertEquals(accountDao.getById(account.getId(), internalCallContext), fetchedAccount);
     }
 
     @Test(groups = "slow")
     public void testHandleDuplicateEmails() {
         final UUID accountId = UUID.randomUUID();
         final AccountEmail email = new DefaultAccountEmail(accountId, "test@gmail.com");
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, internalCallContext).size(), 0);
 
-        accountEmailDao.addEmail(accountId, email, context);
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+        accountEmailDao.addEmail(accountId, email, internalCallContext);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, internalCallContext).size(), 1);
 
-        accountEmailDao.addEmail(accountId, email, context);
-        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+        accountEmailDao.addEmail(accountId, email, internalCallContext);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
@@ -434,8 +434,8 @@ public class TestAccountDao extends AccountDaoTestBase {
         // add a new e-mail
         final AccountEmail email = new DefaultAccountEmail(accountId, "test@gmail.com");
         emails.add(email);
-        accountEmailDao.saveEmails(accountId, emails, context);
-        emails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.saveEmails(accountId, emails, internalCallContext);
+        emails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(emails.size(), 1);
 
         // verify that history and audit contain one entry
@@ -445,8 +445,8 @@ public class TestAccountDao extends AccountDaoTestBase {
         final AccountEmail updatedEmail = new DefaultAccountEmail(email, "test2@gmail.com");
         emails.clear();
         emails.add(updatedEmail);
-        accountEmailDao.saveEmails(accountId, emails, context);
-        emails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.saveEmails(accountId, emails, internalCallContext);
+        emails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(emails.size(), 1);
 
         // verify that history and audit contain three entries
@@ -454,8 +454,8 @@ public class TestAccountDao extends AccountDaoTestBase {
         verifyAccountEmailAuditAndHistoryCount(accountId, 3);
 
         // delete e-mail
-        accountEmailDao.saveEmails(accountId, new ArrayList<AccountEmail>(), context);
-        emails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.saveEmails(accountId, new ArrayList<AccountEmail>(), internalCallContext);
+        emails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(emails.size(), 0);
 
         // verify that history and audit contain four entries
@@ -469,20 +469,20 @@ public class TestAccountDao extends AccountDaoTestBase {
         final String email2 = UUID.randomUUID().toString();
 
         // Verify the original state
-        assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+        assertEquals(accountEmailDao.getEmails(accountId, internalCallContext).size(), 0);
 
         // Add a new e-mail
         final AccountEmail accountEmail1 = new DefaultAccountEmail(accountId, email1);
-        accountEmailDao.addEmail(accountId, accountEmail1, context);
-        final List<AccountEmail> firstEmails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.addEmail(accountId, accountEmail1, internalCallContext);
+        final List<AccountEmail> firstEmails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(firstEmails.size(), 1);
         assertEquals(firstEmails.get(0).getAccountId(), accountId);
         assertEquals(firstEmails.get(0).getEmail(), email1);
 
         // Add a second e-mail
         final AccountEmail accountEmail2 = new DefaultAccountEmail(accountId, email2);
-        accountEmailDao.addEmail(accountId, accountEmail2, context);
-        final List<AccountEmail> secondEmails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.addEmail(accountId, accountEmail2, internalCallContext);
+        final List<AccountEmail> secondEmails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(secondEmails.size(), 2);
         assertTrue(secondEmails.get(0).getAccountId().equals(accountId));
         assertTrue(secondEmails.get(1).getAccountId().equals(accountId));
@@ -490,8 +490,8 @@ public class TestAccountDao extends AccountDaoTestBase {
         assertTrue(secondEmails.get(1).getEmail().equals(email1) || secondEmails.get(1).getEmail().equals(email2));
 
         // Delete the first e-mail
-        accountEmailDao.removeEmail(accountId, accountEmail1, context);
-        final List<AccountEmail> thirdEmails = accountEmailDao.getEmails(accountId);
+        accountEmailDao.removeEmail(accountId, accountEmail1, internalCallContext);
+        final List<AccountEmail> thirdEmails = accountEmailDao.getEmails(accountId, internalCallContext);
         assertEquals(thirdEmails.size(), 1);
         assertEquals(thirdEmails.get(0).getAccountId(), accountId);
         assertEquals(thirdEmails.get(0).getEmail(), email2);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index d3e09e1..184ea75 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.analytics;
 
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.AccountCreationEvent;
@@ -26,11 +24,16 @@ import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.RequestedSubscriptionEvent;
 import com.ning.billing.invoice.api.InvoiceAdjustmentEvent;
-import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.overdue.OverdueChangeEvent;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.bus.BusEvent;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.tag.api.ControlTagCreationEvent;
 import com.ning.billing.util.tag.api.ControlTagDefinitionCreationEvent;
 import com.ning.billing.util.tag.api.ControlTagDefinitionDeletionEvent;
@@ -40,13 +43,18 @@ import com.ning.billing.util.tag.api.UserTagDefinitionCreationEvent;
 import com.ning.billing.util.tag.api.UserTagDefinitionDeletionEvent;
 import com.ning.billing.util.tag.api.UserTagDeletionEvent;
 
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+
 public class AnalyticsListener {
+
     private final BusinessSubscriptionTransitionRecorder bstRecorder;
     private final BusinessAccountRecorder bacRecorder;
     private final BusinessInvoiceRecorder invoiceRecorder;
     private final BusinessOverdueStatusRecorder bosRecorder;
     private final BusinessInvoicePaymentRecorder bipRecorder;
     private final BusinessTagRecorder tagRecorder;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public AnalyticsListener(final BusinessSubscriptionTransitionRecorder bstRecorder,
@@ -54,36 +62,38 @@ public class AnalyticsListener {
                              final BusinessInvoiceRecorder invoiceRecorder,
                              final BusinessOverdueStatusRecorder bosRecorder,
                              final BusinessInvoicePaymentRecorder bipRecorder,
-                             final BusinessTagRecorder tagRecorder) {
+                             final BusinessTagRecorder tagRecorder,
+                             final InternalCallContextFactory internalCallContextFactory) {
         this.bstRecorder = bstRecorder;
         this.bacRecorder = bacRecorder;
         this.invoiceRecorder = invoiceRecorder;
         this.bosRecorder = bosRecorder;
         this.bipRecorder = bipRecorder;
         this.tagRecorder = tagRecorder;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Subscribe
     public void handleEffectiveSubscriptionTransitionChange(final EffectiveSubscriptionEvent eventEffective) throws AccountApiException, EntitlementUserApiException {
         // The event is used as a trigger to rebuild all transitions for this bundle
-        bstRecorder.rebuildTransitionsForBundle(eventEffective.getBundleId());
+        bstRecorder.rebuildTransitionsForBundle(eventEffective.getBundleId(), createCallContext(eventEffective));
     }
 
     @Subscribe
     public void handleRequestedSubscriptionTransitionChange(final RequestedSubscriptionEvent eventRequested) throws AccountApiException, EntitlementUserApiException {
         // The event is used as a trigger to rebuild all transitions for this bundle
-        bstRecorder.rebuildTransitionsForBundle(eventRequested.getBundleId());
+        bstRecorder.rebuildTransitionsForBundle(eventRequested.getBundleId(), createCallContext(eventRequested));
     }
 
     @Subscribe
     public void handleRepairEntitlement(final RepairEntitlementEvent event) {
         // In case of repair, just rebuild all transitions
-        bstRecorder.rebuildTransitionsForBundle(event.getBundleId());
+        bstRecorder.rebuildTransitionsForBundle(event.getBundleId(), createCallContext(event));
     }
 
     @Subscribe
     public void handleAccountCreation(final AccountCreationEvent event) {
-        bacRecorder.accountCreated(event.getData());
+        bacRecorder.accountCreated(event.getData(), createCallContext(event));
     }
 
     @Subscribe
@@ -92,13 +102,13 @@ public class AnalyticsListener {
             return;
         }
 
-        bacRecorder.accountUpdated(event.getAccountId());
+        bacRecorder.accountUpdated(event.getAccountId(), createCallContext(event));
     }
 
     @Subscribe
     public void handleInvoiceCreation(final InvoiceCreationEvent event) {
         // The event is used as a trigger to rebuild all invoices and invoice items for this account
-        invoiceRecorder.rebuildInvoicesForAccount(event.getAccountId());
+        invoiceRecorder.rebuildInvoicesForAccount(event.getAccountId(), createCallContext(event));
     }
 
     @Subscribe
@@ -109,7 +119,7 @@ public class AnalyticsListener {
     @Subscribe
     public void handleInvoiceAdjustment(final InvoiceAdjustmentEvent event) {
         // The event is used as a trigger to rebuild all invoices and invoice items for this account
-        invoiceRecorder.rebuildInvoicesForAccount(event.getAccountId());
+        invoiceRecorder.rebuildInvoicesForAccount(event.getAccountId(), createCallContext(event));
     }
 
     @Subscribe
@@ -118,7 +128,8 @@ public class AnalyticsListener {
                                          paymentInfo.getPaymentId(),
                                          paymentInfo.getExtFirstPaymentRefId(),
                                          paymentInfo.getExtSecondPaymentRefId(),
-                                         paymentInfo.getStatus().toString());
+                                         paymentInfo.getStatus().toString(),
+                                         createCallContext(paymentInfo));
     }
 
     @Subscribe
@@ -127,32 +138,33 @@ public class AnalyticsListener {
                                          paymentError.getPaymentId(),
                                          null,
                                          null,
-                                         paymentError.getMessage());
+                                         paymentError.getMessage(),
+                                         createCallContext(paymentError));
     }
 
     @Subscribe
     public void handleOverdueChange(final OverdueChangeEvent changeEvent) {
-        bosRecorder.overdueStatusChanged(changeEvent.getOverdueObjectType(), changeEvent.getOverdueObjectId());
+        bosRecorder.overdueStatusChanged(changeEvent.getOverdueObjectType(), changeEvent.getOverdueObjectId(), createCallContext(changeEvent));
     }
 
     @Subscribe
     public void handleControlTagCreation(final ControlTagCreationEvent event) {
-        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName(), createCallContext(event));
     }
 
     @Subscribe
     public void handleControlTagDeletion(final ControlTagDeletionEvent event) {
-        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName(), createCallContext(event));
     }
 
     @Subscribe
     public void handleUserTagCreation(final UserTagCreationEvent event) {
-        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName(), createCallContext(event));
     }
 
     @Subscribe
     public void handleUserTagDeletion(final UserTagDeletionEvent event) {
-        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName(), createCallContext(event));
     }
 
     @Subscribe
@@ -174,4 +186,8 @@ public class AnalyticsListener {
     public void handleUserTagDefinitionDeletion(final UserTagDefinitionDeletionEvent event) {
         // Ignored for now
     }
+
+    private InternalCallContext createCallContext(final BusEvent event) {
+        return internalCallContextFactory.createInternalCallContext("AnalyticsService", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
+    }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
index 691eb33..fb74122 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
@@ -30,53 +30,57 @@ import com.ning.billing.analytics.model.BusinessInvoiceItem;
 import com.ning.billing.analytics.model.BusinessInvoicePayment;
 import com.ning.billing.analytics.model.BusinessOverdueStatus;
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
 
+    private final InternalCallContextFactory internalCallContextFactory;
     private final AnalyticsDao analyticsDao;
 
     @Inject
-    public DefaultAnalyticsUserApi(final AnalyticsDao analyticsDao) {
+    public DefaultAnalyticsUserApi(final AnalyticsDao analyticsDao, final InternalCallContextFactory internalCallContextFactory) {
         this.analyticsDao = analyticsDao;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public TimeSeriesData getAccountsCreatedOverTime() {
-        return analyticsDao.getAccountsCreatedOverTime();
+    public TimeSeriesData getAccountsCreatedOverTime(final TenantContext context) {
+        return analyticsDao.getAccountsCreatedOverTime(internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug) {
-        return analyticsDao.getSubscriptionsCreatedOverTime(productType, slug);
+    public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug, final TenantContext context) {
+        return analyticsDao.getSubscriptionsCreatedOverTime(productType, slug, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     // Note: the following is not exposed in api yet, as the models need to be extracted first
 
-    public BusinessAccount getAccountByKey(final String accountKey) {
-        return analyticsDao.getAccountByKey(accountKey);
+    public BusinessAccount getAccountByKey(final String accountKey, final TenantContext context) {
+        return analyticsDao.getAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey) {
-        return analyticsDao.getTransitionsByKey(externalKey);
+    public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey, final TenantContext context) {
+        return analyticsDao.getTransitionsByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessInvoice> getInvoicesForAccount(final String accountKey) {
-        return analyticsDao.getInvoicesByKey(accountKey);
+    public List<BusinessInvoice> getInvoicesForAccount(final String accountKey, final TenantContext context) {
+        return analyticsDao.getInvoicesByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessAccountTag> getTagsForAccount(final String accountKey) {
-        return analyticsDao.getTagsForAccount(accountKey);
+    public List<BusinessAccountTag> getTagsForAccount(final String accountKey, final TenantContext context) {
+        return analyticsDao.getTagsForAccount(accountKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessOverdueStatus> getOverdueStatusesForBundle(final String externalKey) {
-        return analyticsDao.getOverdueStatusesForBundleByKey(externalKey);
+    public List<BusinessOverdueStatus> getOverdueStatusesForBundle(final String externalKey, final TenantContext context) {
+        return analyticsDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final UUID invoiceId) {
-        return analyticsDao.getInvoiceItemsForInvoice(invoiceId.toString());
+    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final UUID invoiceId, final TenantContext context) {
+        return analyticsDao.getInvoiceItemsForInvoice(invoiceId.toString(), internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(final String accountKey) {
-        return analyticsDao.getInvoicePaymentsForAccountByKey(accountKey);
+    public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(final String accountKey, final TenantContext context) {
+        return analyticsDao.getInvoicePaymentsForAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index b4fd225..0ff5e92 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -38,6 +38,8 @@ import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.inject.Inject;
 
@@ -59,11 +61,11 @@ public class BusinessAccountRecorder {
         this.paymentApi = paymentApi;
     }
 
-    public void accountCreated(final AccountData data) {
+    public void accountCreated(final AccountData data, final InternalCallContext context) {
         final Account account;
         try {
-            account = accountApi.getAccountByKey(data.getExternalKey());
-            accountUpdated(account.getId());
+            account = accountApi.getAccountByKey(data.getExternalKey(), context.toCallContext());
+            accountUpdated(account.getId(), context);
         } catch (AccountApiException e) {
             log.warn("Error encountered creating BusinessAccount", e);
         }
@@ -74,33 +76,33 @@ public class BusinessAccountRecorder {
      *
      * @param accountId account id associated with the created invoice
      */
-    public void accountUpdated(final UUID accountId) {
+    public void accountUpdated(final UUID accountId, final InternalCallContext context) {
         final Account account;
         try {
-            account = accountApi.getAccountById(accountId);
+            account = accountApi.getAccountById(accountId, context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Error encountered creating BusinessAccount", e);
             return;
         }
 
-        updateAccountInTransaction(account, sqlDao);
+        updateAccountInTransaction(account, sqlDao, context);
     }
 
-    public void updateAccountInTransaction(final Account account, final BusinessAccountSqlDao transactional) {
-        BusinessAccount bac = transactional.getAccount(account.getId().toString());
+    public void updateAccountInTransaction(final Account account, final BusinessAccountSqlDao transactional, final InternalCallContext context) {
+        BusinessAccount bac = transactional.getAccount(account.getId().toString(), context);
         if (bac == null) {
             bac = new BusinessAccount(account.getId());
-            updateBusinessAccountFromAccount(account, bac);
+            updateBusinessAccountFromAccount(account, bac, context);
             log.info("ACCOUNT CREATION " + bac);
-            transactional.createAccount(bac);
+            transactional.createAccount(bac, context);
         } else {
-            updateBusinessAccountFromAccount(account, bac);
+            updateBusinessAccountFromAccount(account, bac, context);
             log.info("ACCOUNT UPDATE " + bac);
-            transactional.saveAccount(bac);
+            transactional.saveAccount(bac, context);
         }
     }
 
-    private void updateBusinessAccountFromAccount(final Account account, final BusinessAccount bac) {
+    private void updateBusinessAccountFromAccount(final Account account, final BusinessAccount bac, final InternalTenantContext context) {
         bac.setName(account.getName());
         bac.setKey(account.getExternalKey());
         final Currency currency = account.getCurrency();
@@ -115,7 +117,7 @@ public class BusinessAccountRecorder {
             String billingAddressCountry = bac.getBillingAddressCountry();
 
             // Retrieve invoices information
-            final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
+            final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), context.toTenantContext());
             if (invoices != null && invoices.size() > 0) {
 
                 for (final Invoice invoice : invoices) {
@@ -129,7 +131,7 @@ public class BusinessAccountRecorder {
                 // Retrieve payments information for these invoices
                 DateTime lastPaymentDate = null;
 
-                final List<Payment> payments = paymentApi.getAccountPayments(account.getId());
+                final List<Payment> payments = paymentApi.getAccountPayments(account.getId(), context.toTenantContext());
                 if (payments != null) {
                     for (final Payment cur : payments) {
                         // Use the last payment method/type/country as the default one for the account
@@ -142,7 +144,7 @@ public class BusinessAccountRecorder {
             }
 
             // Retrieve payment methods
-            for (final PaymentMethod paymentMethod : paymentApi.getPaymentMethods(account, true)) {
+            for (final PaymentMethod paymentMethod : paymentApi.getPaymentMethods(account, true, context.toTenantContext())) {
                 if (paymentMethod.getId().equals(account.getPaymentMethodId()) && paymentMethod.getPluginDetail() != null) {
                     paymentMethodType = PaymentMethodUtils.getPaymentMethodType(paymentMethod.getPluginDetail());
                     creditCardType = PaymentMethodUtils.getCardType(paymentMethod.getPluginDetail());
@@ -158,8 +160,7 @@ public class BusinessAccountRecorder {
             bac.setLastInvoiceDate(lastInvoiceDate);
             bac.setTotalInvoiceBalance(totalInvoiceBalance);
 
-            bac.setBalance(invoiceUserApi.getAccountBalance(account.getId()));
-
+            bac.setBalance(invoiceUserApi.getAccountBalance(account.getId(), context.toTenantContext()));
         } catch (PaymentApiException ex) {
             log.error(String.format("Failed to handle account update for account %s", account.getId()), ex);
         }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentRecorder.java
index 9c64c3a..42ec7d9 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentRecorder.java
@@ -40,6 +40,7 @@ import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.clock.Clock;
 
 public class BusinessInvoicePaymentRecorder {
@@ -68,7 +69,7 @@ public class BusinessInvoicePaymentRecorder {
     }
 
     public void invoicePaymentPosted(final UUID accountId, @Nullable final UUID paymentId, @Nullable final String extFirstPaymentRefId,
-                                     @Nullable final String extSecondPaymentRefId, final String message) {
+                                     @Nullable final String extSecondPaymentRefId, final String message, final InternalCallContext context) {
         // Payment attempt with no default payment method. Ignore.
         if (paymentId == null) {
             return;
@@ -76,7 +77,7 @@ public class BusinessInvoicePaymentRecorder {
 
         final Account account;
         try {
-            account = accountApi.getAccountById(accountId);
+            account = accountApi.getAccountById(accountId, context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Ignoring payment {}: account {} does not exist", paymentId, accountId);
             return;
@@ -84,26 +85,27 @@ public class BusinessInvoicePaymentRecorder {
 
         final Payment payment;
         try {
-            payment = paymentApi.getPayment(paymentId);
+            payment = paymentApi.getPayment(paymentId, context.toCallContext());
         } catch (PaymentApiException e) {
             log.warn("Ignoring payment {}: payment does not exist", paymentId);
             return;
         }
 
-        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(paymentId);
+        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(paymentId, context.toCallContext());
         final PaymentMethod paymentMethod;
         try {
-            paymentMethod = paymentApi.getPaymentMethod(account, payment.getPaymentMethodId(), true);
+            paymentMethod = paymentApi.getPaymentMethod(account, payment.getPaymentMethodId(), true, context.toCallContext());
         } catch (PaymentApiException e) {
             log.warn("Ignoring payment {}: payment method {} does not exist", paymentId, payment.getPaymentMethodId());
             return;
         }
 
-        createPayment(account, invoicePayment, payment, paymentMethod, extFirstPaymentRefId, extSecondPaymentRefId, message);
+        createPayment(account, invoicePayment, payment, paymentMethod, extFirstPaymentRefId, extSecondPaymentRefId, message, context);
     }
 
     private void createPayment(final Account account, @Nullable final InvoicePayment invoicePayment, final Payment payment,
-                               final PaymentMethod paymentMethod, final String extFirstPaymentRefId, final String extSecondPaymentRefId, final String message) {
+                               final PaymentMethod paymentMethod, final String extFirstPaymentRefId, final String extSecondPaymentRefId,
+                               final String message, final InternalCallContext context) {
         final PaymentMethodPlugin pluginDetail = paymentMethod.getPluginDetail();
         final String cardCountry = PaymentMethodUtils.getCardCountry(pluginDetail);
         final String cardType = PaymentMethodUtils.getCardType(pluginDetail);
@@ -113,7 +115,7 @@ public class BusinessInvoicePaymentRecorder {
             @Override
             public Void inTransaction(final BusinessInvoicePaymentSqlDao transactional, final TransactionStatus status) throws Exception {
                 // Delete the existing payment if it exists - this is to make the call idempotent
-                transactional.deleteInvoicePayment(payment.getId().toString());
+                transactional.deleteInvoicePayment(payment.getId().toString(), context);
 
                 // invoicePayment may be null on payment failures
                 final String invoicePaymentType;
@@ -148,15 +150,15 @@ public class BusinessInvoicePaymentRecorder {
                         clock.getUTCNow(),
                         invoicePaymentType,
                         linkedInvoicePaymentId);
-                transactional.createInvoicePayment(businessInvoicePayment);
+                transactional.createInvoicePayment(businessInvoicePayment, context);
 
                 // Update bin to get the latest invoice(s) balance(s)
                 final BusinessInvoiceSqlDao invoiceSqlDao = transactional.become(BusinessInvoiceSqlDao.class);
-                invoiceRecorder.rebuildInvoicesForAccountInTransaction(account.getId(), invoiceSqlDao);
+                invoiceRecorder.rebuildInvoicesForAccountInTransaction(account.getId(), invoiceSqlDao, context);
 
                 // Update bac to get the latest account balance, total invoice balance, etc.
                 final BusinessAccountSqlDao accountSqlDao = transactional.become(BusinessAccountSqlDao.class);
-                accountRecorder.updateAccountInTransaction(account, accountSqlDao);
+                accountRecorder.updateAccountInTransaction(account, accountSqlDao, context);
 
                 log.info("Added payment {}", businessInvoicePayment);
                 return null;
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
index e78a04f..4bb7fa1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
@@ -47,6 +47,8 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -77,21 +79,21 @@ public class BusinessInvoiceRecorder {
         this.clock = clock;
     }
 
-    public void rebuildInvoicesForAccount(final UUID accountId) {
+    public void rebuildInvoicesForAccount(final UUID accountId, final InternalCallContext context) {
         sqlDao.inTransaction(new Transaction<Void, BusinessInvoiceSqlDao>() {
             @Override
             public Void inTransaction(final BusinessInvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
-                rebuildInvoicesForAccountInTransaction(accountId, transactional);
+                rebuildInvoicesForAccountInTransaction(accountId, transactional, context);
                 return null;
             }
         });
     }
 
-    public void rebuildInvoicesForAccountInTransaction(final UUID accountId, final BusinessInvoiceSqlDao transactional) {
+    public void rebuildInvoicesForAccountInTransaction(final UUID accountId, final BusinessInvoiceSqlDao transactional, final InternalCallContext context) {
         // Lookup the associated account
         final String accountKey;
         try {
-            final Account account = accountApi.getAccountById(accountId);
+            final Account account = accountApi.getAccountById(accountId, context.toCallContext());
             accountKey = account.getExternalKey();
         } catch (AccountApiException e) {
             log.warn("Ignoring invoice update for account id {} (account does not exist)", accountId);
@@ -99,64 +101,67 @@ public class BusinessInvoiceRecorder {
         }
 
         log.info("Started rebuilding invoices for account id {}", accountId);
-        deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, accountId);
+        deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, accountId, context);
 
-        for (final Invoice invoice : invoiceApi.getInvoicesByAccount(accountId)) {
-            createInvoiceInTransaction(transactional, accountKey, invoice);
+        for (final Invoice invoice : invoiceApi.getInvoicesByAccount(accountId, context.toCallContext())) {
+            createInvoiceInTransaction(transactional, accountKey, invoice, context);
         }
 
         log.info("Finished rebuilding invoices for account id {}", accountId);
     }
 
-    private void deleteInvoicesAndInvoiceItemsForAccountInTransaction(final BusinessInvoiceSqlDao transactional, final UUID accountId) {
+    private void deleteInvoicesAndInvoiceItemsForAccountInTransaction(final BusinessInvoiceSqlDao transactional,
+                                                                      final UUID accountId, final InternalCallContext context) {
         // We don't use on cascade delete here as we don't want the database layer to be generic - hence we have
         // to delete the invoice items manually.
-        final List<BusinessInvoice> invoicesToDelete = transactional.getInvoicesForAccount(accountId.toString());
+        final List<BusinessInvoice> invoicesToDelete = transactional.getInvoicesForAccount(accountId.toString(), context);
         final BusinessInvoiceItemSqlDao invoiceItemSqlDao = transactional.become(BusinessInvoiceItemSqlDao.class);
         for (final BusinessInvoice businessInvoice : invoicesToDelete) {
-            final List<BusinessInvoiceItem> invoiceItemsForInvoice = invoiceItemSqlDao.getInvoiceItemsForInvoice(businessInvoice.getInvoiceId().toString());
+            final List<BusinessInvoiceItem> invoiceItemsForInvoice = invoiceItemSqlDao.getInvoiceItemsForInvoice(businessInvoice.getInvoiceId().toString(), context);
             for (final BusinessInvoiceItem invoiceItemToDelete : invoiceItemsForInvoice) {
                 log.info("Deleting invoice item {}", invoiceItemToDelete.getItemId());
-                invoiceItemSqlDao.deleteInvoiceItem(invoiceItemToDelete.getItemId().toString());
+                invoiceItemSqlDao.deleteInvoiceItem(invoiceItemToDelete.getItemId().toString(), context);
             }
         }
 
         log.info("Deleting invoices for account {}", accountId);
-        transactional.deleteInvoicesForAccount(accountId.toString());
+        transactional.deleteInvoicesForAccount(accountId.toString(), context);
     }
 
-    private void createInvoiceInTransaction(final BusinessInvoiceSqlDao transactional, final String accountKey, final Invoice invoice) {
+    private void createInvoiceInTransaction(final BusinessInvoiceSqlDao transactional, final String accountKey,
+                                            final Invoice invoice, final InternalCallContext context) {
         // Create the invoice
         final BusinessInvoice businessInvoice = new BusinessInvoice(accountKey, invoice);
 
         // Create associated invoice items
         final List<BusinessInvoiceItem> businessInvoiceItems = new ArrayList<BusinessInvoiceItem>();
         for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
-            final BusinessInvoiceItem businessInvoiceItem = createBusinessInvoiceItem(invoiceItem);
+            final BusinessInvoiceItem businessInvoiceItem = createBusinessInvoiceItem(invoiceItem, context);
             if (businessInvoiceItem != null) {
                 businessInvoiceItems.add(businessInvoiceItem);
             }
         }
 
-        createInvoiceInTransaction(transactional, invoice.getAccountId(), businessInvoice, businessInvoiceItems);
+        createInvoiceInTransaction(transactional, invoice.getAccountId(), businessInvoice, businessInvoiceItems, context);
     }
 
     private void createInvoiceInTransaction(final BusinessInvoiceSqlDao transactional, final UUID accountId,
-                                            final BusinessInvoice invoice, final Iterable<BusinessInvoiceItem> invoiceItems) {
+                                            final BusinessInvoice invoice, final Iterable<BusinessInvoiceItem> invoiceItems,
+                                            final InternalCallContext context) {
         // Create the invoice
         log.info("Adding invoice {}", invoice);
-        transactional.createInvoice(invoice);
+        transactional.createInvoice(invoice, context);
 
         // Add associated invoice items
         final BusinessInvoiceItemSqlDao invoiceItemSqlDao = transactional.become(BusinessInvoiceItemSqlDao.class);
         for (final BusinessInvoiceItem invoiceItem : invoiceItems) {
             log.info("Adding invoice item {}", invoiceItem);
-            invoiceItemSqlDao.createInvoiceItem(invoiceItem);
+            invoiceItemSqlDao.createInvoiceItem(invoiceItem, context);
         }
 
         // Update BAC
         final BusinessAccountSqlDao accountSqlDao = transactional.become(BusinessAccountSqlDao.class);
-        final BusinessAccount account = accountSqlDao.getAccount(accountId.toString());
+        final BusinessAccount account = accountSqlDao.getAccount(accountId.toString(), context);
         if (account == null) {
             throw new IllegalStateException("Account does not exist for id " + accountId);
         }
@@ -165,11 +170,11 @@ public class BusinessInvoiceRecorder {
         account.setTotalInvoiceBalance(account.getTotalInvoiceBalance().add(invoice.getBalance()));
         account.setUpdatedDt(clock.getUTCNow());
         log.info("Updating account {}", account);
-        accountSqlDao.saveAccount(account);
+        accountSqlDao.saveAccount(account, context);
     }
 
     @VisibleForTesting
-    BusinessInvoiceItem createBusinessInvoiceItem(final InvoiceItem invoiceItem) {
+    BusinessInvoiceItem createBusinessInvoiceItem(final InvoiceItem invoiceItem, final InternalTenantContext context) {
         String externalKey = null;
         Plan plan = null;
         PlanPhase planPhase = null;
@@ -177,7 +182,7 @@ public class BusinessInvoiceRecorder {
         // Subscription and bundle could be null for e.g. credits or adjustments
         if (invoiceItem.getBundleId() != null) {
             try {
-                final SubscriptionBundle bundle = entitlementApi.getBundleFromId(invoiceItem.getBundleId());
+                final SubscriptionBundle bundle = entitlementApi.getBundleFromId(invoiceItem.getBundleId(), context.toTenantContext());
                 externalKey = bundle.getKey();
             } catch (EntitlementUserApiException e) {
                 log.warn("Ignoring subscription fields for invoice item {} for bundle {} (bundle does not exist)",
@@ -197,7 +202,7 @@ public class BusinessInvoiceRecorder {
         if (invoiceItem.getSubscriptionId() != null && invoiceItem.getPhaseName() != null) {
             final Subscription subscription;
             try {
-                subscription = entitlementApi.getSubscriptionFromId(invoiceItem.getSubscriptionId());
+                subscription = entitlementApi.getSubscriptionFromId(invoiceItem.getSubscriptionId(), context.toTenantContext());
                 planPhase = catalogService.getFullCatalog().findPhase(invoiceItem.getPhaseName(), invoiceItem.getStartDate().toDateTimeAtStartOfDay(), subscription.getStartDate());
             } catch (EntitlementUserApiException e) {
                 log.warn("Ignoring subscription fields for invoice item {} for subscription {} (subscription does not exist)",
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusRecorder.java
index 06141c8..b670eab 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusRecorder.java
@@ -16,19 +16,17 @@
 
 package com.ning.billing.analytics;
 
-import javax.inject.Inject;
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
+import javax.inject.Inject;
+
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -40,8 +38,13 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.callcontext.InternalCallContext;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 public class BusinessOverdueStatusRecorder {
+
     private static final Logger log = LoggerFactory.getLogger(BusinessOverdueStatusRecorder.class);
 
     private final BusinessOverdueStatusSqlDao overdueStatusSqlDao;
@@ -58,18 +61,18 @@ public class BusinessOverdueStatusRecorder {
         this.blockingApi = blockingApi;
     }
 
-    public void overdueStatusChanged(final Blockable.Type objectType, final UUID objectId) {
+    public void overdueStatusChanged(final Blockable.Type objectType, final UUID objectId, final InternalCallContext context) {
         if (Blockable.Type.SUBSCRIPTION_BUNDLE.equals(objectType)) {
-            overdueStatusChangedForBundle(objectId);
+            overdueStatusChangedForBundle(objectId, context);
         } else {
             log.info("Ignoring overdue status change for object id {} (type {})", objectId.toString(), objectType.toString());
         }
     }
 
-    private void overdueStatusChangedForBundle(final UUID bundleId) {
+    private void overdueStatusChangedForBundle(final UUID bundleId, final InternalCallContext context) {
         final SubscriptionBundle bundle;
         try {
-            bundle = entitlementApi.getBundleFromId(bundleId);
+            bundle = entitlementApi.getBundleFromId(bundleId, context.toCallContext());
         } catch (EntitlementUserApiException e) {
             log.warn("Ignoring update for bundle {}: bundle does not exist", bundleId);
             return;
@@ -77,7 +80,7 @@ public class BusinessOverdueStatusRecorder {
 
         final Account account;
         try {
-            account = accountApi.getAccountById(bundle.getAccountId());
+            account = accountApi.getAccountById(bundle.getAccountId(), context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Ignoring update for bundle {}: account {} does not exist", bundleId, bundle.getAccountId());
             return;
@@ -90,9 +93,9 @@ public class BusinessOverdueStatusRecorder {
             @Override
             public Void inTransaction(final BusinessOverdueStatusSqlDao transactional, final TransactionStatus status) throws Exception {
                 log.info("Started rebuilding overdue statuses for bundle id {}", bundleId);
-                transactional.deleteOverdueStatusesForBundle(bundleId.toString());
+                transactional.deleteOverdueStatusesForBundle(bundleId.toString(), context);
 
-                final List<BlockingState> blockingHistory = blockingApi.getBlockingHistory(bundleId);
+                final List<BlockingState> blockingHistory = blockingApi.getBlockingHistory(bundleId, context.toCallContext());
                 if (blockingHistory != null && blockingHistory.size() > 0) {
                     final List<BlockingState> overdueStates = ImmutableList.<BlockingState>copyOf(blockingHistory);
                     final List<BlockingState> overdueStatesReversed = Lists.reverse(overdueStates);
@@ -102,7 +105,7 @@ public class BusinessOverdueStatusRecorder {
                         final BusinessOverdueStatus overdueStatus = new BusinessOverdueStatus(accountKey, bundleId, previousStartDate,
                                                                                               externalKey, state.getTimestamp(), state.getStateName());
                         log.info("Adding overdue state {}", overdueStatus);
-                        overdueStatusSqlDao.createOverdueStatus(overdueStatus);
+                        overdueStatusSqlDao.createOverdueStatus(overdueStatus, context);
 
                         previousStartDate = state.getTimestamp();
                     }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
index 4e1b199..a46a521 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
@@ -25,7 +25,6 @@ import org.skife.jdbi.v2.TransactionStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -42,9 +41,13 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class BusinessSubscriptionTransitionRecorder {
+
     private static final Logger log = LoggerFactory.getLogger(BusinessSubscriptionTransitionRecorder.class);
 
     private final BusinessSubscriptionTransitionSqlDao sqlDao;
@@ -66,10 +69,10 @@ public class BusinessSubscriptionTransitionRecorder {
         this.clock = clock;
     }
 
-    public void rebuildTransitionsForBundle(final UUID bundleId) {
+    public void rebuildTransitionsForBundle(final UUID bundleId, final InternalCallContext context) {
         final SubscriptionBundle bundle;
         try {
-            bundle = entitlementApi.getBundleFromId(bundleId);
+            bundle = entitlementApi.getBundleFromId(bundleId, context.toCallContext());
         } catch (EntitlementUserApiException e) {
             log.warn("Ignoring update for bundle {}: bundle does not exist", bundleId);
             return;
@@ -77,13 +80,13 @@ public class BusinessSubscriptionTransitionRecorder {
 
         final Account account;
         try {
-            account = accountApi.getAccountById(bundle.getAccountId());
+            account = accountApi.getAccountById(bundle.getAccountId(), context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Ignoring update for bundle {}: account {} does not exist", bundleId, bundle.getAccountId());
             return;
         }
 
-        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundleId);
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundleId, context.toCallContext());
 
         final Currency currency = account.getCurrency();
 
@@ -91,7 +94,7 @@ public class BusinessSubscriptionTransitionRecorder {
             @Override
             public Void inTransaction(final BusinessSubscriptionTransitionSqlDao transactional, final TransactionStatus status) throws Exception {
                 log.info("Started rebuilding transitions for bundle id {}", bundleId);
-                transactional.deleteTransitionsForBundle(bundleId.toString());
+                transactional.deleteTransitionsForBundle(bundleId.toString(), context);
 
                 final ArrayList<BusinessSubscriptionTransition> transitions = new ArrayList<BusinessSubscriptionTransition>();
                 for (final Subscription subscription : subscriptions) {
@@ -116,13 +119,13 @@ public class BusinessSubscriptionTransitionRecorder {
                                 nextSubscription
                         );
 
-                        transactional.createTransition(transition);
+                        transactional.createTransition(transition, context);
                         transitions.add(transition);
                         log.info("Adding transition {}", transition);
 
                         // We need to manually add the system cancel event
                         if (SubscriptionTransitionType.CANCEL.equals(event.getTransitionType()) &&
-                                clock.getUTCNow().isAfter(event.getEffectiveTransitionTime())) {
+                            clock.getUTCNow().isAfter(event.getEffectiveTransitionTime())) {
                             final BusinessSubscriptionTransition systemCancelTransition = new BusinessSubscriptionTransition(
                                     event.getTotalOrdering(),
                                     bundleId,
@@ -135,7 +138,7 @@ public class BusinessSubscriptionTransitionRecorder {
                                     prevSubscription,
                                     nextSubscription
                             );
-                            transactional.createTransition(systemCancelTransition);
+                            transactional.createTransition(systemCancelTransition, context);
                             transitions.add(systemCancelTransition);
                             log.info("Adding transition {}", systemCancelTransition);
                         }
@@ -186,7 +189,6 @@ public class BusinessSubscriptionTransitionRecorder {
         return BusinessSubscriptionEvent.subscriptionTransfered(transfered.getNextPlan(), catalogService.getFullCatalog(), transfered.getEffectiveTransitionTime(), transfered.getSubscriptionStartDate());
     }
 
-
     private BusinessSubscriptionEvent subscriptionCancelled(final SubscriptionEvent cancelled) throws AccountApiException, EntitlementUserApiException {
         // cancelled.getNextPlan() is null here - need to look at the previous one to create the correct event name
         return BusinessSubscriptionEvent.subscriptionCancelled(cancelled.getPreviousPlan(), catalogService.getFullCatalog(), cancelled.getEffectiveTransitionTime(), cancelled.getSubscriptionStartDate());
@@ -203,7 +205,7 @@ public class BusinessSubscriptionTransitionRecorder {
     private BusinessSubscription createNextBusinessSubscription(final EffectiveSubscriptionEvent event, final BusinessSubscriptionEvent businessEvent, final Currency currency) {
         final BusinessSubscription nextSubscription;
         if (BusinessSubscriptionEvent.EventType.CANCEL.equals(businessEvent.getEventType()) ||
-                BusinessSubscriptionEvent.EventType.SYSTEM_CANCEL.equals(businessEvent.getEventType())) {
+            BusinessSubscriptionEvent.EventType.SYSTEM_CANCEL.equals(businessEvent.getEventType())) {
             nextSubscription = null;
         } else {
             nextSubscription = new BusinessSubscription(event.getNextPriceList(), event.getNextPlan(), event.getNextPhase(),
@@ -219,8 +221,8 @@ public class BusinessSubscriptionTransitionRecorder {
                                                                     final ArrayList<BusinessSubscriptionTransition> transitions,
                                                                     final Currency currency) {
         if (BusinessSubscriptionEvent.EventType.ADD.equals(businessEvent.getEventType()) ||
-                BusinessSubscriptionEvent.EventType.RE_ADD.equals(businessEvent.getEventType()) ||
-                BusinessSubscriptionEvent.EventType.TRANSFER.equals(businessEvent.getEventType())) {
+            BusinessSubscriptionEvent.EventType.RE_ADD.equals(businessEvent.getEventType()) ||
+            BusinessSubscriptionEvent.EventType.TRANSFER.equals(businessEvent.getEventType())) {
             return null;
         }
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java
index 7708f15..24643fa 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java
@@ -16,9 +16,10 @@
 
 package com.ning.billing.analytics;
 
-import javax.inject.Inject;
 import java.util.UUID;
 
+import javax.inject.Inject;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,9 +33,11 @@ import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.dao.ObjectType;
 
 public class BusinessTagRecorder {
+
     private static final Logger log = LoggerFactory.getLogger(BusinessTagRecorder.class);
 
     private final BusinessAccountTagSqlDao accountTagSqlDao;
@@ -59,55 +62,55 @@ public class BusinessTagRecorder {
         this.entitlementUserApi = entitlementUserApi;
     }
 
-    public void tagAdded(final ObjectType objectType, final UUID objectId, final String name) {
+    public void tagAdded(final ObjectType objectType, final UUID objectId, final String name, final InternalCallContext context) {
         if (objectType.equals(ObjectType.ACCOUNT)) {
-            tagAddedForAccount(objectId, name);
+            tagAddedForAccount(objectId, name, context);
         } else if (objectType.equals(ObjectType.BUNDLE)) {
-            tagAddedForBundle(objectId, name);
+            tagAddedForBundle(objectId, name, context);
         } else if (objectType.equals(ObjectType.INVOICE)) {
-            tagAddedForInvoice(objectId, name);
+            tagAddedForInvoice(objectId, name, context);
         } else if (objectType.equals(ObjectType.PAYMENT)) {
-            tagAddedForPayment(objectId, name);
+            tagAddedForPayment(objectId, name, context);
         } else {
             log.info("Ignoring tag addition of {} for object id {} (type {})", new Object[]{name, objectId.toString(), objectType.toString()});
         }
     }
 
-    public void tagRemoved(final ObjectType objectType, final UUID objectId, final String name) {
+    public void tagRemoved(final ObjectType objectType, final UUID objectId, final String name, final InternalCallContext context) {
         if (objectType.equals(ObjectType.ACCOUNT)) {
-            tagRemovedForAccount(objectId, name);
+            tagRemovedForAccount(objectId, name, context);
         } else if (objectType.equals(ObjectType.BUNDLE)) {
-            tagRemovedForBundle(objectId, name);
+            tagRemovedForBundle(objectId, name, context);
         } else if (objectType.equals(ObjectType.INVOICE)) {
-            tagRemovedForInvoice(objectId, name);
+            tagRemovedForInvoice(objectId, name, context);
         } else if (objectType.equals(ObjectType.PAYMENT)) {
-            tagRemovedForPayment(objectId, name);
+            tagRemovedForPayment(objectId, name, context);
         } else {
             log.info("Ignoring tag removal of {} for object id {} (type {})", new Object[]{name, objectId.toString(), objectType.toString()});
         }
     }
 
-    private void tagAddedForAccount(final UUID accountId, final String name) {
+    private void tagAddedForAccount(final UUID accountId, final String name, final InternalCallContext context) {
         final Account account;
         try {
-            account = accountApi.getAccountById(accountId);
+            account = accountApi.getAccountById(accountId, context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Ignoring tag addition of {} for account id {} (account does not exist)", name, accountId.toString());
             return;
         }
 
         final String accountKey = account.getExternalKey();
-        accountTagSqlDao.addTag(accountId.toString(), accountKey, name);
+        accountTagSqlDao.addTag(accountId.toString(), accountKey, name, context);
     }
 
-    private void tagRemovedForAccount(final UUID accountId, final String name) {
-        accountTagSqlDao.removeTag(accountId.toString(), name);
+    private void tagRemovedForAccount(final UUID accountId, final String name, final InternalCallContext context) {
+        accountTagSqlDao.removeTag(accountId.toString(), name, context);
     }
 
-    private void tagAddedForBundle(final UUID bundleId, final String name) {
+    private void tagAddedForBundle(final UUID bundleId, final String name, final InternalCallContext context) {
         final SubscriptionBundle bundle;
         try {
-            bundle = entitlementUserApi.getBundleFromId(bundleId);
+            bundle = entitlementUserApi.getBundleFromId(bundleId, context.toCallContext());
         } catch (EntitlementUserApiException e) {
             log.warn("Ignoring tag addition of {} for bundle id {} (bundle does not exist)", name, bundleId.toString());
             return;
@@ -115,7 +118,7 @@ public class BusinessTagRecorder {
 
         final Account account;
         try {
-            account = accountApi.getAccountById(bundle.getAccountId());
+            account = accountApi.getAccountById(bundle.getAccountId(), context.toCallContext());
         } catch (AccountApiException e) {
             log.warn("Ignoring tag addition of {} for bundle id {} and account id {} (account does not exist)", new Object[]{name, bundleId.toString(), bundle.getAccountId()});
             return;
@@ -126,26 +129,26 @@ public class BusinessTagRecorder {
          */
         final String accountKey = account.getExternalKey();
         final String externalKey = bundle.getKey();
-        subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId.toString(), externalKey, name);
+        subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId.toString(), externalKey, name, context);
     }
 
-    private void tagRemovedForBundle(final UUID bundleId, final String name) {
-        subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name);
+    private void tagRemovedForBundle(final UUID bundleId, final String name, final InternalCallContext context) {
+        subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name, context);
     }
 
-    private void tagAddedForInvoice(final UUID objectId, final String name) {
-        invoiceTagSqlDao.addTag(objectId.toString(), name);
+    private void tagAddedForInvoice(final UUID objectId, final String name, final InternalCallContext context) {
+        invoiceTagSqlDao.addTag(objectId.toString(), name, context);
     }
 
-    private void tagRemovedForInvoice(final UUID objectId, final String name) {
-        invoiceTagSqlDao.removeTag(objectId.toString(), name);
+    private void tagRemovedForInvoice(final UUID objectId, final String name, final InternalCallContext context) {
+        invoiceTagSqlDao.removeTag(objectId.toString(), name, context);
     }
 
-    private void tagAddedForPayment(final UUID objectId, final String name) {
-        invoicePaymentTagSqlDao.addTag(objectId.toString(), name);
+    private void tagAddedForPayment(final UUID objectId, final String name, final InternalCallContext context) {
+        invoicePaymentTagSqlDao.addTag(objectId.toString(), name, context);
     }
 
-    private void tagRemovedForPayment(final UUID objectId, final String name) {
-        invoicePaymentTagSqlDao.removeTag(objectId.toString(), name);
+    private void tagRemovedForPayment(final UUID objectId, final String name, final InternalCallContext context) {
+        invoicePaymentTagSqlDao.removeTag(objectId.toString(), name, context);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
index 165d087..d99f5b8 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
@@ -26,24 +26,25 @@ import com.ning.billing.analytics.model.BusinessInvoiceItem;
 import com.ning.billing.analytics.model.BusinessInvoicePayment;
 import com.ning.billing.analytics.model.BusinessOverdueStatus;
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface AnalyticsDao {
 
-    TimeSeriesData getAccountsCreatedOverTime();
+    TimeSeriesData getAccountsCreatedOverTime(InternalTenantContext context);
 
-    TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug);
+    TimeSeriesData getSubscriptionsCreatedOverTime(String productType, String slug, InternalTenantContext context);
 
-    BusinessAccount getAccountByKey(final String accountKey);
+    BusinessAccount getAccountByKey(String accountKey, InternalTenantContext context);
 
-    List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey);
+    List<BusinessSubscriptionTransition> getTransitionsByKey(String externalKey, InternalTenantContext context);
 
-    List<BusinessInvoice> getInvoicesByKey(final String accountKey);
+    List<BusinessInvoice> getInvoicesByKey(String accountKey, InternalTenantContext context);
 
-    List<BusinessAccountTag> getTagsForAccount(final String accountKey);
+    List<BusinessAccountTag> getTagsForAccount(String accountKey, InternalTenantContext context);
 
-    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId);
+    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(String invoiceId, InternalTenantContext context);
 
-    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(final String externalKey);
+    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(String externalKey, InternalTenantContext context);
 
-    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(final String accountKey);
+    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(String accountKey, InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
index 4aed48a..f8e00fc 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
@@ -25,20 +25,30 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessAccountField;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessAccountFieldMapper.class)
 public interface BusinessAccountFieldSqlDao {
+
     @SqlQuery
-    List<BusinessAccountField> getFieldsForAccountByKey(@Bind("account_key") final String accountKey);
+    List<BusinessAccountField> getFieldsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addField(@Bind("account_id") final String accountId, @Bind("account_key") final String accountKey,
-                 @Bind("name") final String name, @Bind("value") final String value);
+    int addField(@Bind("account_id") final String accountId,
+                 @Bind("account_key") final String accountKey,
+                 @Bind("name") final String name,
+                 @Bind("value") final String value,
+                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeField(@Bind("account_id") final String accountId, @Bind("name") final String name);
+    int removeField(@Bind("account_id") final String accountId,
+                    @Bind("name") final String name,
+                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
index d2c6d2e..f081a7a 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
@@ -27,26 +27,33 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper({BusinessAccountMapper.class, TimeSeriesTupleMapper.class})
 public interface BusinessAccountSqlDao extends Transactional<BusinessAccountSqlDao>, Transmogrifier {
 
     @SqlQuery
-    List<TimeSeriesTuple> getAccountsCreatedOverTime();
+    List<TimeSeriesTuple> getAccountsCreatedOverTime(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    BusinessAccount getAccount(@Bind("account_id") final String accountId);
+    BusinessAccount getAccount(@Bind("account_id") final String accountId,
+                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    BusinessAccount getAccountByKey(@Bind("account_key") String accountKey);
+    BusinessAccount getAccountByKey(@Bind("account_key") String accountKey,
+                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createAccount(@BusinessAccountBinder final BusinessAccount account);
+    int createAccount(@BusinessAccountBinder final BusinessAccount account,
+                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int saveAccount(@BusinessAccountBinder final BusinessAccount account);
+    int saveAccount(@BusinessAccountBinder final BusinessAccount account,
+                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
index 77cb020..f197c84 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
@@ -25,19 +25,29 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessAccountTagMapper.class)
 public interface BusinessAccountTagSqlDao {
+
     @SqlQuery
-    List<BusinessAccountTag> getTagsForAccountByKey(@Bind("account_key") final String accountKey);
+    List<BusinessAccountTag> getTagsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addTag(@Bind("account_id") final String accountId, @Bind("account_key") final String accountKey, @Bind("name") final String name);
+    int addTag(@Bind("account_id") final String accountId,
+               @Bind("account_key") final String accountKey,
+               @Bind("name") final String name,
+               @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeTag(@Bind("account_id") final String accountId, @Bind("name") final String name);
+    int removeTag(@Bind("account_id") final String accountId,
+                  @Bind("name") final String name,
+                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
index a6a9e18..96e69d1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
@@ -25,19 +25,29 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoiceField;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoiceFieldMapper.class)
 public interface BusinessInvoiceFieldSqlDao {
+
     @SqlQuery
-    List<BusinessInvoiceField> getFieldsForInvoice(@Bind("invoice_id") final String invoiceId);
+    List<BusinessInvoiceField> getFieldsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addField(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name, @Bind("value") final String value);
+    int addField(@Bind("invoice_id") final String invoiceId,
+                 @Bind("name") final String name,
+                 @Bind("value") final String value,
+                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeField(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+    int removeField(@Bind("invoice_id") final String invoiceId,
+                    @Bind("name") final String name,
+                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
index f94293a..1ff220b 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
@@ -27,25 +27,34 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoiceItemMapper.class)
 public interface BusinessInvoiceItemSqlDao extends Transactional<BusinessInvoiceItemSqlDao>, Transmogrifier {
+
     @SqlQuery
-    BusinessInvoiceItem getInvoiceItem(@Bind("item_id") final String itemId);
+    BusinessInvoiceItem getInvoiceItem(@Bind("item_id") final String itemId,
+                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(@Bind("invoice_id") final String invoiceId);
+    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoiceItem> getInvoiceItemsForBundleByKey(@Bind("external_key") final String externalKey);
+    List<BusinessInvoiceItem> getInvoiceItemsForBundleByKey(@Bind("external_key") final String externalKey,
+                                                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItem invoiceItem);
+    int createInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItem invoiceItem,
+                          @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int deleteInvoiceItem(@Bind("item_id") final String itemId);
+    int deleteInvoiceItem(@Bind("item_id") final String itemId,
+                          @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
index 2b85250..c7964f4 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
@@ -25,19 +25,29 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoicePaymentFieldMapper.class)
 public interface BusinessInvoicePaymentFieldSqlDao {
+
     @SqlQuery
-    List<BusinessInvoicePaymentField> getFieldsForInvoicePayment(@Bind("payment_id") final String paymentId);
+    List<BusinessInvoicePaymentField> getFieldsForInvoicePayment(@Bind("payment_id") final String paymentId,
+                                                                 @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addField(@Bind("payment_id") final String paymentId, @Bind("name") final String name, @Bind("value") final String value);
+    int addField(@Bind("payment_id") final String paymentId,
+                 @Bind("name") final String name,
+                 @Bind("value") final String value,
+                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeField(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+    int removeField(@Bind("payment_id") final String paymentId,
+                    @Bind("name") final String name,
+                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
index d21613a..b3fdd5b 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
@@ -27,22 +27,30 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoicePaymentMapper.class)
 public interface BusinessInvoicePaymentSqlDao extends Transactional<BusinessInvoicePaymentSqlDao>, Transmogrifier {
+
     @SqlQuery
-    BusinessInvoicePayment getInvoicePayment(@Bind("payment_id") final String paymentId);
+    BusinessInvoicePayment getInvoicePayment(@Bind("payment_id") final String paymentId,
+                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(@Bind("account_key") final String accountKey);
+    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoicePayment(@BusinessInvoicePaymentBinder final BusinessInvoicePayment payment);
+    int createInvoicePayment(@BusinessInvoicePaymentBinder final BusinessInvoicePayment payment,
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int deleteInvoicePayment(@Bind("payment_id") final String paymentId);
+    int deleteInvoicePayment(@Bind("payment_id") final String paymentId,
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
index 74f67b3..20af667 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
@@ -25,19 +25,28 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoicePaymentTagMapper.class)
 public interface BusinessInvoicePaymentTagSqlDao {
+
     @SqlQuery
-    List<BusinessInvoicePaymentTag> getTagsForInvoicePayment(@Bind("payment_id") final String paymentId);
+    List<BusinessInvoicePaymentTag> getTagsForInvoicePayment(@Bind("payment_id") final String paymentId,
+                                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addTag(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+    int addTag(@Bind("payment_id") final String paymentId,
+               @Bind("name") final String name,
+               @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeTag(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+    int removeTag(@Bind("payment_id") final String paymentId,
+                  @Bind("name") final String name,
+                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
index 73fbb9b..3f22fcc 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
@@ -27,28 +27,38 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoiceMapper.class)
 public interface BusinessInvoiceSqlDao extends Transactional<BusinessInvoiceSqlDao>, Transmogrifier {
+
     @SqlQuery
-    BusinessInvoice getInvoice(@Bind("invoice_id") final String invoiceId);
+    BusinessInvoice getInvoice(@Bind("invoice_id") final String invoiceId,
+                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoice> getInvoicesForAccount(@Bind("account_id") final String accountId);
+    List<BusinessInvoice> getInvoicesForAccount(@Bind("account_id") final String accountId,
+                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoice> getInvoicesForAccountByKey(@Bind("account_key") final String accountKey);
+    List<BusinessInvoice> getInvoicesForAccountByKey(@Bind("account_key") final String accountKey,
+                                                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoice(@BusinessInvoiceBinder final BusinessInvoice invoice);
+    int createInvoice(@BusinessInvoiceBinder final BusinessInvoice invoice,
+                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int deleteInvoice(@Bind("invoice_id") final String invoiceId);
+    int deleteInvoice(@Bind("invoice_id") final String invoiceId,
+                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void deleteInvoicesForAccount(@Bind("account_id") final String accountId);
+    void deleteInvoicesForAccount(@Bind("account_id") final String accountId,
+                                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
index 587f45a..9e3e6f7 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
@@ -25,19 +25,28 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessInvoiceTag;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessInvoiceTagMapper.class)
 public interface BusinessInvoiceTagSqlDao {
+
     @SqlQuery
-    List<BusinessInvoiceTag> getTagsForInvoice(@Bind("invoice_id") final String invoiceId);
+    List<BusinessInvoiceTag> getTagsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addTag(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+    int addTag(@Bind("invoice_id") final String invoiceId,
+               @Bind("name") final String name,
+               @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeTag(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+    int removeTag(@Bind("invoice_id") final String invoiceId,
+                  @Bind("name") final String name,
+                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
index c0d501b..0936c0b 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
@@ -27,19 +27,26 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessOverdueStatusMapper.class)
 public interface BusinessOverdueStatusSqlDao extends Transactional<BusinessOverdueStatusSqlDao>, Transmogrifier {
+
     @SqlQuery
-    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(@Bind("external_key") final String externalKey);
+    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(@Bind("external_key") final String externalKey,
+                                                                 @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createOverdueStatus(@BusinessOverdueStatusBinder final BusinessOverdueStatus status);
+    int createOverdueStatus(@BusinessOverdueStatusBinder final BusinessOverdueStatus status,
+                            @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void deleteOverdueStatusesForBundle(@Bind("bundle_id") final String bundleId);
+    void deleteOverdueStatusesForBundle(@Bind("bundle_id") final String bundleId,
+                                        @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
index 3a3411d..7bdfec1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
@@ -25,20 +25,31 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessSubscriptionTransitionFieldMapper.class)
 public interface BusinessSubscriptionTransitionFieldSqlDao {
+
     @SqlQuery
-    List<BusinessSubscriptionTransitionField> getFieldsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey);
+    List<BusinessSubscriptionTransitionField> getFieldsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
+                                                                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addField(@Bind("account_key") final String accountKey, @Bind("bundle_id") final String bundleId, @Bind("external_key") final String externalKey,
-                 @Bind("name") final String name, @Bind("value") final String value);
+    int addField(@Bind("account_key") final String accountKey,
+                 @Bind("bundle_id") final String bundleId,
+                 @Bind("external_key") final String externalKey,
+                 @Bind("name") final String name,
+                 @Bind("value") final String value,
+                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeField(@Bind("bundle_id") final String bundleId, @Bind("name") final String name);
+    int removeField(@Bind("bundle_id") final String bundleId,
+                    @Bind("name") final String name,
+                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
index e8703a5..6706537 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
@@ -26,6 +26,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper({BusinessSubscriptionTransitionMapper.class, TimeSeriesTupleMapper.class})
@@ -33,20 +36,25 @@ public interface BusinessSubscriptionTransitionSqlDao extends Transactional<Busi
 
     @SqlQuery
     List<TimeSeriesTuple> getSubscriptionsCreatedOverTime(@Bind("product_type") final String productType,
-                                                          @Bind("slug") final String slug);
+                                                          @Bind("slug") final String slug,
+                                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("external_key") final String externalKey);
+    List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("external_key") final String externalKey,
+                                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId);
+    List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
+                                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition);
+    int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition,
+                         @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void deleteTransitionsForBundle(@Bind("bundle_id") final String bundleId);
+    void deleteTransitionsForBundle(@Bind("bundle_id") final String bundleId,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
index 07d4f24..75c1bf5 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
@@ -25,20 +25,30 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(BusinessSubscriptionTransitionTagMapper.class)
 public interface BusinessSubscriptionTransitionTagSqlDao {
+
     @SqlQuery
-    List<BusinessSubscriptionTransitionTag> getTagsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey);
+    List<BusinessSubscriptionTransitionTag> getTagsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
+                                                                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int addTag(@Bind("account_key") final String accountKey, @Bind("bundle_id") final String bundleId,
-               @Bind("external_key") final String externalKey, @Bind("name") final String name);
+    int addTag(@Bind("account_key") final String accountKey,
+               @Bind("bundle_id") final String bundleId,
+               @Bind("external_key") final String externalKey,
+               @Bind("name") final String name,
+               @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int removeTag(@Bind("bundle_id") final String bundleId, @Bind("name") final String name);
+    int removeTag(@Bind("bundle_id") final String bundleId,
+                  @Bind("name") final String name,
+                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
index dc25ba2..59e9af8 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
@@ -29,6 +29,7 @@ import com.ning.billing.analytics.model.BusinessInvoiceItem;
 import com.ning.billing.analytics.model.BusinessInvoicePayment;
 import com.ning.billing.analytics.model.BusinessOverdueStatus;
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public class DefaultAnalyticsDao implements AnalyticsDao {
 
@@ -58,47 +59,47 @@ public class DefaultAnalyticsDao implements AnalyticsDao {
     }
 
     @Override
-    public TimeSeriesData getAccountsCreatedOverTime() {
-        return new DefaultTimeSeriesData(accountSqlDao.getAccountsCreatedOverTime());
+    public TimeSeriesData getAccountsCreatedOverTime(final InternalTenantContext context) {
+        return new DefaultTimeSeriesData(accountSqlDao.getAccountsCreatedOverTime(context));
     }
 
     @Override
-    public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug) {
-        return new DefaultTimeSeriesData(subscriptionTransitionSqlDao.getSubscriptionsCreatedOverTime(productType, slug));
+    public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug, final InternalTenantContext context) {
+        return new DefaultTimeSeriesData(subscriptionTransitionSqlDao.getSubscriptionsCreatedOverTime(productType, slug, context));
     }
 
     @Override
-    public BusinessAccount getAccountByKey(final String accountKey) {
-        return accountSqlDao.getAccountByKey(accountKey);
+    public BusinessAccount getAccountByKey(final String accountKey, final InternalTenantContext context) {
+        return accountSqlDao.getAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey) {
-        return subscriptionTransitionSqlDao.getTransitionsByKey(externalKey);
+    public List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey, final InternalTenantContext context) {
+        return subscriptionTransitionSqlDao.getTransitionsByKey(externalKey, context);
     }
 
     @Override
-    public List<BusinessInvoice> getInvoicesByKey(final String accountKey) {
-        return invoiceSqlDao.getInvoicesForAccountByKey(accountKey);
+    public List<BusinessInvoice> getInvoicesByKey(final String accountKey, final InternalTenantContext context) {
+        return invoiceSqlDao.getInvoicesForAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessAccountTag> getTagsForAccount(final String accountKey) {
-        return accountTagSqlDao.getTagsForAccountByKey(accountKey);
+    public List<BusinessAccountTag> getTagsForAccount(final String accountKey, final InternalTenantContext context) {
+        return accountTagSqlDao.getTagsForAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId) {
-        return invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId);
+    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId, final InternalTenantContext context) {
+        return invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId, context);
     }
 
     @Override
-    public List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(final String externalKey) {
-        return overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey);
+    public List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(final String externalKey, final InternalTenantContext context) {
+        return overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, context);
     }
 
     @Override
-    public List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(final String accountKey) {
-        return invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(accountKey);
+    public List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(final String accountKey, final InternalTenantContext context) {
+        return invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(accountKey, context);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java
index 4664c45..bad0b96 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java
@@ -77,7 +77,9 @@ public class BusinessInvoiceItem {
 
     public BusinessInvoiceItem(@Nullable final String externalKey, final InvoiceItem invoiceItem, @Nullable final Plan plan, @Nullable final PlanPhase planPhase) {
         this(invoiceItem.getAmount(), planPhase != null ? planPhase.getBillingPeriod().toString() : null, new DateTime(DateTimeZone.UTC), invoiceItem.getCurrency(),
-             invoiceItem.getEndDate(), externalKey, invoiceItem.getInvoiceId(), invoiceItem.getId(), invoiceItem.getLinkedItemId(), invoiceItem.getInvoiceItemType().toString(),
+             /* Populate end date for fixed items for convenience (null in invoice_items table) */
+             (invoiceItem.getEndDate() == null && planPhase != null) ? invoiceItem.getStartDate().plus(planPhase.getDuration().toJodaPeriod()) : invoiceItem.getEndDate(),
+             externalKey, invoiceItem.getInvoiceId(), invoiceItem.getId(), invoiceItem.getLinkedItemId(), invoiceItem.getInvoiceItemType().toString(),
              planPhase != null ? planPhase.getPhaseType().toString() : null, plan != null ? plan.getProduct().getCategory().toString() : null,
              plan != null ? plan.getProduct().getName() : null, plan != null ? plan.getProduct().getCatalogName() : null,
              planPhase != null ? planPhase.getName() : null, invoiceItem.getStartDate(), new DateTime(DateTimeZone.UTC));
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg
index 2fd6b5c..996a5d6 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessAccountField;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getFieldsForAccountByKey(account_key) ::=<<
 select
   account_id
@@ -8,6 +11,7 @@ select
 , value
 from bac_fields
 where account_key = :account_key
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -17,18 +21,22 @@ insert into bac_fields (
 , account_key
 , name
 , value
+, account_record_id
+, tenant_record_id
 ) values (
   :account_id
 , :account_key
 , :name
 , :value
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeField(account_id, name) ::= <<
-delete from bac_fields where account_id = :account_id and name = :name;
+delete from bac_fields where account_id = :account_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bac_fields;
+select 1 from bac_fields where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
index c6b9195..3fab53f 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
@@ -1,11 +1,15 @@
 group BusinessAccount;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getAccountsCreatedOverTime() ::= <<
   select
     date(from_unixtime(created_date / 1000)) day
     -- TODO: use account_record_id, once populated
   , count(record_id) count
   from bac
+  where <CHECK_TENANT()>
   group by 1
   order by 1
   ;
@@ -26,8 +30,10 @@ getAccount(account_id) ::= <<
   , credit_card_type
   , billing_address_country
   , currency
+  , tenant_record_id
   from bac
   where account_id=:account_id
+  <AND_CHECK_TENANT()>
   limit 1
   ;
 >>
@@ -47,8 +53,10 @@ getAccountByKey(account_key) ::= <<
   , credit_card_type
   , billing_address_country
   , currency
+  , tenant_record_id
   from bac
   where account_key=:account_key
+  <AND_CHECK_TENANT()>
   limit 1
   ;
 >>
@@ -68,6 +76,8 @@ createAccount() ::= <<
   , credit_card_type
   , billing_address_country
   , currency
+  , account_record_id
+  , tenant_record_id
   ) values (
     :account_id
   , :account_key
@@ -82,6 +92,8 @@ createAccount() ::= <<
   , :credit_card_type
   , :billing_address_country
   , :currency
+  , :accountRecordId
+  , :tenantRecordId
   );
 >>
 
@@ -98,9 +110,10 @@ saveAccount() ::= <<
   , billing_address_country=:billing_address_country
   , currency=:currency
   where account_id=:account_id
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 test() ::= <<
-  select 1 from bac;
+  select 1 from bac where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg
index 5c9a954..ad5365a 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessAccountTag;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getTagsForAccountByKey(account_key) ::=<<
 select
   account_id
@@ -7,6 +10,7 @@ select
 , name
 from bac_tags
 where account_key = :account_key
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -15,17 +19,21 @@ insert into bac_tags (
   account_id
 , account_key
 , name
+, account_record_id
+, tenant_record_id
 ) values (
   :account_id
 , :account_key
 , :name
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeTag(account_id, name) ::= <<
-delete from bac_tags where account_id = :account_id and name = :name;
+delete from bac_tags where account_id = :account_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bac_tags;
+select 1 from bac_tags where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg
index fe0080f..6c1c73a 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessInvoiceField;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getFieldsForInvoice(invoice_id) ::=<<
 select
   invoice_id
@@ -7,6 +10,7 @@ select
 , value
 from bin_fields
 where invoice_id = :invoice_id
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -15,17 +19,21 @@ insert into bin_fields (
   invoice_id
 , name
 , value
+, account_record_id
+, tenant_record_id
 ) values (
   :invoice_id
 , :name
 , :value
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeField(invoice_id, name, value) ::= <<
-delete from bin_fields where invoice_id = :invoice_id and name = :name;
+delete from bin_fields where invoice_id = :invoice_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bin_tags;
+select 1 from bin_tags where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg
index b987105..8fe8ad5 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessInvoiceItem;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getInvoiceItem(item_id) ::= <<
 select
   item_id
@@ -19,8 +22,10 @@ select
 , amount
 , currency
 , linked_item_id
+, tenant_record_id
 from bii
 where item_id = :item_id
+<AND_CHECK_TENANT()>
 limit 1
 ;
 >>
@@ -44,8 +49,10 @@ select
 , amount
 , currency
 , linked_item_id
+, tenant_record_id
 from bii
 where invoice_id = :invoice_id
+<AND_CHECK_TENANT()>
 order by created_date asc
 ;
 >>
@@ -69,8 +76,10 @@ select
 , amount
 , currency
 , linked_item_id
+, tenant_record_id
 from bii
 where external_key = :external_key
+<AND_CHECK_TENANT()>
 order by created_date asc
 ;
 >>
@@ -94,6 +103,8 @@ insert into bii (
 , amount
 , currency
 , linked_item_id
+, account_record_id
+, tenant_record_id
 ) values (
   :item_id
 , :created_date
@@ -112,13 +123,15 @@ insert into bii (
 , :amount
 , :currency
 , :linked_item_id
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 deleteInvoiceItem(item_id) ::= <<
-delete from bii where item_id = :item_id;
+delete from bii where item_id = :item_id <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bii;
+select 1 from bii where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg
index a2ced92..e14b987 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessInvoicePaymentField;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getFieldsForInvoicePayment(payment_id) ::=<<
 select
   payment_id
@@ -7,6 +10,7 @@ select
 , value
 from bip_fields
 where payment_id = :payment_id
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -15,17 +19,21 @@ insert into bip_fields (
   payment_id
 , name
 , value
+, account_record_id
+, tenant_record_id
 ) values (
   :payment_id
 , :name
 , :value
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeField(payment_id, name) ::= <<
-delete from bip_fields where payment_id = :payment_id and name = :name;
+delete from bip_fields where payment_id = :payment_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bip_fields;
+select 1 from bip_fields where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg
index 54f8d22..385bb38 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessInvoicePayment;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getInvoicePayment(payment_id) ::= <<
 select
   payment_id
@@ -22,8 +25,10 @@ select
 , card_country
 , invoice_payment_type
 , linked_invoice_payment_id
+, tenant_record_id
 from bip
 where payment_id = :payment_id
+<AND_CHECK_TENANT()>
 limit 1
 ;
 >>
@@ -50,8 +55,10 @@ select
 , card_country
 , invoice_payment_type
 , linked_invoice_payment_id
+, tenant_record_id
 from bip
 where account_key = :account_key
+<AND_CHECK_TENANT()>
 order by created_date asc
 ;
 >>
@@ -78,6 +85,8 @@ insert into bip (
 , card_country
 , invoice_payment_type
 , linked_invoice_payment_id
+, account_record_id
+, tenant_record_id
 ) values (
   :payment_id
 , :created_date
@@ -99,13 +108,15 @@ insert into bip (
 , :card_country
 , :invoice_payment_type
 , :linked_invoice_payment_id
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 deleteInvoicePayment(payment_id) ::= <<
-delete from bip where payment_id = :payment_id
+delete from bip where payment_id = :payment_id <AND_CHECK_TENANT()>
 >>
 
 test() ::= <<
-select 1 from bip;
+select 1 from bip where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg
index 57553ad..a5ff50b 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg
@@ -1,11 +1,16 @@
 group BusinessInvoicePaymentTag;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getTagsForInvoicePayment(payment_id) ::=<<
 select
   payment_id
 , name
+, tenant_record_id
 from bip_tags
 where payment_id = :payment_id
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -13,16 +18,20 @@ addTag(payment_id, name) ::=<<
 insert into bip_tags (
   payment_id
 , name
+, account_record_id
+, tenant_record_id
 ) values (
   :payment_id
 , :name
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeTag(payment_id, name) ::= <<
-delete from bip_tags where payment_id = :payment_id and name = :name;
+delete from bip_tags where payment_id = :payment_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bip_tags;
+select 1 from bip_tags where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg
index fed7d20..46a69e7 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessInvoice;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getInvoice(invoice_id) ::= <<
 select
   invoice_id
@@ -15,8 +18,10 @@ select
 , amount_paid
 , amount_charged
 , amount_credited
+, tenant_record_id
 from bin
 where invoice_id = :invoice_id
+<AND_CHECK_TENANT()>
 limit 1
 ;
 >>
@@ -36,8 +41,10 @@ select
 , amount_paid
 , amount_charged
 , amount_credited
+, tenant_record_id
 from bin
 where account_id = :account_id
+<AND_CHECK_TENANT()>
 order by created_date asc
 ;
 >>
@@ -57,8 +64,10 @@ select
 , amount_paid
 , amount_charged
 , amount_credited
+, tenant_record_id
 from bin
 where account_key = :account_key
+<AND_CHECK_TENANT()>
 order by created_date asc
 ;
 >>
@@ -78,6 +87,8 @@ insert into bin (
 , amount_paid
 , amount_charged
 , amount_credited
+, account_record_id
+, tenant_record_id
 ) values (
   :invoice_id
 , :invoice_number
@@ -92,6 +103,8 @@ insert into bin (
 , :amount_paid
 , :amount_charged
 , :amount_credited
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
@@ -108,17 +121,18 @@ update bin set
 , amount_charged = :amount_charged
 , amount_credited = :amount_credited
 where invoice_id = :invoice_id
+<AND_CHECK_TENANT()>
 ;
 >>
 
 deleteInvoice(invoice_id) ::= <<
-delete from bin where invoice_id = :invoice_id;
+delete from bin where invoice_id = :invoice_id <AND_CHECK_TENANT()>;
 >>
 
 deleteInvoicesForAccount(account_id) ::= <<
-delete from bin where account_id = :account_id;
+delete from bin where account_id = :account_id <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bin;
+select 1 from bin where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg
index f01a7d7..083401c 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg
@@ -1,11 +1,16 @@
 group BusinessInvoiceTag;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getTagsForInvoice(invoice_id) ::=<<
 select
   invoice_id
 , name
+, tenant_record_id
 from bin_tags
 where invoice_id = :invoice_id
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -13,16 +18,20 @@ addTag(invoice_id, name) ::=<<
 insert into bin_tags (
   invoice_id
 , name
+, account_record_id
+, tenant_record_id
 ) values (
   :invoice_id
 , :name
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeTag(invoice_id, name) ::= <<
-delete from bin_tags where invoice_id = :invoice_id and name = :name;
+delete from bin_tags where invoice_id = :invoice_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bin_tags;
+select 1 from bin_tags where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg
index 532a39b..2102bc3 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessOverdueStatus;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getOverdueStatusesForBundleByKey(external_key) ::= <<
 select
   bundle_id
@@ -8,8 +11,10 @@ select
 , status
 , start_date
 , end_date
+, tenant_record_id
 from bos
 where external_key = :external_key
+<AND_CHECK_TENANT()>
 order by start_date asc
 ;
 >>
@@ -22,6 +27,8 @@ insert into bos (
 , status
 , start_date
 , end_date
+, account_record_id
+, tenant_record_id
 ) values (
   :bundle_id
 , :external_key
@@ -29,13 +36,15 @@ insert into bos (
 , :status
 , :start_date
 , :end_date
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 deleteOverdueStatusesForBundle(bundle_id) ::= <<
-delete from bos where bundle_id = :bundle_id;
+delete from bos where bundle_id = :bundle_id <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bos;
+select 1 from bos where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg
index 8480e3f..52b0db3 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessSubscriptionTransitionField;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getFieldsForBusinessSubscriptionTransitionByKey(external_key) ::=<<
 select
   bundle_id
@@ -7,8 +10,10 @@ select
 , account_key
 , name
 , value
+, tenant_record_id
 from bst_fields
 where external_key = :external_key
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -19,19 +24,23 @@ insert into bst_fields (
 , account_key
 , name
 , value
+, account_record_id
+, tenant_record_id
 ) values (
   :bundle_id
 , :external_key
 , :account_key
 , :name
 , :value
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeField(bundle_id, name) ::= <<
-delete from bst_fields where bundle_id = :bundle_id and name = :name;
+delete from bst_fields where bundle_id = :bundle_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bst_fields;
+select 1 from bst_fields where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.sql.stg
index 8a1d2f6..8649840 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BusinessSubscriptionTransition;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getSubscriptionsCreatedOverTime(product_type, slug) ::= <<
   select
     date(from_unixtime(requested_timestamp / 1000)) day
@@ -8,6 +11,7 @@ getSubscriptionsCreatedOverTime(product_type, slug) ::= <<
   where event in ('ADD_ADD_ON', 'ADD_BASE', 'ADD_STANDALONE')
   and next_product_type = :product_type
   and next_slug = :slug
+  <AND_CHECK_TENANT()>
   group by 1
   order by 1
   ;
@@ -47,8 +51,10 @@ getTransitionsByKey(external_key) ::= <<
   , next_currency
   , next_start_date
   , next_state
+  , tenant_record_id
   from bst
   where external_key=:external_key
+  <AND_CHECK_TENANT()>
   order by requested_timestamp asc
   ;
 >>
@@ -87,8 +93,10 @@ getTransitionForSubscription(subscription_id) ::= <<
   , next_currency
   , next_start_date
   , next_state
+  , tenant_record_id
   from bst
   where subscription_id = :subscription_id
+  <AND_CHECK_TENANT()>
   order by requested_timestamp asc
   ;
 >>
@@ -127,6 +135,8 @@ createTransition() ::= <<
   , next_currency
   , next_start_date
   , next_state
+  , account_record_id
+  , tenant_record_id
   ) values (
     :total_ordering
   , :bundle_id
@@ -160,15 +170,18 @@ createTransition() ::= <<
   , :next_currency
   , :next_start_date
   , :next_state
+  , :accountRecordId
+  , :tenantRecordId
   );
 >>
 
 deleteTransitionsForBundle(bundle_id) ::= <<
   delete from bst
   where bundle_id=:bundle_id
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 test() ::= <<
-  select 1 from bst;
+  select 1 from bst where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg
index 2eb6f37..d3ebce1 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg
@@ -1,13 +1,18 @@
 group BusinessSubscriptionTransitionTag;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getTagsForBusinessSubscriptionTransitionByKey(external_key) ::=<<
 select
   bundle_id
 , external_key
 , account_key
 , name
+, tenant_record_id
 from bst_tags
 where external_key = :external_key
+<AND_CHECK_TENANT()>
 ;
 >>
 
@@ -17,18 +22,22 @@ insert into bst_tags (
 , external_key
 , account_key
 , name
+, account_record_id
+, tenant_record_id
 ) values (
   :bundle_id
 , :external_key
 , :account_key
 , :name
+, :accountRecordId
+, :tenantRecordId
 );
 >>
 
 removeTag(bundle_id, name) ::= <<
-delete from bst_tags where bundle_id = :bundle_id and name = :name;
+delete from bst_tags where bundle_id = :bundle_id and name = :name <AND_CHECK_TENANT()>;
 >>
 
 test() ::= <<
-select 1 from bst_tags;
+select 1 from bst_tags where <CHECK_TENANT()>;
 >>
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 86bec0a..dc3e1a8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -80,10 +80,6 @@ import com.ning.billing.payment.dao.PaymentAttemptModelDao;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.dao.PaymentModelDao;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
@@ -106,7 +102,6 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
     private static final BigDecimal INVOICE_AMOUNT = BigDecimal.valueOf(1243.11);
 
     private final Clock clock = new DefaultClock();
-    private final CallContext context = new DefaultCallContextFactory(clock).createCallContext("Analytics Test", CallOrigin.TEST, UserType.TEST);
 
     @Inject
     private AccountUserApi accountApi;
@@ -166,7 +161,7 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
                 .build();
 
         try {
-            final Account storedAccount = accountApi.createAccount(account, context);
+            final Account storedAccount = accountApi.createAccount(account, callContext);
 
             // Create events for the bus and expected results
             createSubscriptionTransitionEvent(storedAccount);
@@ -178,7 +173,7 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
     }
 
     private void createSubscriptionTransitionEvent(final Account account) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), BUNDLE_EXTERNAL_KEY, context);
+        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), BUNDLE_EXTERNAL_KEY, callContext);
 
         // Verify we correctly initialized the account subsystem
         Assert.assertNotNull(bundle);
@@ -234,8 +229,8 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
                 INVOICE_AMOUNT, ACCOUNT_CURRENCY);
         invoice.addInvoiceItem(invoiceItem);
 
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
-        final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId());
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId(), internalCallContext);
         Assert.assertEquals(invoices.size(), 1);
         Assert.assertEquals(invoices.get(0).getInvoiceItems().size(), 1);
 
@@ -250,8 +245,8 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
                                                                 BigDecimal.ONE, Currency.USD, clock.getUTCNow(), PaymentStatus.SUCCESS);
         final PaymentAttemptModelDao paymentAttempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), paymentInfo.getId(),
                                                                                  clock.getUTCNow(), BigDecimal.ONE);
-        paymentDao.insertPaymentWithAttempt(paymentInfo, paymentAttempt, context);
-        Assert.assertEquals(paymentDao.getPaymentsForAccount(account.getId()).size(), 1);
+        paymentDao.insertPaymentWithAttempt(paymentInfo, paymentAttempt, internalCallContext);
+        Assert.assertEquals(paymentDao.getPaymentsForAccount(account.getId(), internalCallContext).size(), 1);
     }
 
     // Flaky
@@ -267,12 +262,12 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
             Assert.fail("Unable to start the bus or service! " + t);
         }
 
-        Assert.assertNull(accountSqlDao.getAccountByKey(ACCOUNT_KEY));
+        Assert.assertNull(accountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext));
 
         // Send events and wait for the async part...
         bus.post(accountCreationNotification);
         Thread.sleep(5000);
-        Assert.assertNotNull(accountSqlDao.getAccountByKey(ACCOUNT_KEY));
+        Assert.assertNotNull(accountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext));
 
         // Test subscriptions integration - this is just to exercise the code. It's hard to test the actual subscriptions
         // as we would need to mock a bunch of APIs (see integration tests in Beatrix instead)
@@ -280,12 +275,12 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
         Thread.sleep(5000);
 
         // Test invoice integration - the account creation notification has triggered a BAC update
-        Assert.assertEquals(accountSqlDao.getAccountByKey(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT), 1);
+        Assert.assertEquals(accountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT), 1);
 
         // Post the same invoice event again - the invoice balance shouldn't change
         bus.post(invoiceCreationNotification);
         Thread.sleep(5000);
-        Assert.assertEquals(accountSqlDao.getAccountByKey(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT), 1);
+        Assert.assertEquals(accountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT), 1);
 
         // Test payment integration - the fields have already been populated, just make sure the code is exercised
         // It's hard to test the actual payments fields though in bac, since we should mock the plugin
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
index 45ef9b9..b76e1cf 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
@@ -54,12 +54,15 @@ import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.mock.MockPlan;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
 public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedDB {
 
     private final Clock clock = new ClockMock();
+    private final TenantContext tenantContext = Mockito.mock(TenantContext.class);
 
     private AnalyticsUserApi analyticsUserApi;
     private BusinessAccountSqlDao accountSqlDao;
@@ -83,16 +86,16 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
 
         final AnalyticsDao analyticsDao = new DefaultAnalyticsDao(accountSqlDao, subscriptionTransitionSqlDao, invoiceSqlDao,
                                                                   invoiceItemSqlDao, accountTagSqlDao, overdueStatusSqlDao, invoicePaymentSqlDao);
-        analyticsUserApi = new DefaultAnalyticsUserApi(analyticsDao);
+        analyticsUserApi = new DefaultAnalyticsUserApi(analyticsDao, new InternalCallContextFactory(dbi, clock));
     }
 
     @Test(groups = "slow")
     public void testAccountsCreatedOverTime() throws Exception {
         final BusinessAccount account = new BusinessAccount(UUID.randomUUID(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
                                                             BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE", "USD");
-        accountSqlDao.createAccount(account);
+        accountSqlDao.createAccount(account, internalCallContext);
 
-        final TimeSeriesData data = analyticsUserApi.getAccountsCreatedOverTime();
+        final TimeSeriesData data = analyticsUserApi.getAccountsCreatedOverTime(tenantContext);
         Assert.assertEquals(data.getDates().size(), 1);
         Assert.assertEquals(data.getDates().get(0), new LocalDate());
         Assert.assertEquals(data.getValues().size(), 1);
@@ -120,13 +123,13 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
                 null,
                 new BusinessSubscription("DEFAULT", plan.getName(), phase.getName(), Currency.USD, clock.getUTCNow(), Subscription.SubscriptionState.ACTIVE, catalog)
         );
-        subscriptionTransitionSqlDao.createTransition(transition);
+        subscriptionTransitionSqlDao.createTransition(transition, internalCallContext);
 
-        final TimeSeriesData notFoundData = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, UUID.randomUUID().toString());
+        final TimeSeriesData notFoundData = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, UUID.randomUUID().toString(), tenantContext);
         Assert.assertEquals(notFoundData.getDates().size(), 0);
         Assert.assertEquals(notFoundData.getValues().size(), 0);
 
-        final TimeSeriesData data = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, phase.getName());
+        final TimeSeriesData data = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, phase.getName(), tenantContext);
         Assert.assertEquals(data.getDates().size(), 1);
         Assert.assertEquals(data.getDates().get(0), new LocalDate());
         Assert.assertEquals(data.getValues().size(), 1);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index ca8b024..a0b49fe 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -99,7 +99,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
         // Healthcheck test to make sure MySQL is setup properly
         try {
-            businessSubscriptionTransitionSqlDao.test();
+            businessSubscriptionTransitionSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
@@ -114,7 +114,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
         // Healthcheck test to make sure MySQL is setup properly
         try {
-            businessAccountSqlDao.test();
+            businessAccountSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
@@ -134,9 +134,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 null,
                 transition.getNextSubscription()
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
     }
@@ -155,9 +155,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 transition.getPreviousSubscription(),
                 null
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullNext);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullNext, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullNext);
     }
@@ -177,9 +177,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 subscriptionWithNullFields,
                 subscriptionWithNullFields
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullFields);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullFields, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullFields);
     }
@@ -199,9 +199,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 subscriptionWithNullPlanAndPhase,
                 subscriptionWithNullPlanAndPhase
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlanAndPhase);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlanAndPhase, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
@@ -225,9 +225,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 subscriptionWithNullPlan,
                 subscriptionWithNullPlan
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlan);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlan, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         // Null Plan but Phase - we don't turn the subscription into a null
         Assert.assertEquals(transitions.get(0), transitionWithNullPlan);
@@ -248,9 +248,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
                 subscriptionWithNullPhase,
                 subscriptionWithNullPhase
         );
-        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPhase);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPhase, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
@@ -264,20 +264,20 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testCreateAndRetrieveTransitions() {
-        businessSubscriptionTransitionSqlDao.createTransition(transition);
+        businessSubscriptionTransitionSqlDao.createTransition(transition, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transition);
 
-        Assert.assertEquals(businessSubscriptionTransitionSqlDao.getTransitionsByKey("Doesn't exist").size(), 0);
+        Assert.assertEquals(businessSubscriptionTransitionSqlDao.getTransitionsByKey("Doesn't exist", internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
     public void testCreateSaveAndRetrieveAccounts() {
         // Create and retrieve an account
-        businessAccountSqlDao.createAccount(account);
-        final BusinessAccount foundAccount = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY);
+        businessAccountSqlDao.createAccount(account, internalCallContext);
+        final BusinessAccount foundAccount = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext);
         Assert.assertNotNull(foundAccount.getCreatedDt());
         Assert.assertEquals(foundAccount.getCreatedDt(), foundAccount.getUpdatedDt());
         // Verify the dates by backfilling them
@@ -290,15 +290,15 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         account.setBalance(BigDecimal.TEN);
         account.setPaymentMethod("PayPal");
         account.setCurrency("CAD");
-        businessAccountSqlDao.saveAccount(account);
+        businessAccountSqlDao.saveAccount(account, internalCallContext);
         // Verify the save worked as expected
-        account = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY);
+        account = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext);
         Assert.assertEquals(Rounder.round(BigDecimal.TEN), account.getRoundedBalance());
         Assert.assertEquals("PayPal", account.getPaymentMethod());
         Assert.assertEquals("CAD", account.getCurrency());
         Assert.assertTrue(account.getUpdatedDt().compareTo(previousUpdatedDt) > 0);
 
         // ACCOUNT not found
-        Assert.assertNull(businessAccountSqlDao.getAccountByKey("Doesn't exist"));
+        Assert.assertNull(businessAccountSqlDao.getAccountByKey("Doesn't exist", internalCallContext));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
index 196da64..c3d7167 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
@@ -44,12 +44,12 @@ public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         final String value = UUID.randomUUID().toString();
 
         // Verify initial state
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey).size(), 0);
-        Assert.assertEquals(accountFieldSqlDao.removeField(accountId.toString(), name), 0);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey, internalCallContext).size(), 0);
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountId.toString(), name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(accountFieldSqlDao.addField(accountId.toString(), accountKey, name, value), 1);
-        final List<BusinessAccountField> fieldsForAccount = accountFieldSqlDao.getFieldsForAccountByKey(accountKey);
+        Assert.assertEquals(accountFieldSqlDao.addField(accountId.toString(), accountKey, name, value, internalCallContext), 1);
+        final List<BusinessAccountField> fieldsForAccount = accountFieldSqlDao.getFieldsForAccountByKey(accountKey, internalCallContext);
         Assert.assertEquals(fieldsForAccount.size(), 1);
 
         // Retrieve it
@@ -60,8 +60,8 @@ public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         Assert.assertEquals(accountField.getValue(), value);
 
         // Delete it
-        Assert.assertEquals(accountFieldSqlDao.removeField(accountId.toString(), name), 1);
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey).size(), 0);
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountId.toString(), name, internalCallContext), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -74,24 +74,24 @@ public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         final String name2 = UUID.randomUUID().toString().substring(0, 30);
 
         // Add a field to both accounts
-        Assert.assertEquals(accountFieldSqlDao.addField(accountId1.toString(), accountKey1, name1, UUID.randomUUID().toString()), 1);
-        Assert.assertEquals(accountFieldSqlDao.addField(accountId2.toString(), accountKey2, name2, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(accountFieldSqlDao.addField(accountId1.toString(), accountKey1, name1, UUID.randomUUID().toString(), internalCallContext), 1);
+        Assert.assertEquals(accountFieldSqlDao.addField(accountId2.toString(), accountKey2, name2, UUID.randomUUID().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey1).size(), 1);
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey2).size(), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey1, internalCallContext).size(), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey2, internalCallContext).size(), 1);
 
         // Remove the field for the first account
-        Assert.assertEquals(accountFieldSqlDao.removeField(accountId1.toString(), name1), 1);
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountId1.toString(), name1, internalCallContext), 1);
 
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey1).size(), 0);
-        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey2).size(), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey1, internalCallContext).size(), 0);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccountByKey(accountKey2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            accountFieldSqlDao.test();
+            accountFieldSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
index 1a55220..90f7f58 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
@@ -43,12 +43,12 @@ public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         final String name = UUID.randomUUID().toString().substring(0, 20);
 
         // Verify initial state
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey).size(), 0);
-        Assert.assertEquals(accountTagSqlDao.removeTag(accountId.toString(), name), 0);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountId.toString(), name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(accountTagSqlDao.addTag(accountId.toString(), accountKey, name), 1);
-        final List<BusinessAccountTag> tagsForAccount = accountTagSqlDao.getTagsForAccountByKey(accountKey);
+        Assert.assertEquals(accountTagSqlDao.addTag(accountId.toString(), accountKey, name, internalCallContext), 1);
+        final List<BusinessAccountTag> tagsForAccount = accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext);
         Assert.assertEquals(tagsForAccount.size(), 1);
 
         // Retrieve it
@@ -58,8 +58,8 @@ public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         Assert.assertEquals(accountTag.getName(), name);
 
         // Delete it
-        Assert.assertEquals(accountTagSqlDao.removeTag(accountId.toString(), name), 1);
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountId.toString(), name, internalCallContext), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -72,24 +72,24 @@ public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         final String name2 = UUID.randomUUID().toString().substring(0, 20);
 
         // Add a tag to both accounts
-        Assert.assertEquals(accountTagSqlDao.addTag(accountId1.toString(), accountKey1, name1), 1);
-        Assert.assertEquals(accountTagSqlDao.addTag(accountId2.toString(), accountKey2, name2), 1);
+        Assert.assertEquals(accountTagSqlDao.addTag(accountId1.toString(), accountKey1, name1, internalCallContext), 1);
+        Assert.assertEquals(accountTagSqlDao.addTag(accountId2.toString(), accountKey2, name2, internalCallContext), 1);
 
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey1).size(), 1);
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey2).size(), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey1, internalCallContext).size(), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey2, internalCallContext).size(), 1);
 
         // Remove the tag for the first account
-        Assert.assertEquals(accountTagSqlDao.removeTag(accountId1.toString(), name1), 1);
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountId1.toString(), name1, internalCallContext), 1);
 
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey1).size(), 0);
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey2).size(), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey1, internalCallContext).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            accountTagSqlDao.test();
+            accountTagSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
index 910fe74..72f70e0 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
@@ -43,12 +43,12 @@ public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         final String value = UUID.randomUUID().toString();
 
         // Verify initial state
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId).size(), 0);
-        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId, internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId, name, value), 1);
-        final List<BusinessInvoiceField> fieldsForInvoice = invoiceFieldSqlDao.getFieldsForInvoice(invoiceId);
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId, name, value, internalCallContext), 1);
+        final List<BusinessInvoiceField> fieldsForInvoice = invoiceFieldSqlDao.getFieldsForInvoice(invoiceId, internalCallContext);
         Assert.assertEquals(fieldsForInvoice.size(), 1);
 
         // Retrieve it
@@ -58,8 +58,8 @@ public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         Assert.assertEquals(invoiceField.getValue(), value);
 
         // Delete it
-        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name), 1);
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId).size(), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name, internalCallContext), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -70,24 +70,24 @@ public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
         final String name2 = UUID.randomUUID().toString().substring(0, 30);
 
         // Add a field to both invoices
-        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId1, name1, UUID.randomUUID().toString()), 1);
-        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId2, name2, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId1, name1, UUID.randomUUID().toString(), internalCallContext), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId2, name2, UUID.randomUUID().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1).size(), 1);
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2).size(), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1, internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2, internalCallContext).size(), 1);
 
         // Remove the field for the first invoice
-        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId1, name1), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId1, name1, internalCallContext), 1);
 
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1).size(), 0);
-        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2).size(), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1, internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoiceFieldSqlDao.test();
+            invoiceFieldSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
index 9c1db5d..494abc4 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
@@ -51,24 +51,24 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
         final BusinessInvoiceItem invoiceItem = createInvoiceItem(invoiceId, externalKey);
 
         // Verify initial state
-        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()));
-        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString()), 0);
+        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext));
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext), 0);
 
         // Add the invoice item
-        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem), 1);
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem, internalCallContext), 1);
 
         // Retrieve it
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()), invoiceItem);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey()).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey()).get(0), invoiceItem);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).get(0), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey(), internalCallContext).get(0), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString(), internalCallContext).get(0), invoiceItem);
 
         // Delete it
-        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString()), 1);
-        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()));
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey()).size(), 0);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext), 1);
+        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext));
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(invoiceItem.getExternalKey(), internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString(), internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -81,28 +81,28 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
         final BusinessInvoiceItem invoiceItem2 = createInvoiceItem(invoiceId2, externalKey2);
 
         // Create both invoice items
-        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem1), 1);
-        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem2), 1);
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem1, internalCallContext), 1);
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem2, internalCallContext), 1);
 
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey1).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey2).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString()).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey1, internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey2, internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString(), internalCallContext).size(), 1);
 
         // Remove the first invoice item
-        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem1.getItemId().toString()), 1);
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem1.getItemId().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey1).size(), 0);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey2).size(), 1);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString()).size(), 0);
-        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey1, internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundleByKey(externalKey2, internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString(), internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString(), internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoiceItemSqlDao.test();
+            invoiceItemSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
index c898a7f..9ee46c7 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
@@ -43,12 +43,12 @@ public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWit
         final String value = UUID.randomUUID().toString();
 
         // Verify initial state
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId).size(), 0);
-        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId, internalCallContext).size(), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId, name, value), 1);
-        final List<BusinessInvoicePaymentField> fieldsForInvoicePayment = invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId, name, value, internalCallContext), 1);
+        final List<BusinessInvoicePaymentField> fieldsForInvoicePayment = invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId, internalCallContext);
         Assert.assertEquals(fieldsForInvoicePayment.size(), 1);
 
         // Retrieve it
@@ -58,8 +58,8 @@ public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWit
         Assert.assertEquals(invoicePaymentField.getValue(), value);
 
         // Delete it
-        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name), 1);
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId).size(), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name, internalCallContext), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -70,24 +70,24 @@ public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWit
         final String name2 = UUID.randomUUID().toString().substring(0, 30);
 
         // Add a field to both invoice payments
-        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId1, name1, UUID.randomUUID().toString()), 1);
-        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId2, name2, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId1, name1, UUID.randomUUID().toString(), internalCallContext), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId2, name2, UUID.randomUUID().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1).size(), 1);
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2).size(), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1, internalCallContext).size(), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2, internalCallContext).size(), 1);
 
         // Remove the field for the first invoice payment
-        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId1, name1), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId1, name1, internalCallContext), 1);
 
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1).size(), 0);
-        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2).size(), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1, internalCallContext).size(), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoicePaymentFieldSqlDao.test();
+            invoicePaymentFieldSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
index 302881a..c4eb863 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
@@ -47,21 +47,21 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         final BusinessInvoicePayment invoicePayment = createInvoicePayment(extFirstPaymentRefId, extSecondPaymentRefId, accountKey);
 
         // Verify initial state
-        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString()));
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey()).size(), 0);
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString(), internalCallContext));
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey(), internalCallContext).size(), 0);
 
         // Add the invoice payment
-        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment, internalCallContext), 1);
 
         // Retrieve it
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString()), invoicePayment);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey()).size(), 1);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey()).get(0), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString(), internalCallContext), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey(), internalCallContext).get(0), invoicePayment);
 
         // Delete it
-        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePayment(invoicePayment.getPaymentId().toString()), 1);
-        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString()));
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey()).size(), 0);
+        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePayment(invoicePayment.getPaymentId().toString(), internalCallContext), 1);
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString(), internalCallContext));
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment.getAccountKey(), internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -76,28 +76,28 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         final BusinessInvoicePayment invoicePayment2 = createInvoicePayment(extFirstPaymentRefId2, extSecondPaymentRefId2,  accountKey2);
 
         // Create both invoice payments
-        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment1), 1);
-        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment2), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment1, internalCallContext), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment2, internalCallContext), 1);
 
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment1.getPaymentId().toString()), invoicePayment1);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment2.getPaymentId().toString()), invoicePayment2);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment1.getAccountKey()).size(), 1);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment2.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment1.getPaymentId().toString(), internalCallContext), invoicePayment1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment2.getPaymentId().toString(), internalCallContext), invoicePayment2);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment1.getAccountKey(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment2.getAccountKey(), internalCallContext).size(), 1);
 
         // Remove the first invoice payment
-        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePayment(invoicePayment1.getPaymentId().toString()), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePayment(invoicePayment1.getPaymentId().toString(), internalCallContext), 1);
 
-        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment1.getPaymentId().toString()));
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment2.getPaymentId().toString()), invoicePayment2);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment1.getAccountKey()).size(), 0);
-        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment2.getAccountKey()).size(), 1);
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment1.getPaymentId().toString(), internalCallContext));
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePayment(invoicePayment2.getPaymentId().toString(), internalCallContext), invoicePayment2);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment1.getAccountKey(), internalCallContext).size(), 0);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(invoicePayment2.getAccountKey(), internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoicePaymentSqlDao.test();
+            invoicePaymentSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
index 2fa6025..a3d4be3 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
@@ -42,12 +42,12 @@ public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithE
         final String name = UUID.randomUUID().toString().substring(0, 20);
 
         // Verify initial state
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId).size(), 0);
-        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId, internalCallContext).size(), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId, name), 1);
-        final List<BusinessInvoicePaymentTag> tagsForInvoicePayment = invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId);
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId, name, internalCallContext), 1);
+        final List<BusinessInvoicePaymentTag> tagsForInvoicePayment = invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId, internalCallContext);
         Assert.assertEquals(tagsForInvoicePayment.size(), 1);
 
         // Retrieve it
@@ -56,8 +56,8 @@ public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithE
         Assert.assertEquals(invoicePaymentTag.getName(), name);
 
         // Delete it
-        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name), 1);
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId).size(), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name, internalCallContext), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -68,24 +68,24 @@ public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithE
         final String name2 = UUID.randomUUID().toString().substring(0, 20);
 
         // Add a tag to both invoice payments
-        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId1, name1), 1);
-        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId2, name2), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId1, name1, internalCallContext), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId2, name2, internalCallContext), 1);
 
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1).size(), 1);
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2).size(), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1, internalCallContext).size(), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2, internalCallContext).size(), 1);
 
         // Remove the tag for the first invoice payment
-        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId1, name1), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId1, name1, internalCallContext), 1);
 
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1).size(), 0);
-        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2).size(), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1, internalCallContext).size(), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoicePaymentTagSqlDao.test();
+            invoicePaymentTagSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
index 515b14e..f273ed2 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
@@ -52,21 +52,21 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         final BusinessInvoice invoice = createInvoice(accountId, invoiceId, accountKey);
 
         // Verify initial state
-        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()));
-        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString()), 0);
+        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString(), internalCallContext));
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString(), internalCallContext), 0);
 
         // Add the invoice
-        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice), 1);
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice, internalCallContext), 1);
 
         // Retrieve it
-        Assert.assertEquals(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()), invoice);
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString()).size(), 1);
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString()).get(0), invoice);
+        Assert.assertEquals(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString(), internalCallContext), invoice);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString(), internalCallContext).get(0), invoice);
 
         // Delete it
-        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString()), 1);
-        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()));
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString()).size(), 0);
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString(), internalCallContext), 1);
+        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString(), internalCallContext));
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountId().toString(), internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -81,24 +81,24 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         final BusinessInvoice invoice2 = createInvoice(invoiceId2, accountId2, accountKey2);
 
         // Create both invoices
-        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice1), 1);
-        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice2), 1);
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice1, internalCallContext), 1);
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice2, internalCallContext), 1);
 
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId1.toString()).size(), 1);
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId2.toString()).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId1.toString(), internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId2.toString(), internalCallContext).size(), 1);
 
         // Remove the first invoice
-        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice1.getInvoiceId().toString()), 1);
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice1.getInvoiceId().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId1.toString()).size(), 0);
-        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId2.toString()).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId1.toString(), internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountId2.toString(), internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoiceSqlDao.test();
+            invoiceSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
index 2c30a46..7f99aab 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
@@ -42,12 +42,12 @@ public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         final String name = UUID.randomUUID().toString().substring(0, 20);
 
         // Verify initial state
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId).size(), 0);
-        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name), 0);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId, internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId, name), 1);
-        final List<BusinessInvoiceTag> tagsForInvoice = invoiceTagSqlDao.getTagsForInvoice(invoiceId);
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId, name, internalCallContext), 1);
+        final List<BusinessInvoiceTag> tagsForInvoice = invoiceTagSqlDao.getTagsForInvoice(invoiceId, internalCallContext);
         Assert.assertEquals(tagsForInvoice.size(), 1);
 
         // Retrieve it
@@ -56,8 +56,8 @@ public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         Assert.assertEquals(invoiceTag.getName(), name);
 
         // Delete it
-        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name), 1);
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId).size(), 0);
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name, internalCallContext), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -68,24 +68,24 @@ public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbedded
         final String name2 = UUID.randomUUID().toString().substring(0, 20);
 
         // Add a tag to both invoices
-        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId1, name1), 1);
-        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId2, name2), 1);
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId1, name1, internalCallContext), 1);
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId2, name2, internalCallContext), 1);
 
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1).size(), 1);
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2).size(), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1, internalCallContext).size(), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2, internalCallContext).size(), 1);
 
         // Remove the tag for the first invoice
-        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId1, name1), 1);
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId1, name1, internalCallContext), 1);
 
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1).size(), 0);
-        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2).size(), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1, internalCallContext).size(), 0);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            invoiceTagSqlDao.test();
+            invoiceTagSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
index 5db58e3..9662857 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
@@ -45,30 +45,30 @@ public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbed
         final BusinessOverdueStatus firstOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
 
         // Verify initial state
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).size(), 0);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).size(), 0);
 
         // Add the overdue status
-        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(firstOverdueStatus), 1);
+        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(firstOverdueStatus, internalCallContext), 1);
 
         // Retrieve it
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).size(), 1);
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).get(0), firstOverdueStatus);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).size(), 1);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).get(0), firstOverdueStatus);
 
         // Add a second one
         final BusinessOverdueStatus secondOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
-        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(secondOverdueStatus), 1);
+        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(secondOverdueStatus, internalCallContext), 1);
 
         // Retrieve both
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).size(), 2);
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).get(0), firstOverdueStatus);
-        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey).get(1), secondOverdueStatus);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).size(), 2);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).get(0), firstOverdueStatus);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).get(1), secondOverdueStatus);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            overdueStatusSqlDao.test();
+            overdueStatusSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
index aac2fde..77d4870 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
@@ -45,12 +45,12 @@ public class TestBusinessSubscriptionTransitionFieldSqlDao extends AnalyticsTest
         final String value = UUID.randomUUID().toString();
 
         // Verify initial state
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId.toString(), name), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId.toString(), name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId.toString(), externalKey, name, value), 1);
-        final List<BusinessSubscriptionTransitionField> fieldsForBusinessSubscriptionTransition = subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId.toString(), externalKey, name, value, internalCallContext), 1);
+        final List<BusinessSubscriptionTransitionField> fieldsForBusinessSubscriptionTransition = subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
         Assert.assertEquals(fieldsForBusinessSubscriptionTransition.size(), 1);
 
         // Retrieve it
@@ -61,8 +61,8 @@ public class TestBusinessSubscriptionTransitionFieldSqlDao extends AnalyticsTest
         Assert.assertEquals(subscriptionTransitionField.getValue(), value);
 
         // Delete it
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId.toString(), name), 1);
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId.toString(), name, internalCallContext), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -76,24 +76,24 @@ public class TestBusinessSubscriptionTransitionFieldSqlDao extends AnalyticsTest
         final String name2 = UUID.randomUUID().toString().substring(0, 30);
 
         // Add a field to both transitions
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId1.toString(), externalKey1, name1, UUID.randomUUID().toString()), 1);
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId2.toString(), externalKey2, name2, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId1.toString(), externalKey1, name1, UUID.randomUUID().toString(), internalCallContext), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId2.toString(), externalKey2, name2, UUID.randomUUID().toString(), internalCallContext), 1);
 
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey1).size(), 1);
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey2).size(), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey1, internalCallContext).size(), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey2, internalCallContext).size(), 1);
 
         // Remove the field for the first transition
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId1.toString(), name1), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(bundleId1.toString(), name1, internalCallContext), 1);
 
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey1).size(), 0);
-        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey2).size(), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey1, internalCallContext).size(), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            subscriptionTransitionFieldSqlDao.test();
+            subscriptionTransitionFieldSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
index 60209fd..8b1f081 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
@@ -44,12 +44,12 @@ public class TestBusinessSubscriptionTransitionTagSqlDao extends AnalyticsTestSu
         final String name = UUID.randomUUID().toString().substring(0, 20);
 
         // Verify initial state
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name, internalCallContext), 0);
 
         // Add an entry
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId.toString(), externalKey, name), 1);
-        final List<BusinessSubscriptionTransitionTag> tagsForBusinessSubscriptionTransition = subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId.toString(), externalKey, name, internalCallContext), 1);
+        final List<BusinessSubscriptionTransitionTag> tagsForBusinessSubscriptionTransition = subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
         Assert.assertEquals(tagsForBusinessSubscriptionTransition.size(), 1);
 
         // Retrieve it
@@ -59,8 +59,8 @@ public class TestBusinessSubscriptionTransitionTagSqlDao extends AnalyticsTestSu
         Assert.assertEquals(subscriptionTransitionTag.getName(), name);
 
         // Delete it
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name), 1);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId.toString(), name, internalCallContext), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
@@ -74,24 +74,24 @@ public class TestBusinessSubscriptionTransitionTagSqlDao extends AnalyticsTestSu
         final String name2 = UUID.randomUUID().toString().substring(0, 20);
 
         // Add a tag to both transitions
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId1.toString(), externalKey1, name1), 1);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId2.toString(), externalKey2, name2), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId1.toString(), externalKey1, name1, internalCallContext), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId2.toString(), externalKey2, name2, internalCallContext), 1);
 
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey1).size(), 1);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey2).size(), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey1, internalCallContext).size(), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey2, internalCallContext).size(), 1);
 
         // Remove the tag for the first transition
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId1.toString(), name1), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(bundleId1.toString(), name1, internalCallContext), 1);
 
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey1).size(), 0);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey2).size(), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey1, internalCallContext).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey2, internalCallContext).size(), 1);
     }
 
     @Test(groups = "slow")
     public void testHealthCheck() throws Exception {
         // HealthCheck test to make sure MySQL is setup properly
         try {
-            subscriptionTransitionTagSqlDao.test();
+            subscriptionTransitionTagSqlDao.test(internalCallContext);
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
index 9401889..58d3148 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
@@ -25,33 +25,43 @@ import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.testng.Assert;
 
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionBinder;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.dao.TimeSeriesTuple;
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
+
+import com.google.common.collect.ImmutableList;
 
 public class MockBusinessSubscriptionTransitionSqlDao implements BusinessSubscriptionTransitionSqlDao {
+
     private final Map<String, List<BusinessSubscriptionTransition>> content = new HashMap<String, List<BusinessSubscriptionTransition>>();
     private final Map<String, String> keyForBundleId = new HashMap<String, String>();
 
     @Override
-    public List<TimeSeriesTuple> getSubscriptionsCreatedOverTime(@Bind("product_type") final String productType, @Bind("slug") final String slug) {
+    public List<TimeSeriesTuple> getSubscriptionsCreatedOverTime(@Bind("product_type") final String productType,
+                                                                 @Bind("slug") final String slug,
+                                                                 @InternalTenantContextBinder final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("event_key") final String key) {
+    public List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("event_key") final String key,
+                                                                    @InternalTenantContextBinder final InternalTenantContext context) {
         return content.get(key);
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId) {
+    public List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
+                                                                             @InternalTenantContextBinder final InternalTenantContext context) {
         return ImmutableList.<BusinessSubscriptionTransition>of();
     }
 
     @Override
-    public int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition) {
+    public int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition,
+                                @InternalTenantContextBinder final InternalCallContext context) {
         if (content.get(transition.getExternalKey()) == null) {
             content.put(transition.getExternalKey(), new ArrayList<BusinessSubscriptionTransition>());
         }
@@ -61,12 +71,13 @@ public class MockBusinessSubscriptionTransitionSqlDao implements BusinessSubscri
     }
 
     @Override
-    public void deleteTransitionsForBundle(@Bind("bundle_id") final String bundleId) {
+    public void deleteTransitionsForBundle(@Bind("bundle_id") final String bundleId,
+                                           @InternalTenantContextBinder final InternalCallContext context) {
         content.put(keyForBundleId.get(bundleId), new ArrayList<BusinessSubscriptionTransition>());
     }
 
     @Override
-    public void test() {
+    public void test(@InternalTenantContextBinder final InternalTenantContext context) {
     }
 
     @Override
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
index 39a5d6d..fce78b9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
@@ -36,7 +36,7 @@ import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.util.clock.Clock;
 
-public class TestBusinessInvoiceRecorder {
+public class TestBusinessInvoiceRecorder extends AnalyticsTestSuite {
 
     private final AccountUserApi accountApi = Mockito.mock(AccountUserApi.class);
     private final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
@@ -59,7 +59,7 @@ public class TestBusinessInvoiceRecorder {
         Mockito.when(invoiceItem.getStartDate()).thenReturn(new LocalDate(1985, 9, 10));
         Mockito.when(invoiceItem.getInvoiceItemType()).thenReturn(InvoiceItemType.CREDIT_ADJ);
 
-        final BusinessInvoiceItem bii = recorder.createBusinessInvoiceItem(invoiceItem);
+        final BusinessInvoiceItem bii = recorder.createBusinessInvoiceItem(invoiceItem, internalCallContext);
         Assert.assertNotNull(bii);
         Assert.assertEquals(bii.getAmount(), invoiceItem.getAmount());
         Assert.assertEquals(bii.getCurrency(), invoiceItem.getCurrency());
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
index 44ccbce..0d1afe8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
@@ -24,7 +24,6 @@ import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
@@ -36,9 +35,13 @@ import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.common.collect.ImmutableList;
+
 public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testCreateAddOn() throws Exception {
         final UUID bundleId = UUID.randomUUID();
@@ -59,13 +62,13 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         Mockito.when(bundle.getAccountId()).thenReturn(accountId);
         Mockito.when(bundle.getKey()).thenReturn(externalKey.toString());
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
-        Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any())).thenReturn(bundle);
+        Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(bundle);
 
         // Setup the account API
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getExternalKey()).thenReturn(externalKey.toString());
         final AccountUserApi accountApi = Mockito.mock(AccountUserApi.class);
-        Mockito.when(accountApi.getAccountById(bundle.getAccountId())).thenReturn(account);
+        Mockito.when(accountApi.getAccountById(Mockito.eq(bundle.getAccountId()), Mockito.<TenantContext>any())).thenReturn(account);
 
         // Create an new subscription event
         final EffectiveSubscriptionEvent eventEffective = Mockito.mock(EffectiveSubscriptionEvent.class);
@@ -80,13 +83,13 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         final Subscription subscription = Mockito.mock(Subscription.class);
         Mockito.when(subscription.getId()).thenReturn(subscriptionId);
         Mockito.when(subscription.getAllTransitions()).thenReturn(ImmutableList.<EffectiveSubscriptionEvent>of(eventEffective));
-        Mockito.when(entitlementApi.getSubscriptionsForBundle(Mockito.<UUID>any())).thenReturn(ImmutableList.<Subscription>of(subscription));
+        Mockito.when(entitlementApi.getSubscriptionsForBundle(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(ImmutableList.<Subscription>of(subscription));
 
         final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(sqlDao, catalogService, entitlementApi, accountApi, new DefaultClock());
-        recorder.rebuildTransitionsForBundle(bundle.getId());
+        recorder.rebuildTransitionsForBundle(bundle.getId(), internalCallContext);
 
-        Assert.assertEquals(sqlDao.getTransitionsByKey(externalKey.toString()).size(), 1);
-        final BusinessSubscriptionTransition transition = sqlDao.getTransitionsByKey(externalKey.toString()).get(0);
+        Assert.assertEquals(sqlDao.getTransitionsByKey(externalKey.toString(), internalCallContext).size(), 1);
+        final BusinessSubscriptionTransition transition = sqlDao.getTransitionsByKey(externalKey.toString(), internalCallContext).get(0);
         Assert.assertEquals(transition.getTotalOrdering(), (long) eventEffective.getTotalOrdering());
         Assert.assertEquals(transition.getAccountKey(), externalKey.toString());
         // Make sure all the prev_ columns are null
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
index f693718..c4d1c4d 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
@@ -52,10 +52,8 @@ import com.ning.billing.entitlement.engine.dao.AuditedEntitlementDao;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.mock.MockAccountBuilder;
 import com.ning.billing.util.bus.InMemoryBus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.DefaultClock;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
@@ -81,16 +79,17 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
         final AccountEmailDao accountEmailDao = new AuditedAccountEmailDao(dbi);
         final DefaultClock clock = new DefaultClock();
         callContextFactory = new DefaultCallContextFactory(clock);
-        accountUserApi = new DefaultAccountUserApi(callContextFactory, accountDao, accountEmailDao);
+        final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
+        accountUserApi = new DefaultAccountUserApi(callContextFactory, internalCallContextFactory, accountDao, accountEmailDao);
         final CatalogService catalogService = new DefaultCatalogService(Mockito.mock(CatalogConfig.class), Mockito.mock(VersionedCatalogLoader.class));
         final AddonUtils addonUtils = new AddonUtils(catalogService);
-        final DefaultNotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
+        final DefaultNotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock, internalCallContextFactory);
         final EntitlementDao entitlementDao = new AuditedEntitlementDao(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService);
         final PlanAligner planAligner = new PlanAligner(catalogService);
-        final DefaultSubscriptionApiService apiService = new DefaultSubscriptionApiService(clock, entitlementDao, catalogService, planAligner);
+        final DefaultSubscriptionApiService apiService = new DefaultSubscriptionApiService(clock, entitlementDao, catalogService, planAligner, internalCallContextFactory);
         final DefaultSubscriptionFactory subscriptionFactory = new DefaultSubscriptionFactory(apiService, clock, catalogService);
         entitlementUserApi = new DefaultEntitlementUserApi(clock, entitlementDao, catalogService,
-                                                           apiService, subscriptionFactory, addonUtils);
+                                                           apiService, subscriptionFactory, addonUtils, internalCallContextFactory);
         tagRecorder = new BusinessTagRecorder(accountTagSqlDao, invoicePaymentTagSqlDao, invoiceTagSqlDao, subscriptionTransitionTagSqlDao,
                                               accountUserApi, entitlementUserApi);
 
@@ -105,7 +104,6 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testAddAndRemoveTagsForAccount() throws Exception {
         final String name = UUID.randomUUID().toString().substring(0, 20);
-        final CallContext callContext = callContextFactory.createCallContext(UUID.randomUUID().toString(), CallOrigin.TEST, UserType.TEST);
         final String accountKey = UUID.randomUUID().toString();
 
         final Account accountData = new MockAccountBuilder()
@@ -115,17 +113,16 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
         final Account account = accountUserApi.createAccount(accountData, callContext);
         final UUID accountId = account.getId();
 
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey).size(), 0);
-        tagRecorder.tagAdded(ObjectType.ACCOUNT, accountId, name);
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey).size(), 1);
-        tagRecorder.tagRemoved(ObjectType.ACCOUNT, accountId, name);
-        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext).size(), 0);
+        tagRecorder.tagAdded(ObjectType.ACCOUNT, accountId, name, internalCallContext);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext).size(), 1);
+        tagRecorder.tagRemoved(ObjectType.ACCOUNT, accountId, name, internalCallContext);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext).size(), 0);
     }
 
     @Test(groups = "slow")
     public void testAddAndRemoveTagsForBundle() throws Exception {
         final String name = UUID.randomUUID().toString().substring(0, 20);
-        final CallContext callContext = callContextFactory.createCallContext(UUID.randomUUID().toString(), CallOrigin.TEST, UserType.TEST);
         final String externalKey = UUID.randomUUID().toString();
 
         final Account accountData = new MockAccountBuilder()
@@ -135,10 +132,10 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
         final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), externalKey, callContext);
         final UUID bundleId = bundle.getId();
 
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
-        tagRecorder.tagAdded(ObjectType.BUNDLE, bundleId, name);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey).size(), 1);
-        tagRecorder.tagRemoved(ObjectType.BUNDLE, bundleId, name);
-        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
+        tagRecorder.tagAdded(ObjectType.BUNDLE, bundleId, name, internalCallContext);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 1);
+        tagRecorder.tagRemoved(ObjectType.BUNDLE, bundleId, name, internalCallContext);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext).size(), 0);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
index 7a3868d..e0914a5 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
@@ -20,8 +20,10 @@ import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface AccountUserApi {
+
     public Account createAccount(AccountData data, CallContext context) throws AccountApiException;
 
     public Account migrateAccount(MigrationAccountData data, CallContext context) throws AccountApiException;
@@ -39,19 +41,19 @@ public interface AccountUserApi {
 
     public void updateAccount(UUID accountId, AccountData accountData, CallContext context) throws AccountApiException;
 
-    public void removePaymentMethod(final UUID accountId, final CallContext context) throws AccountApiException;
+    public void removePaymentMethod(UUID accountId, CallContext context) throws AccountApiException;
 
     public void updatePaymentMethod(UUID accountId, UUID paymentMethodId, CallContext context) throws AccountApiException;
 
-    public Account getAccountByKey(String key) throws AccountApiException;
+    public Account getAccountByKey(String key, TenantContext context) throws AccountApiException;
 
-    public Account getAccountById(UUID accountId) throws AccountApiException;
+    public Account getAccountById(UUID accountId, TenantContext context) throws AccountApiException;
 
-    public List<Account> getAccounts();
+    public List<Account> getAccounts(TenantContext context);
 
-    public UUID getIdFromKey(String externalKey) throws AccountApiException;
+    public UUID getIdFromKey(String externalKey, TenantContext context) throws AccountApiException;
 
-    public List<AccountEmail> getEmails(UUID accountId);
+    public List<AccountEmail> getEmails(UUID accountId, TenantContext context);
 
     public void saveEmails(UUID accountId, List<AccountEmail> emails, CallContext context);
 
diff --git a/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java b/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
index dc79d9a..cbdea9b 100644
--- a/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
+++ b/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
@@ -17,18 +17,19 @@
 package com.ning.billing.analytics.api.user;
 
 import com.ning.billing.analytics.api.TimeSeriesData;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface AnalyticsUserApi {
 
     /**
      * @return the number of accounts created per day
      */
-    public TimeSeriesData getAccountsCreatedOverTime();
+    public TimeSeriesData getAccountsCreatedOverTime(TenantContext context);
 
     /**
      * @param productType catalog name
      * @param slug        plan phase name, as returned by PlanPhase#getName()
      * @return the number of new subscriptions created per day (transfers not included)
      */
-    public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug);
+    public TimeSeriesData getSubscriptionsCreatedOverTime(String productType, String slug, TenantContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/CatalogUserApi.java b/api/src/main/java/com/ning/billing/catalog/api/CatalogUserApi.java
index 21bd254..e7c9cb9 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/CatalogUserApi.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/CatalogUserApi.java
@@ -16,7 +16,9 @@
 
 package com.ning.billing.catalog.api;
 
+import com.ning.billing.util.callcontext.TenantContext;
+
 public interface CatalogUserApi {
 
-    Catalog getCatalog(String catalogName);
+    Catalog getCatalog(String catalogName, TenantContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java b/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
index f4902e7..2f6ebff 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
@@ -21,6 +21,7 @@ import java.util.UUID;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface ChargeThruApi {
 
@@ -28,7 +29,7 @@ public interface ChargeThruApi {
      * @param subscriptionId
      * @return UUID of
      */
-    public UUID getAccountIdFromSubscriptionId(UUID subscriptionId) throws EntitlementBillingApiException;
+    public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, TenantContext context) throws EntitlementBillingApiException;
 
     /**
      * Sets the charged through date for the subscription with that Id.
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
index 18296be..1079e2a 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
@@ -13,24 +13,26 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.entitlement.api.timeline;
 
 import java.util.UUID;
 
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface EntitlementTimelineApi {
 
-    public BundleTimeline getBundleTimeline(final SubscriptionBundle bundle)
-    throws EntitlementRepairException;
+    public BundleTimeline getBundleTimeline(SubscriptionBundle bundle, TenantContext context)
+            throws EntitlementRepairException;
 
-    public BundleTimeline getBundleTimeline(final UUID accountId, final String bundleName)
-    throws EntitlementRepairException;
+    public BundleTimeline getBundleTimeline(UUID accountId, String bundleName, TenantContext context)
+            throws EntitlementRepairException;
 
-    public BundleTimeline getBundleTimeline(final UUID bundleId)
-    throws EntitlementRepairException;
+    public BundleTimeline getBundleTimeline(UUID bundleId, TenantContext context)
+            throws EntitlementRepairException;
 
-    public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context)
-    throws EntitlementRepairException;
+    public BundleTimeline repairBundle(BundleTimeline input, boolean dryRun, CallContext context)
+            throws EntitlementRepairException;
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/transfer/EntitlementTransferApi.java b/api/src/main/java/com/ning/billing/entitlement/api/transfer/EntitlementTransferApi.java
index 06c08ae..71e325f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/transfer/EntitlementTransferApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/transfer/EntitlementTransferApi.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.entitlement.api.transfer;
 
 import java.util.UUID;
@@ -25,7 +26,6 @@ import com.ning.billing.util.callcontext.CallContext;
 public interface EntitlementTransferApi {
 
     public SubscriptionBundle transferBundle(final UUID sourceAccountId, final UUID destAccountId, final String bundleKey, final DateTime requestedDate,
-            final boolean transferAddOn, final boolean cancelImmediately, final CallContext context)
-        throws EntitlementTransferApiException;
-
+                                             final boolean transferAddOn, final boolean cancelImmediately, final CallContext context)
+            throws EntitlementTransferApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index 2a78f6c..3da109b 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -25,34 +25,35 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.util.callcontext.CallContext;
-
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface EntitlementUserApi {
 
-    public SubscriptionBundle getBundleFromId(final UUID id) throws EntitlementUserApiException;
+    public SubscriptionBundle getBundleFromId(UUID id, TenantContext context) throws EntitlementUserApiException;
 
-    public Subscription getSubscriptionFromId(final UUID id) throws EntitlementUserApiException;
+    public Subscription getSubscriptionFromId(UUID id, TenantContext context) throws EntitlementUserApiException;
 
-    public List<SubscriptionBundle> getBundlesForKey(final String bundleKey) throws EntitlementUserApiException;
+    public List<SubscriptionBundle> getBundlesForKey(String bundleKey, TenantContext context) throws EntitlementUserApiException;
 
-    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey) throws EntitlementUserApiException;
+    public SubscriptionBundle getBundleForAccountAndKey(UUID accountId, String bundleKey, TenantContext context) throws EntitlementUserApiException;
 
-    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId);
+    public List<SubscriptionBundle> getBundlesForAccount(UUID accountId, TenantContext context);
 
-    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId);
+    public List<Subscription> getSubscriptionsForBundle(UUID bundleId, TenantContext context);
 
-    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey);
+    public List<Subscription> getSubscriptionsForAccountAndKey(UUID accountId, String bundleKey, TenantContext context);
 
-    public Subscription getBaseSubscription(final UUID bundleId) throws EntitlementUserApiException;
+    public Subscription getBaseSubscription(UUID bundleId, TenantContext context) throws EntitlementUserApiException;
 
-    public SubscriptionBundle createBundleForAccount(final UUID accountId, final String bundleKey, final CallContext context)
+    public SubscriptionBundle createBundleForAccount(UUID accountId, String bundleKey, CallContext context)
             throws EntitlementUserApiException;
 
-    public Subscription createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
+    public Subscription createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
             throws EntitlementUserApiException;
 
-    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String productName, final DateTime requestedDate)
+    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, @Nullable String productName,
+                                                                    DateTime requestedDate, TenantContext context)
             throws EntitlementUserApiException;
 
-    public DateTime getNextBillingDate(final UUID account);
+    public DateTime getNextBillingDate(UUID account, TenantContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 12982f5..ebf5ac7 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -272,8 +272,19 @@ public enum ErrorCode {
     EMAIL_SENDING_FAILED(9000, "Sending email failed"),
     EMAIL_PROPERTIES_FILE_MISSING(9001, "The properties file for email configuration could not be found."),
     MISSING_TRANSLATION_RESOURCE(9010, "The resources for %s translation could not be found."),
-    MISSING_DEFAULT_TRANSLATION_RESOURCE(9011, "The default resource for %s translation could not be found.");
+    MISSING_DEFAULT_TRANSLATION_RESOURCE(9011, "The default resource for %s translation could not be found."),
 
+    /*
+    *
+    * Range 10000: TENANT
+    *
+    */
+    TENANT_ALREADY_EXISTS(10000, "Tenant already exists for key %s"),
+    TENANT_DOES_NOT_EXIST_FOR_ID(10001, "Tenant does not exist for id %s"),
+    TENANT_DOES_NOT_EXIST_FOR_KEY(10002, "Tenant does not exist for key %s"),
+    TENANT_DOES_NOT_EXIST_FOR_API_KEY(10003, "Tenant does not exist for api key %s"),
+    TENANT_CREATION_FAILED(10004, "Tenant creation failed."),
+    TENANT_UPDATE_FAILED(10005, "Tenant update failed.");
 
     private final int code;
     private final String format;
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
index 4c9e4c3..11c82da 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
@@ -22,16 +22,21 @@ import java.util.UUID;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.callcontext.CallContext;
 
 public interface InvoiceMigrationApi {
+
     /**
      * @param accountId  account id
      * @param targetDate maximum billing event day to consider (in the account timezone)
      * @param balance    invoice balance
      * @param currency   invoice currency
+     * @param context    call context
      * @return The UUID of the created invoice
      */
-    public UUID createMigrationInvoice(UUID accountId, LocalDate targetDate,
-                                       BigDecimal balance, Currency currency);
-
+    public UUID createMigrationInvoice(UUID accountId,
+                                       LocalDate targetDate,
+                                       BigDecimal balance,
+                                       Currency currency,
+                                       CallContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
index d335a71..8275ee0 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
@@ -17,7 +17,9 @@
 package com.ning.billing.invoice.api;
 
 import com.ning.billing.account.api.Account;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface InvoiceNotifier {
-    public void notify(Account account, Invoice invoice) throws InvoiceApiException;
+
+    public void notify(Account account, Invoice invoice, TenantContext tenantContext) throws InvoiceApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index b65cf34..e000af6 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -25,6 +25,7 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface InvoicePaymentApi {
 
@@ -32,24 +33,23 @@ public interface InvoicePaymentApi {
      * @param accountId id of the account
      * @return All invoices, including migrated invoices
      */
-    public List<Invoice> getAllInvoicesByAccount(UUID accountId);
+    public List<Invoice> getAllInvoicesByAccount(UUID accountId, TenantContext context);
 
-    public Invoice getInvoice(UUID invoiceId) throws InvoiceApiException;
+    public Invoice getInvoice(UUID invoiceId, TenantContext context) throws InvoiceApiException;
 
-    public Invoice getInvoiceForPaymentId(UUID paymentId) throws InvoiceApiException;
+    public Invoice getInvoiceForPaymentId(UUID paymentId, TenantContext context) throws InvoiceApiException;
 
-    public List<InvoicePayment> getInvoicePayments(UUID paymentId);
+    public List<InvoicePayment> getInvoicePayments(UUID paymentId, TenantContext context);
 
-    public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId);
+    public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId, TenantContext context);
 
-    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context);
+    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context) throws InvoiceApiException;
 
-    public void notifyOfPayment(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentId, DateTime paymentDate, CallContext context);
+    public void notifyOfPayment(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentId, DateTime paymentDate, CallContext context) throws InvoiceApiException;
 
     /**
      * Create a refund.
      *
-     *
      * @param paymentId                 payment associated with that refund
      * @param amount                    amount to refund
      * @param isInvoiceAdjusted         whether the refund should trigger an invoice or invoice item adjustment
@@ -66,13 +66,13 @@ public interface InvoicePaymentApi {
 
     public InvoicePayment createChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
 
-    public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId);
+    public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId, TenantContext context);
 
-    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId);
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId, TenantContext context);
 
-    public UUID getAccountIdFromInvoicePaymentId(UUID uuid) throws InvoiceApiException;
+    public UUID getAccountIdFromInvoicePaymentId(UUID uuid, TenantContext context) throws InvoiceApiException;
 
-    public List<InvoicePayment> getChargebacksByPaymentId(UUID paymentId);
+    public List<InvoicePayment> getChargebacksByPaymentId(UUID paymentId, TenantContext context);
 
-    public InvoicePayment getChargebackById(UUID chargebackId) throws InvoiceApiException;
+    public InvoicePayment getChargebackById(UUID chargebackId, TenantContext context) throws InvoiceApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 1d63e9d..3db2693 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -28,6 +28,7 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface InvoiceUserApi {
 
@@ -35,50 +36,56 @@ public interface InvoiceUserApi {
      * Get all invoices for a given account.
      *
      * @param accountId account id
+     * @param context   the tenant context
      * @return all invoices
      */
-    public List<Invoice> getInvoicesByAccount(UUID accountId);
+    public List<Invoice> getInvoicesByAccount(UUID accountId, TenantContext context);
 
     /**
      * Find invoices from a given day, for a given account.
      *
      * @param accountId account id
      * @param fromDate  the earliest target day to consider, in the account timezone
+     * @param context   the tenant context
      * @return a list of invoices
      */
-    public List<Invoice> getInvoicesByAccount(UUID accountId, LocalDate fromDate);
+    public List<Invoice> getInvoicesByAccount(UUID accountId, LocalDate fromDate, TenantContext context);
 
     /**
      * Retrieve the account balance.
      *
      * @param accountId account id
+     * @param context   the tenant context
      * @return the account balance
      */
-    public BigDecimal getAccountBalance(UUID accountId);
+    public BigDecimal getAccountBalance(UUID accountId, TenantContext context);
 
     /**
      * Retrieve the account CBA.
      *
      * @param accountId account id
+     * @param context   the tenant context
      * @return the account CBA
      */
-    public BigDecimal getAccountCBA(UUID accountId);
+    public BigDecimal getAccountCBA(UUID accountId, TenantContext context);
 
     /**
      * Retrieve an invoice by id.
      *
      * @param invoiceId invoice id
+     * @param context   the tenant context
      * @return the invoice
      */
-    public Invoice getInvoice(UUID invoiceId) throws InvoiceApiException;
+    public Invoice getInvoice(UUID invoiceId, TenantContext context) throws InvoiceApiException;
 
     /**
      * Retrieve an invoice by invoice number.
      *
-     * @param number invoice number
+     * @param number  invoice number
+     * @param context the tenant context
      * @return the invoice
      */
-    public Invoice getInvoiceByNumber(Integer number) throws InvoiceApiException;
+    public Invoice getInvoiceByNumber(Integer number, TenantContext context) throws InvoiceApiException;
 
     /**
      * Record a payment for an invoice.
@@ -86,16 +93,17 @@ public interface InvoiceUserApi {
      * @param invoicePayment invoice payment
      * @param context        call context
      */
-    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context);
+    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context) throws InvoiceApiException;
 
     /**
      * Find unpaid invoices for a given account, up to a given day.
      *
      * @param accountId account id
      * @param upToDate  the latest target day to consider, in the account timezone
+     * @param context   the tenant context
      * @return a collection of invoices
      */
-    public Collection<Invoice> getUnpaidInvoicesByAccountId(UUID accountId, LocalDate upToDate);
+    public Collection<Invoice> getUnpaidInvoicesByAccountId(UUID accountId, LocalDate upToDate, TenantContext context);
 
     /**
      * Trigger an invoice for a given account and a given day.
@@ -116,7 +124,7 @@ public interface InvoiceUserApi {
      * @param context   call context
      * @throws TagApiException
      */
-    public void tagInvoiceAsWrittenOff(UUID invoiceId, CallContext context) throws TagApiException;
+    public void tagInvoiceAsWrittenOff(UUID invoiceId, CallContext context) throws TagApiException, InvoiceApiException;
 
     /**
      * Unmark an invoice as written off.
@@ -125,16 +133,17 @@ public interface InvoiceUserApi {
      * @param context   call context
      * @throws TagApiException
      */
-    public void tagInvoiceAsNotWrittenOff(UUID invoiceId, CallContext context) throws TagApiException;
+    public void tagInvoiceAsNotWrittenOff(UUID invoiceId, CallContext context) throws TagApiException, InvoiceApiException;
 
     /**
      * Retrieve an external charge by id.
      *
      * @param externalChargeId external charge id
+     * @param context          the tenant context
      * @return the external charge
      * @throws InvoiceApiException
      */
-    public InvoiceItem getExternalChargeById(UUID externalChargeId) throws InvoiceApiException;
+    public InvoiceItem getExternalChargeById(UUID externalChargeId, TenantContext context) throws InvoiceApiException;
 
     /**
      * Add an external charge to an account.
@@ -204,10 +213,11 @@ public interface InvoiceUserApi {
      * Retrieve a credit by id.
      *
      * @param creditId credit id
+     * @param context  the tenant context
      * @return the credit
      * @throws InvoiceApiException
      */
-    public InvoiceItem getCreditById(UUID creditId) throws InvoiceApiException;
+    public InvoiceItem getCreditById(UUID creditId, TenantContext context) throws InvoiceApiException;
 
     /**
      * Add a credit to an account.
@@ -282,10 +292,11 @@ public interface InvoiceUserApi {
      * Retrieve the invoice formatted in HTML.
      *
      * @param invoiceId invoice id
+     * @param context   the tenant context
      * @return the invoice in HTML format
      * @throws AccountApiException
      * @throws IOException
      * @throws InvoiceApiException
      */
-    public String getInvoiceAsHTML(UUID invoiceId) throws AccountApiException, IOException, InvoiceApiException;
+    public String getInvoiceAsHTML(UUID invoiceId, TenantContext context) throws AccountApiException, IOException, InvoiceApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BillingApi.java b/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
index 6a2c665..dcd23ac 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
@@ -19,11 +19,12 @@ package com.ning.billing.junction.api;
 import java.util.UUID;
 
 import com.ning.billing.entitlement.api.billing.ChargeThruApi;
+import com.ning.billing.util.callcontext.CallContext;
 
 public interface BillingApi extends ChargeThruApi {
+
     /**
-     * @param accountId
      * @return an ordered list of billing event for the given accounts
      */
-    public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(UUID accountId);
+    public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(UUID accountId, CallContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java b/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
index ee1fe5b..adb92bd 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
@@ -17,21 +17,23 @@
 package com.ning.billing.junction.api;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface BlockingApi {
+
     public static final String CLEAR_STATE_NAME = "__KILLBILL__CLEAR__OVERDUE_STATE__";
 
-    public BlockingState getBlockingStateFor(Blockable overdueable);
+    public BlockingState getBlockingStateFor(Blockable overdueable, TenantContext context);
 
-    public BlockingState getBlockingStateFor(UUID overdueableId);
+    public BlockingState getBlockingStateFor(UUID overdueableId, TenantContext context);
 
-    public List<BlockingState> getBlockingHistory(Blockable overdueable);
+    public List<BlockingState> getBlockingHistory(Blockable overdueable, TenantContext context);
 
-    public List<BlockingState> getBlockingHistory(UUID overdueableId);
+    public List<BlockingState> getBlockingHistory(UUID overdueableId, TenantContext context);
 
-    public <T extends Blockable> void setBlockingState(BlockingState state);
+    public <T extends Blockable> void setBlockingState(BlockingState state, CallContext context);
 
 }
diff --git a/api/src/main/java/com/ning/billing/overdue/Condition.java b/api/src/main/java/com/ning/billing/overdue/Condition.java
index f5fe347..0a76429 100644
--- a/api/src/main/java/com/ning/billing/overdue/Condition.java
+++ b/api/src/main/java/com/ning/billing/overdue/Condition.java
@@ -16,9 +16,7 @@
 
 package com.ning.billing.overdue;
 
-
 import org.joda.time.LocalDate;
-import org.joda.time.Period;
 
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.config.api.BillingState;
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
index 56a63f9..4634a91 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
@@ -19,7 +19,6 @@ package com.ning.billing.overdue.config.api;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
index d06bd7e..4fc6a67 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
@@ -19,15 +19,17 @@ package com.ning.billing.overdue;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface OverdueUserApi {
 
-    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueException, OverdueApiException;
+    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(T overdueable, CallContext context) throws OverdueException, OverdueApiException;
 
-    public <T extends Blockable> void setOverrideBillingStateForAccount(T overdueable, BillingState<T> state) throws OverdueException;
+    public <T extends Blockable> void setOverrideBillingStateForAccount(T overdueable, BillingState<T> state, CallContext context) throws OverdueException;
 
-    public <T extends Blockable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueException;
+    public <T extends Blockable> OverdueState<T> getOverdueStateFor(T overdueable, TenantContext context) throws OverdueException;
 
-    public <T extends Blockable> BillingState<T> getBillingStateFor(T overdueable) throws OverdueException;
+    public <T extends Blockable> BillingState<T> getBillingStateFor(T overdueable, TenantContext context) throws OverdueException;
 
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index 16c4c5f..43116ac 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -24,16 +24,17 @@ import java.util.UUID;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface PaymentApi {
 
-    public Payment createPayment(final Account account, final UUID invoiceId, final BigDecimal amount, final CallContext context)
+    public Payment createPayment(Account account, UUID invoiceId, BigDecimal amount, CallContext context)
             throws PaymentApiException;
 
-    public Payment createExternalPayment(final Account account, final UUID invoiceId, final BigDecimal amount, final CallContext context)
+    public Payment createExternalPayment(Account account, UUID invoiceId, BigDecimal amount, CallContext context)
             throws PaymentApiException;
 
-    public Refund getRefund(final UUID refundId)
+    public Refund getRefund(UUID refundId, TenantContext context)
             throws PaymentApiException;
 
     /**
@@ -46,7 +47,7 @@ public interface PaymentApi {
      * @return the created Refund
      * @throws PaymentApiException
      */
-    public Refund createRefund(final Account account, final UUID paymentId, final BigDecimal refundAmount, final CallContext context)
+    public Refund createRefund(Account account, UUID paymentId, BigDecimal refundAmount, CallContext context)
             throws PaymentApiException;
 
     /**
@@ -59,7 +60,7 @@ public interface PaymentApi {
      * @return the created Refund
      * @throws PaymentApiException
      */
-    public Refund createRefundWithAdjustment(final Account account, final UUID paymentId, final BigDecimal refundAmount, final CallContext context)
+    public Refund createRefundWithAdjustment(Account account, UUID paymentId, BigDecimal refundAmount, CallContext context)
             throws PaymentApiException;
 
     /**
@@ -73,7 +74,7 @@ public interface PaymentApi {
      * @return the created Refund
      * @throws PaymentApiException
      */
-    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Set<UUID> invoiceItemIds, final CallContext context)
+    public Refund createRefundWithItemsAdjustments(Account account, UUID paymentId, Set<UUID> invoiceItemIds, CallContext context)
             throws PaymentApiException;
 
     /**
@@ -87,22 +88,22 @@ public interface PaymentApi {
      * @return the created Refund
      * @throws PaymentApiException
      */
-    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final CallContext context)
+    public Refund createRefundWithItemsAdjustments(Account account, UUID paymentId, Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, CallContext context)
             throws PaymentApiException;
 
-    public List<Refund> getAccountRefunds(final Account account)
+    public List<Refund> getAccountRefunds(Account account, TenantContext context)
             throws PaymentApiException;
 
-    public List<Refund> getPaymentRefunds(final UUID paymentId)
+    public List<Refund> getPaymentRefunds(UUID paymentId, TenantContext context)
             throws PaymentApiException;
 
-    public List<Payment> getInvoicePayments(final UUID invoiceId)
+    public List<Payment> getInvoicePayments(UUID invoiceId, TenantContext context)
             throws PaymentApiException;
 
-    public List<Payment> getAccountPayments(final UUID accountId)
+    public List<Payment> getAccountPayments(UUID accountId, TenantContext context)
             throws PaymentApiException;
 
-    public Payment getPayment(final UUID paymentId)
+    public Payment getPayment(UUID paymentId, TenantContext context)
             throws PaymentApiException;
 
     /*
@@ -110,31 +111,31 @@ public interface PaymentApi {
      */
     public Set<String> getAvailablePlugins();
 
-    public String initializeAccountPlugin(final String pluginName, final Account account)
+    public String initializeAccountPlugin(String pluginName, Account account, CallContext context)
             throws PaymentApiException;
 
-    public UUID addPaymentMethod(final String pluginName, final Account account, boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
+    public UUID addPaymentMethod(String pluginName, Account account, boolean setDefault, PaymentMethodPlugin paymentMethodInfo, CallContext context)
             throws PaymentApiException;
 
-    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
+    public List<PaymentMethod> refreshPaymentMethods(String pluginName, Account account, CallContext context)
             throws PaymentApiException;
 
-    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail)
+    public List<PaymentMethod> getPaymentMethods(Account account, boolean withPluginDetail, TenantContext context)
             throws PaymentApiException;
 
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
+    public PaymentMethod getPaymentMethodById(UUID paymentMethodId, TenantContext context)
             throws PaymentApiException;
 
-    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail)
+    public PaymentMethod getPaymentMethod(Account account, UUID paymentMethodId, boolean withPluginDetail, TenantContext context)
             throws PaymentApiException;
 
-    public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMetghodInfo)
+    public void updatePaymentMethod(Account account, UUID paymentMethodId, PaymentMethodPlugin paymentMethodInfo, CallContext context)
             throws PaymentApiException;
 
-    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff, final CallContext context)
+    public void deletedPaymentMethod(Account account, UUID paymentMethodId, boolean deleteDefaultPaymentMethodWithAutoPayOff, CallContext context)
             throws PaymentApiException;
 
-    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+    public void setDefaultPaymentMethod(Account account, UUID paymentMethodId, CallContext context)
             throws PaymentApiException;
 
 }
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
index dd54118..c6e200f 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
@@ -22,41 +22,43 @@ import java.util.UUID;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public interface PaymentPluginApi {
 
     public String getName();
 
-    public PaymentInfoPlugin processPayment(String externalAccountKey, UUID paymentId, BigDecimal amount)
+    public PaymentInfoPlugin processPayment(String externalAccountKey, UUID paymentId, BigDecimal amount, CallContext context)
             throws PaymentPluginApiException;
 
-    public PaymentInfoPlugin getPaymentInfo(UUID paymentId)
+    public PaymentInfoPlugin getPaymentInfo(UUID paymentId, TenantContext context)
             throws PaymentPluginApiException;
 
-    public void processRefund(final Account account, final UUID paymentId, BigDecimal refundAmount)
+    public void processRefund(final Account account, final UUID paymentId, BigDecimal refundAmount, CallContext context)
             throws PaymentPluginApiException;
 
-    public int getNbRefundForPaymentAmount(final Account account, final UUID paymentId, final BigDecimal refundAmount)
+    public int getNbRefundForPaymentAmount(final Account account, final UUID paymentId, final BigDecimal refundAmount, TenantContext context)
             throws PaymentPluginApiException;
 
-    public String createPaymentProviderAccount(Account account)
+    public String createPaymentProviderAccount(Account account, CallContext context)
             throws PaymentPluginApiException;
 
-    public List<PaymentMethodPlugin> getPaymentMethodDetails(String accountKey)
+    public List<PaymentMethodPlugin> getPaymentMethodDetails(String accountKey, TenantContext context)
             throws PaymentPluginApiException;
 
-    public PaymentMethodPlugin getPaymentMethodDetail(String accountKey, String externalPaymentMethodId)
+    public PaymentMethodPlugin getPaymentMethodDetail(String accountKey, String externalPaymentMethodId, TenantContext context)
             throws PaymentPluginApiException;
 
-    public String addPaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps, boolean setDefault)
+    public String addPaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps, boolean setDefault, CallContext context)
             throws PaymentPluginApiException;
 
-    public void updatePaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps)
+    public void updatePaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps, CallContext context)
             throws PaymentPluginApiException;
 
-    public void deletePaymentMethod(String accountKey, String externalPaymentMethodId)
+    public void deletePaymentMethod(String accountKey, String externalPaymentMethodId, CallContext context)
             throws PaymentPluginApiException;
 
-    public void setDefaultPaymentMethod(String accountKey, String externalPaymentId)
+    public void setDefaultPaymentMethod(String accountKey, String externalPaymentId, CallContext context)
             throws PaymentPluginApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/tenant/api/Tenant.java b/api/src/main/java/com/ning/billing/tenant/api/Tenant.java
new file mode 100644
index 0000000..b389a3e
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/tenant/api/Tenant.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+import com.ning.billing.util.entity.Entity;
+
+public interface Tenant extends TenantData, Entity {
+
+}
diff --git a/api/src/main/java/com/ning/billing/tenant/api/TenantApiException.java b/api/src/main/java/com/ning/billing/tenant/api/TenantApiException.java
new file mode 100644
index 0000000..3a96ab7
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/tenant/api/TenantApiException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+import com.ning.billing.BillingExceptionBase;
+import com.ning.billing.ErrorCode;
+
+public class TenantApiException extends BillingExceptionBase {
+
+    private static final long serialVersionUID = 1L;
+
+    public TenantApiException(final Throwable cause, final int code, final String msg) {
+        super(cause, code, msg);
+    }
+
+    public TenantApiException(final Throwable cause, final ErrorCode code, final Object... args) {
+        super(cause, code, args);
+    }
+
+    public TenantApiException(final ErrorCode code, final Object... args) {
+        super(code, args);
+    }
+}
diff --git a/api/src/main/java/com/ning/billing/tenant/api/TenantData.java b/api/src/main/java/com/ning/billing/tenant/api/TenantData.java
new file mode 100644
index 0000000..ce98eeb
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/tenant/api/TenantData.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+public interface TenantData {
+
+    public String getExternalKey();
+
+    public String getApiKey();
+
+    /**
+     * Note that we don't expose in the API how the
+     * secret is stored (with or without salt, hashing algorithm)
+     * so we can change it later
+     *
+     * @return the decrypted api secret
+     */
+    public String getApiSecret();
+}
diff --git a/api/src/main/java/com/ning/billing/tenant/api/TenantService.java b/api/src/main/java/com/ning/billing/tenant/api/TenantService.java
new file mode 100644
index 0000000..91bd610
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/tenant/api/TenantService.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+import com.ning.billing.lifecycle.KillbillService;
+
+public interface TenantService extends KillbillService {
+
+}
diff --git a/api/src/main/java/com/ning/billing/tenant/api/TenantUserApi.java b/api/src/main/java/com/ning/billing/tenant/api/TenantUserApi.java
new file mode 100644
index 0000000..cf49c1a
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/tenant/api/TenantUserApi.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+import java.util.UUID;
+
+import com.ning.billing.util.callcontext.CallContext;
+
+public interface TenantUserApi {
+
+    public Tenant createTenant(TenantData data, CallContext context) throws TenantApiException;
+
+    public Tenant getTenantByApiKey(String key) throws TenantApiException;
+
+    public Tenant getTenantById(UUID tenantId) throws TenantApiException;
+}
diff --git a/api/src/main/java/com/ning/billing/usage/api/UsageUserApi.java b/api/src/main/java/com/ning/billing/usage/api/UsageUserApi.java
index eb6935c..8735313 100644
--- a/api/src/main/java/com/ning/billing/usage/api/UsageUserApi.java
+++ b/api/src/main/java/com/ning/billing/usage/api/UsageUserApi.java
@@ -20,6 +20,9 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.util.callcontext.CallContext;
+
 public interface UsageUserApi {
 
     /**
@@ -27,8 +30,9 @@ public interface UsageUserApi {
      *
      * @param bundleId   bundle id source
      * @param metricName metric name for this usage
+     * @param context    call context
      */
-    public void incrementUsage(final UUID bundleId, final String metricName);
+    public void incrementUsage(UUID bundleId, String metricName, CallContext context) throws EntitlementUserApiException;
 
     /**
      * Fine grained usage API if the external system doesn't roll its usage data. This is used to record e.g. "X has used
@@ -38,8 +42,9 @@ public interface UsageUserApi {
      * @param metricName metric name for this usage
      * @param timestamp  timestamp of this usage
      * @param value      value to record
+     * @param context    tenant context
      */
-    public void recordUsage(final UUID bundleId, final String metricName, final DateTime timestamp, final long value);
+    public void recordUsage(UUID bundleId, String metricName, DateTime timestamp, long value, CallContext context) throws EntitlementUserApiException;
 
     /**
      * Bulk usage API if the external system rolls-up usage data. This is used to record e.g. "X has used 12 minutes
@@ -50,6 +55,7 @@ public interface UsageUserApi {
      * @param startDate  start date of the usage period
      * @param endDate    end date of the usage period
      * @param value      value to record
+     * @param context    tenant context
      */
-    public void recordRolledUpUsage(final UUID bundleId, final String metricName, final DateTime startDate, final DateTime endDate, final long value);
+    public void recordRolledUpUsage(UUID bundleId, String metricName, DateTime startDate, DateTime endDate, long value, CallContext context) throws EntitlementUserApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/util/api/AuditUserApi.java b/api/src/main/java/com/ning/billing/util/api/AuditUserApi.java
index 6bf4220..498507c 100644
--- a/api/src/main/java/com/ning/billing/util/api/AuditUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/AuditUserApi.java
@@ -30,6 +30,7 @@ import com.ning.billing.util.audit.AuditLogsForInvoicePayments;
 import com.ning.billing.util.audit.AuditLogsForInvoices;
 import com.ning.billing.util.audit.AuditLogsForPayments;
 import com.ning.billing.util.audit.AuditLogsForRefunds;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 public interface AuditUserApi {
@@ -39,45 +40,50 @@ public interface AuditUserApi {
      *
      * @param bundles    the bundles to lookup
      * @param auditLevel audit level (verbosity)
+     * @param context    the tenant context
      * @return all audit logs for these refunds
      */
-    public AuditLogsForBundles getAuditLogsForBundles(final List<BundleTimeline> bundles, final AuditLevel auditLevel);
+    public AuditLogsForBundles getAuditLogsForBundles(List<BundleTimeline> bundles, AuditLevel auditLevel, TenantContext context);
 
     /**
      * Fetch all audit logs for invoice payments.
      *
      * @param invoicePayments the invoice payments to lookup
      * @param auditLevel      audit level (verbosity)
+     * @param context         the tenant context
      * @return all audit logs for these invoice payments
      */
-    public AuditLogsForInvoicePayments getAuditLogsForInvoicePayments(final List<InvoicePayment> invoicePayments, final AuditLevel auditLevel);
+    public AuditLogsForInvoicePayments getAuditLogsForInvoicePayments(List<InvoicePayment> invoicePayments, AuditLevel auditLevel, TenantContext context);
 
     /**
      * Fetch all audit logs for refunds.
      *
      * @param refunds    the refunds to lookup
      * @param auditLevel audit level (verbosity)
+     * @param context    the tenant context
      * @return all audit logs for these refunds
      */
-    public AuditLogsForRefunds getAuditLogsForRefunds(final List<Refund> refunds, final AuditLevel auditLevel);
+    public AuditLogsForRefunds getAuditLogsForRefunds(List<Refund> refunds, AuditLevel auditLevel, TenantContext context);
 
     /**
      * Fetch all audit logs for payments.
      *
      * @param payments   the payments to lookup
      * @param auditLevel audit level (verbosity)
+     * @param context    the tenant context
      * @return all audit logs for these payments
      */
-    public AuditLogsForPayments getAuditLogsForPayments(final List<Payment> payments, final AuditLevel auditLevel);
+    public AuditLogsForPayments getAuditLogsForPayments(List<Payment> payments, AuditLevel auditLevel, TenantContext context);
 
     /**
      * Fetch all audit logs for invoices and associated invoice items.
      *
      * @param invoices   the invoices to lookup
      * @param auditLevel audit level (verbosity)
+     * @param context    the tenant context
      * @return all audit logs for these invoices
      */
-    public AuditLogsForInvoices getAuditLogsForInvoices(final List<Invoice> invoices, final AuditLevel auditLevel);
+    public AuditLogsForInvoices getAuditLogsForInvoices(List<Invoice> invoices, AuditLevel auditLevel, TenantContext context);
 
     /**
      * Get all the audit entries for a given object.
@@ -85,7 +91,8 @@ public interface AuditUserApi {
      * @param objectId   the object id
      * @param objectType the type of object
      * @param auditLevel audit level (verbosity)
+     * @param context    the tenant context
      * @return all audit entries for that object
      */
-    public List<AuditLog> getAuditLogs(final UUID objectId, final ObjectType objectType, final AuditLevel auditLevel);
+    public List<AuditLog> getAuditLogs(UUID objectId, ObjectType objectType, AuditLevel auditLevel, TenantContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java b/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
index 828d030..7a6328e 100644
--- a/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
@@ -21,11 +21,13 @@ import java.util.Map;
 import java.util.UUID;
 
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.dao.ObjectType;
 
 public interface CustomFieldUserApi {
-    Map<String, CustomField> getCustomFields(UUID objectId, ObjectType objectType);
+
+    Map<String, CustomField> getCustomFields(UUID objectId, ObjectType objectType, TenantContext context);
 
     void saveCustomFields(UUID objectId, ObjectType objectType, List<CustomField> fields, CallContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/util/api/TagUserApi.java b/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
index 5312fc4..3e31e4d 100644
--- a/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
@@ -22,15 +22,18 @@ import java.util.Map;
 import java.util.UUID;
 
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 
 public interface TagUserApi {
+
     /**
+     * @param context The tenant context
      * @return the list of all available tag definitions
      */
-    public List<TagDefinition> getTagDefinitions();
+    public List<TagDefinition> getTagDefinitions(TenantContext context);
 
     /**
      * @param definitionName Identifies the definition.
@@ -43,16 +46,16 @@ public interface TagUserApi {
 
     /**
      * @param tagDefinitionId The UUID for that tagDefinition
-     * @param context        The call context, for auditing purposes
+     * @param context         The call context, for auditing purposes
      * @throws TagDefinitionApiException
      */
     public void deleteTagDefinition(UUID tagDefinitionId, CallContext context) throws TagDefinitionApiException;
 
-    public TagDefinition getTagDefinition(UUID tagDefinitionId) throws TagDefinitionApiException;
+    public TagDefinition getTagDefinition(UUID tagDefinitionId, TenantContext context) throws TagDefinitionApiException;
 
-    public TagDefinition getTagDefinitionForName(String tageDefinitionName) throws TagDefinitionApiException;
+    public TagDefinition getTagDefinitionForName(String tageDefinitionName, TenantContext context) throws TagDefinitionApiException;
 
-    public List<TagDefinition> getTagDefinitions(final Collection<UUID> tagDefinitionIds) throws TagDefinitionApiException;
+    public List<TagDefinition> getTagDefinitions(Collection<UUID> tagDefinitionIds, TenantContext context) throws TagDefinitionApiException;
 
     public void addTags(UUID objectId, ObjectType objectType, Collection<UUID> tagDefinitionIds, CallContext context) throws TagApiException;
 
@@ -63,10 +66,10 @@ public interface TagUserApi {
     public void removeTag(UUID objectId, ObjectType objectType, UUID tagDefinitionId, CallContext context) throws TagApiException;
 
     /**
-     *
-     * @param objectId UUID of the object on which to retrieve the tags
+     * @param objectId   UUID of the object on which to retrieve the tags
      * @param objectType The type of object
+     * @param context    The tenant context
      * @return A map of tag, key being the tagId, and value the tag
      */
-    public Map<String, Tag> getTags(UUID objectId, ObjectType objectType);
+    public Map<String, Tag> getTags(UUID objectId, ObjectType objectType, TenantContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
index 2887f51..bb0270d 100644
--- a/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
+++ b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
@@ -20,7 +20,11 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-public interface CallContext {
+/**
+ * External use
+ */
+public interface CallContext extends TenantContext {
+
     public UUID getUserToken();
 
     public String getUserName();
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/TenantContext.java b/api/src/main/java/com/ning/billing/util/callcontext/TenantContext.java
new file mode 100644
index 0000000..d26c4a3
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/callcontext/TenantContext.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import java.util.UUID;
+
+/**
+ * External use
+ */
+public interface TenantContext {
+
+    public UUID getTenantId();
+}
diff --git a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
index 1eb1537..6e0d952 100644
--- a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
+++ b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
@@ -28,7 +28,8 @@ public enum ObjectType {
     SUBSCRIPTION_EVENT("subscription event"),
     PAYMENT_METHOD("payment method"),
     REFUND("refund"),
-    TAG_DEFINITION("tag definition");
+    TAG_DEFINITION("tag definition"),
+    TENANT("tenant");
 
     private final String objectName;
 
diff --git a/api/src/main/java/com/ning/billing/util/tag/Tag.java b/api/src/main/java/com/ning/billing/util/tag/Tag.java
index 33584d9..553ef5f 100644
--- a/api/src/main/java/com/ning/billing/util/tag/Tag.java
+++ b/api/src/main/java/com/ning/billing/util/tag/Tag.java
@@ -18,7 +18,6 @@ package com.ning.billing.util.tag;
 
 import java.util.UUID;
 
-
 import com.ning.billing.util.entity.Entity;
 
 public interface Tag extends Entity {
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
index b7c308d..4b9a492 100644
--- a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
@@ -21,8 +21,8 @@ import java.util.concurrent.TimeoutException;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
-import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.util.bus.BusEvent;
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueBase.java
index 27de0ba..a0d3aed 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueBase.java
@@ -15,10 +15,6 @@
  */
 package com.ning.billing.beatrix.integration.overdue;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.testng.Assert.assertNotNull;
-
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.List;
@@ -47,6 +43,10 @@ import com.ning.billing.util.config.XMLLoader;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.testng.Assert.assertNotNull;
+
 public abstract class TestOverdueBase extends TestIntegrationBase {
 
     @Inject
@@ -112,9 +112,9 @@ public abstract class TestOverdueBase extends TestIntegrationBase {
         account = createAccountWithPaymentMethod(getAccountData(0));
         assertNotNull(account);
 
-        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, paymentMethodPlugin, context);
+        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, paymentMethodPlugin, callContext);
 
-        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         productName = "Shotgun";
         term = BillingPeriod.MONTHLY;
@@ -133,11 +133,11 @@ public abstract class TestOverdueBase extends TestIntegrationBase {
             await().atMost(10, SECONDS).until(new Callable<Boolean>() {
                 @Override
                 public Boolean call() throws Exception {
-                    return expected.equals(blockingApi.getBlockingStateFor(bundle).getStateName());
+                    return expected.equals(blockingApi.getBlockingStateFor(bundle, callContext).getStateName());
                 }
             });
         } catch (Exception e) {
-            Assert.assertEquals(blockingApi.getBlockingStateFor(bundle).getStateName(), expected, "Got exception: " + e.toString());
+            Assert.assertEquals(blockingApi.getBlockingStateFor(bundle, callContext).getStateName(), expected, "Got exception: " + e.toString());
         }
     }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 6aa69ad..e243b56 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -111,14 +111,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         paymentPlugin.makeAllInvoicesFailWithError(true);
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -134,8 +134,8 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // DAY 65 - 35 days after invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Now we should be in OD1
         checkODState("OD1");
@@ -163,7 +163,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkChangePlanWithOverdueState(baseSubscription, true);
 
         paymentPlugin.makeAllInvoicesFailWithError(false);
-        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday());
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
         for (final Invoice invoice : invoices) {
             if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                 createPaymentAndCheckForCompletion(account, invoice, NextEvent.PAYMENT);
@@ -174,11 +174,11 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkChangePlanWithOverdueState(baseSubscription, false);
 
         invoiceChecker.checkRepairedInvoice(account.getId(), 3,
-                                            new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+                                            callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
                                             // We paid up to 07-31, hence the adjustment
                                             new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-249.95")),
                                             new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("249.95")));
-        invoiceChecker.checkInvoice(account.getId(), 4,
+        invoiceChecker.checkInvoice(account.getId(), 4, callContext,
                                     // Note the end date here is not 07-25, but 07-15. The overdue configuration disabled invoicing between 07-15 and 07-25 (e.g. the bundle
                                     // was inaccessible, hence we didn't want to charge the customer for that period, even though the account was overdue).
                                     new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("124.98")),
@@ -186,10 +186,10 @@ public class TestOverdueIntegration extends TestOverdueBase {
                                     new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("116.09")),
                                     // Credits consumed
                                     new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("-241.07")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Verify the account balance: 249.95 - 124.98 - 116.09
-        assertEquals(invoiceUserApi.getAccountBalance(account.getId()).compareTo(new BigDecimal("-8.88")), 0);
+        assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("-8.88")), 0);
     }
 
     @Test(groups = "slow")
@@ -200,19 +200,19 @@ public class TestOverdueIntegration extends TestOverdueBase {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
 
         // Make sure the account doesn't have any payment method
-        accountUserApi.removePaymentMethod(account.getId(), context);
+        accountUserApi.removePaymentMethod(account.getId(), callContext);
 
         // Create subscription
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment. A payment error, one for each invoice, should be on the bus (because there is no payment method)
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -227,8 +227,8 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Single PAYMENT_ERROR here here triggered by the invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Now we should be in OD1
         checkODState("OD1");
@@ -256,10 +256,10 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkChangePlanWithOverdueState(baseSubscription, true);
 
         // Add a payment method and set it as default
-        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, paymentMethodPlugin, context);
+        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, paymentMethodPlugin, callContext);
 
         // Pay all invoices
-        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday());
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
         for (final Invoice invoice : invoices) {
             if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                 createPaymentAndCheckForCompletion(account, invoice, NextEvent.PAYMENT);
@@ -270,11 +270,11 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkChangePlanWithOverdueState(baseSubscription, false);
 
         invoiceChecker.checkRepairedInvoice(account.getId(), 3,
-                                            new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+                                            callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
                                             // We paid up to 07-31, hence the adjustment
                                             new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-249.95")),
                                             new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("249.95")));
-        invoiceChecker.checkInvoice(account.getId(), 4,
+        invoiceChecker.checkInvoice(account.getId(), 4, callContext,
                                     // Note the end date here is not 07-25, but 07-15. The overdue configuration disabled invoicing between 07-15 and 07-25 (e.g. the bundle
                                     // was inaccessible, hence we didn't want to charge the customer for that period, even though the account was overdue).
                                     new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("124.98")),
@@ -282,10 +282,10 @@ public class TestOverdueIntegration extends TestOverdueBase {
                                     new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("116.09")),
                                     // Credits consumed
                                     new ExpectedItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("-241.07")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Verify the account balance: 249.95 - 124.98 - 116.09
-        assertEquals(invoiceUserApi.getAccountBalance(account.getId()).compareTo(new BigDecimal("-8.88")), 0);
+        assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("-8.88")), 0);
     }
 
     @Test(groups = "slow")
@@ -295,26 +295,26 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Create a subscription without failing payments
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // Create an external charge on a new invoice
         addDaysAndCheckForCompletion(5);
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        invoiceApi.insertExternalChargeForBundle(account.getId(), bundle.getId(), BigDecimal.TEN, "For overdue", new LocalDate(2012, 5, 6), Currency.USD, context);
+        invoiceApi.insertExternalChargeForBundle(account.getId(), bundle.getId(), BigDecimal.TEN, "For overdue", new LocalDate(2012, 5, 6), Currency.USD, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 6), null, InvoiceItemType.EXTERNAL_CHARGE, BigDecimal.TEN));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 6), null, InvoiceItemType.EXTERNAL_CHARGE, BigDecimal.TEN));
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(25, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state - the invoice for the bundle has been paid, but not the invoice with the external charge
         // We refresh overdue just to be safe, see below
-        overdueApi.refreshOverdueStateFor(bundle);
+        overdueApi.refreshOverdueStateFor(bundle, callContext);
         checkODState(BlockingApi.CLEAR_STATE_NAME);
 
         // Past 30 days since the external charge
@@ -322,12 +322,12 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Note! We need to explicitly refresh here because overdue won't get notified to refresh up until the next
         // payment (when the next invoice is generated)
         // TODO - we should fix this
-        overdueApi.refreshOverdueStateFor(bundle);
+        overdueApi.refreshOverdueStateFor(bundle, callContext);
         // We should now be in OD1
         checkODState("OD1");
 
         // Pay the invoice
-        final Invoice externalChargeInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday()).iterator().next();
+        final Invoice externalChargeInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).iterator().next();
         createExternalPaymentAndCheckForCompletion(account, externalChargeInvoice, NextEvent.PAYMENT);
         // We should be clear now
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -340,14 +340,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Create subscription and don't fail payments
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -361,14 +361,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // DAY 65 - 35 days after invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
 
         // Now, refund the second (first non-zero dollar) invoice
-        final Payment payment = paymentApi.getPayment(invoiceApi.getInvoicesByAccount(account.getId()).get(1).getPayments().get(0).getPaymentId());
+        final Payment payment = paymentApi.getPayment(invoiceApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), callContext);
         refundPaymentAndCheckForCompletion(account, payment, NextEvent.INVOICE_ADJUSTMENT);
         // We should now be in OD1
         checkODState("OD1");
@@ -382,14 +382,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Create subscription and don't fail payments
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -403,14 +403,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // DAY 65 - 35 days after invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
 
         // Now, create a chargeback for the second (first non-zero dollar) invoice
-        final InvoicePayment payment = invoicePaymentApi.getInvoicePayments(invoiceApi.getInvoicesByAccount(account.getId()).get(1).getPayments().get(0).getPaymentId()).get(0);
+        final InvoicePayment payment = invoicePaymentApi.getInvoicePayments(invoiceApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), callContext).get(0);
         createChargeBackAndCheckForCompletion(payment, NextEvent.INVOICE_ADJUSTMENT);
         // We should now be in OD1
         checkODState("OD1");
@@ -425,14 +425,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         paymentPlugin.makeAllInvoicesFailWithError(true);
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -446,8 +446,8 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // DAY 65 - 35 days after invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Now we should be in OD1
         checkODState("OD1");
@@ -456,7 +456,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // We have two unpaid non-zero dollar invoices at this point
         // Pay the first one via an external payment - we should then be 5 days apart from the second invoice
         // (which is the earliest unpaid one) and hence come back to a clear state (see configuration)
-        final Invoice firstNonZeroInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday()).iterator().next();
+        final Invoice firstNonZeroInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).iterator().next();
         createExternalPaymentAndCheckForCompletion(account, firstNonZeroInvoice, NextEvent.PAYMENT);
         // We should be clear now
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -475,14 +475,14 @@ public class TestOverdueIntegration extends TestOverdueBase {
         paymentPlugin.makeAllInvoicesFailWithError(true);
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -496,8 +496,8 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // DAY 65 - 35 days after invoice
         addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 3, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Now we should be in OD1
         checkODState("OD1");
@@ -506,15 +506,15 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // We have two unpaid non-zero dollar invoices at this point
         // Adjust the first (and only) item of the first invoice - we should then be 5 days apart from the second invoice
         // (which is the earliest unpaid one) and hence come back to a clear state (see configuration)
-        final Invoice firstNonZeroInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday()).iterator().next();
+        final Invoice firstNonZeroInvoice = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).iterator().next();
         fullyAdjustInvoiceItemAndCheckForCompletion(account, firstNonZeroInvoice, 1, NextEvent.INVOICE_ADJUSTMENT);
         // We should be clear now
         checkODState(BlockingApi.CLEAR_STATE_NAME);
 
         invoiceChecker.checkRepairedInvoice(account.getId(), 2,
-                                            new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+                                            callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
                                             new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 5, 31), InvoiceItemType.ITEM_ADJ, new BigDecimal("-249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // DAY 70 - 10 days after second invoice
         addDaysAndCheckForCompletion(5);
@@ -535,10 +535,10 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkODState("OD1");
         checkChangePlanWithOverdueState(baseSubscription, true);
 
-        invoiceChecker.checkInvoice(account.getId(), 4, new ExpectedItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 8, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 8, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
 
         // Fully adjust all invoices
-        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday());
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
         for (final Invoice invoice : invoices) {
             if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                 fullyAdjustInvoiceAndCheckForCompletion(account, invoice, NextEvent.INVOICE_ADJUSTMENT);
@@ -552,7 +552,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
     private void checkChangePlanWithOverdueState(final Subscription subscription, final boolean shouldFail) {
         if (shouldFail) {
             try {
-                subscription.changePlan("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), context);
+                subscription.changePlan("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), callContext);
             } catch (EntitlementUserApiException e) {
                 assertTrue(e.getCause() instanceof BlockingApiException);
             }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
index 11c5e8d..b9eeb2a 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
@@ -15,19 +15,7 @@
  */
 package com.ning.billing.beatrix.integration.overdue;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
 import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-
-import junit.framework.Assert;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
@@ -43,6 +31,8 @@ import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.junction.api.BlockingApi;
 
+import static junit.framework.Assert.assertTrue;
+
 @Test(groups = "slow")
 @Guice(modules = {BeatrixModule.class})
 public class TestOverdueWithSubscriptionCancellation extends TestOverdueBase {
@@ -79,14 +69,14 @@ public class TestOverdueWithSubscriptionCancellation extends TestOverdueBase {
         paymentPlugin.makeAllInvoicesFailWithError(true);
         final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
 
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
 
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
-        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+        invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         // Should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
@@ -97,7 +87,7 @@ public class TestOverdueWithSubscriptionCancellation extends TestOverdueBase {
         // Should be in OD1
         checkODState("OD1");
 
-        Subscription cancelledBaseSubscription = entitlementUserApi.getSubscriptionFromId(baseSubscription.getId());
+        final Subscription cancelledBaseSubscription = entitlementUserApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertTrue(cancelledBaseSubscription.getState() == SubscriptionState.CANCELLED);
     }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
index 0dfcc78..78e2d55 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -39,6 +38,8 @@ import com.ning.billing.analytics.model.BusinessAccount;
 import com.ning.billing.analytics.model.BusinessAccountTag;
 import com.ning.billing.analytics.model.BusinessInvoice;
 import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessOverdueStatus;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
 import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.analytics.utils.Rounder;
@@ -54,7 +55,6 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.invoice.generator.InvoiceDateUtils;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.util.api.TagApiException;
@@ -157,8 +157,8 @@ public class TestAnalytics extends TestIntegrationBase {
 
         // Cancel end of term - refetch the subscription to have the CTD set
         // (otherwise, cancellation would be immediate)
-        subscription = entitlementUserApi.getSubscriptionFromId(subscription.getId());
-        subscription.cancel(clock.getUTCNow(), context);
+        subscription = entitlementUserApi.getSubscriptionFromId(subscription.getId(), callContext);
+        subscription.cancel(clock.getUTCNow(), callContext);
 
         waitALittle();
 
@@ -206,14 +206,14 @@ public class TestAnalytics extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
 
         // Verify the initial state of payments
-        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey(), callContext).size(), 0);
 
         // Verify the account payment fields
-        Assert.assertEquals(analyticsUserApi.getAccountByKey(account.getExternalKey()).getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
-        Assert.assertNull(analyticsUserApi.getAccountByKey(account.getExternalKey()).getLastPaymentStatus());
+        Assert.assertEquals(analyticsUserApi.getAccountByKey(account.getExternalKey(), callContext).getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        Assert.assertNull(analyticsUserApi.getAccountByKey(account.getExternalKey(), callContext).getLastPaymentStatus());
 
         // Verify the initial overdue status
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext).size(), 0);
 
         // Move after trial
         busHandler.pushExpectedEvents(TestApiListener.NextEvent.PHASE, TestApiListener.NextEvent.INVOICE, TestApiListener.NextEvent.PAYMENT_ERROR);
@@ -225,26 +225,27 @@ public class TestAnalytics extends TestIntegrationBase {
         verifyBSTWithTrialAndEvergreenPhases(account, bundle, subscription);
 
         // Verify the payments - we should have received one
-        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).size(), 1);
-        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getAccountKey(), account.getExternalKey());
-        Assert.assertTrue(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getAmount().compareTo(BigDecimal.ZERO) > 0);
-        Assert.assertTrue(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getRequestedAmount().compareTo(BigDecimal.ZERO) > 0);
-        Assert.assertNull(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getExtFirstPaymentRefId());
-        Assert.assertNull(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getExtSecondPaymentRefId());
-        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getProcessingStatus(), PaymentStatus.PAYMENT_FAILURE.toString());
-        Assert.assertEquals(analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getPluginName(), BeatrixModule.PLUGIN_NAME);
+        final List<BusinessInvoicePayment> invoicePaymentsForAccount = analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey(), callContext);
+        Assert.assertEquals(invoicePaymentsForAccount.size(), 1);
+        Assert.assertEquals(invoicePaymentsForAccount.get(0).getAccountKey(), account.getExternalKey());
+        Assert.assertTrue(invoicePaymentsForAccount.get(0).getAmount().compareTo(BigDecimal.ZERO) > 0);
+        Assert.assertTrue(invoicePaymentsForAccount.get(0).getRequestedAmount().compareTo(BigDecimal.ZERO) > 0);
+        Assert.assertNull(invoicePaymentsForAccount.get(0).getExtFirstPaymentRefId());
+        Assert.assertNull(invoicePaymentsForAccount.get(0).getExtSecondPaymentRefId());
+        Assert.assertEquals(invoicePaymentsForAccount.get(0).getProcessingStatus(), PaymentStatus.PAYMENT_FAILURE.toString());
+        Assert.assertEquals(invoicePaymentsForAccount.get(0).getPluginName(), BeatrixModule.PLUGIN_NAME);
 
         // Verify the account object has been updated
-        Assert.assertEquals(analyticsUserApi.getAccountByKey(account.getExternalKey()).getBalance(),
-                            analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getAmount());
+        Assert.assertEquals(analyticsUserApi.getAccountByKey(account.getExternalKey(), callContext).getBalance(),
+                            invoicePaymentsForAccount.get(0).getAmount());
 
         // Verify the invoice balance isn't zero and is equal to the payment amount (don't look at the first, trial, invoice)
-        Assert.assertTrue(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getBalance().compareTo(BigDecimal.ZERO) > 0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getBalance(),
-                            analyticsUserApi.getInvoicePaymentsForAccount(account.getExternalKey()).get(0).getAmount());
+        Assert.assertTrue(analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext).get(1).getBalance().compareTo(BigDecimal.ZERO) > 0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext).get(1).getBalance(),
+                            invoicePaymentsForAccount.get(0).getAmount());
 
         // Verify overdue status - we should still be in clear state
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext).size(), 0);
 
         clock.addDays(15); // DAY 45 - 15 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
@@ -253,7 +254,7 @@ public class TestAnalytics extends TestIntegrationBase {
         verifyBSTWithTrialAndEvergreenPhases(account, bundle, subscription);
 
         // Verify overdue status - we should still be in clear state
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext).size(), 0);
 
         busHandler.pushExpectedEvents(TestApiListener.NextEvent.INVOICE, TestApiListener.NextEvent.PAYMENT_ERROR);
         clock.addDays(20); // DAY 65 - 35 days after invoice
@@ -261,67 +262,71 @@ public class TestAnalytics extends TestIntegrationBase {
         waitALittle();
 
         // Verify overdue status - we should be in OD1
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 1);
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getStatus(), "OD1");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getAccountKey(), account.getExternalKey());
+        final List<BusinessOverdueStatus> od1Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
+        Assert.assertEquals(od1Bundle.size(), 1);
+        Assert.assertEquals(od1Bundle.get(0).getStatus(), "OD1");
+        Assert.assertEquals(od1Bundle.get(0).getBundleId(), bundle.getId());
+        Assert.assertEquals(od1Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od1Bundle.get(0).getAccountKey(), account.getExternalKey());
 
         clock.addDays(2); // DAY 67 - 37 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         waitALittle();
         // Verify overdue status - we should still be in OD1
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 1);
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getStatus(), "OD1");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getAccountKey(), account.getExternalKey());
+        final List<BusinessOverdueStatus> stillOd1Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
+        Assert.assertEquals(stillOd1Bundle.size(), 1);
+        Assert.assertEquals(stillOd1Bundle.get(0).getStatus(), "OD1");
+        Assert.assertEquals(stillOd1Bundle.get(0).getBundleId(), bundle.getId());
+        Assert.assertEquals(stillOd1Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(stillOd1Bundle.get(0).getAccountKey(), account.getExternalKey());
 
         clock.addDays(8); // DAY 75 - 45 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         waitALittle();
         // Verify overdue status - we should be in OD2
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 2);
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getStatus(), "OD1");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getStatus(), "OD2");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getEndDate(),
-                            analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getStartDate());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getAccountKey(), account.getExternalKey());
+        final List<BusinessOverdueStatus> od2Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
+        Assert.assertEquals(od2Bundle.size(), 2);
+        Assert.assertEquals(od2Bundle.get(0).getStatus(), "OD1");
+        Assert.assertEquals(od2Bundle.get(1).getStatus(), "OD2");
+        Assert.assertEquals(od2Bundle.get(0).getEndDate(),
+                            od2Bundle.get(1).getStartDate());
+        Assert.assertEquals(od2Bundle.get(0).getBundleId(), bundle.getId());
+        Assert.assertEquals(od2Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od2Bundle.get(0).getAccountKey(), account.getExternalKey());
+        Assert.assertEquals(od2Bundle.get(1).getBundleId(), bundle.getId());
+        Assert.assertEquals(od2Bundle.get(1).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od2Bundle.get(1).getAccountKey(), account.getExternalKey());
 
         clock.addDays(10); // DAY 85 - 55 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         waitALittle();
         // Verify overdue status - we should be in OD3
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).size(), 3);
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getStatus(), "OD1");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getStatus(), "OD2");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(2).getStatus(), "OD3");
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getEndDate(),
-                            analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getStartDate());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getEndDate(),
-                            analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(2).getStartDate());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(0).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(1).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(2).getBundleId(), bundle.getId());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(2).getExternalKey(), bundle.getKey());
-        Assert.assertEquals(analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey()).get(2).getAccountKey(), account.getExternalKey());
+        final List<BusinessOverdueStatus> od3Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
+        Assert.assertEquals(od3Bundle.size(), 3);
+        Assert.assertEquals(od3Bundle.get(0).getStatus(), "OD1");
+        Assert.assertEquals(od3Bundle.get(1).getStatus(), "OD2");
+        Assert.assertEquals(od3Bundle.get(2).getStatus(), "OD3");
+        Assert.assertEquals(od3Bundle.get(0).getEndDate(),
+                            od3Bundle.get(1).getStartDate());
+        Assert.assertEquals(od3Bundle.get(1).getEndDate(),
+                            od3Bundle.get(2).getStartDate());
+        Assert.assertEquals(od3Bundle.get(0).getBundleId(), bundle.getId());
+        Assert.assertEquals(od3Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(0).getAccountKey(), account.getExternalKey());
+        Assert.assertEquals(od3Bundle.get(1).getBundleId(), bundle.getId());
+        Assert.assertEquals(od3Bundle.get(1).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(1).getAccountKey(), account.getExternalKey());
+        Assert.assertEquals(od3Bundle.get(2).getBundleId(), bundle.getId());
+        Assert.assertEquals(od3Bundle.get(2).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(2).getAccountKey(), account.getExternalKey());
     }
 
-    private Account verifyAccountCreation(int billCycleDay) throws Exception {
+    private Account verifyAccountCreation(final int billCycleDay) throws Exception {
 
         final AccountData accountData = getAccountData(billCycleDay);
 
         // Verify BAC is empty
-        Assert.assertNull(analyticsUserApi.getAccountByKey(accountData.getExternalKey()));
+        Assert.assertNull(analyticsUserApi.getAccountByKey(accountData.getExternalKey(), callContext));
 
         // Create an account
         final Account account = createAccountWithPaymentMethod(accountData);
@@ -330,7 +335,7 @@ public class TestAnalytics extends TestIntegrationBase {
         waitALittle();
 
         // Verify Analytics got the account creation event
-        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey());
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey(), callContext);
         Assert.assertNotNull(businessAccount);
         // No balance yet
         Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
@@ -348,7 +353,7 @@ public class TestAnalytics extends TestIntegrationBase {
         //Assert.assertNotNull(businessAccount.getPaymentMethod());
 
         // The account shouldn't have any invoice yet
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext).size(), 0);
 
         return account;
     }
@@ -359,7 +364,7 @@ public class TestAnalytics extends TestIntegrationBase {
         mutableAccountData.setName(UUID.randomUUID().toString().substring(0, 20));
 
         try {
-            accountUserApi.updateAccount(account.getId(), mutableAccountData, context);
+            accountUserApi.updateAccount(account.getId(), mutableAccountData, callContext);
         } catch (AccountApiException e) {
             Assert.fail("Unable to update account", e);
         }
@@ -367,7 +372,7 @@ public class TestAnalytics extends TestIntegrationBase {
         waitALittle();
 
         // Verify Analytics got the account update event
-        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(mutableAccountData.getExternalKey());
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(mutableAccountData.getExternalKey(), callContext);
         Assert.assertNotNull(businessAccount);
         // No balance yet
         Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
@@ -385,34 +390,34 @@ public class TestAnalytics extends TestIntegrationBase {
         //Assert.assertNotNull(businessAccount.getPaymentMethod());
 
         // The account should still not have any invoice
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext).size(), 0);
     }
 
     private void verifyAddTagToAccount(final Account account) throws TagDefinitionApiException, TagApiException, InterruptedException {
-        Assert.assertEquals(analyticsUserApi.getTagsForAccount(account.getExternalKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext).size(), 0);
 
-        final TagDefinition tagDefinition = tagUserApi.create(UUID.randomUUID().toString().substring(0, 10), UUID.randomUUID().toString(), context);
-        tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, tagDefinition.getId(), context);
+        final TagDefinition tagDefinition = tagUserApi.create(UUID.randomUUID().toString().substring(0, 10), UUID.randomUUID().toString(), callContext);
+        tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, tagDefinition.getId(), callContext);
 
         waitALittle();
 
-        final List<BusinessAccountTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey());
+        final List<BusinessAccountTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext);
         Assert.assertEquals(tagsForAccount.size(), 1);
         Assert.assertEquals(tagsForAccount.get(0).getName(), tagDefinition.getName());
     }
 
     private SubscriptionBundle verifyFirstBundle(final Account account) throws EntitlementUserApiException, InterruptedException {
         // Add a bundle
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), UUID.randomUUID().toString(), context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), UUID.randomUUID().toString(), callContext);
         Assert.assertNotNull(bundle);
 
         waitALittle();
 
         // Verify BST is still empty since no subscription has been added yet
-        Assert.assertEquals(analyticsUserApi.getTransitionsForBundle(bundle.getKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext).size(), 0);
 
         // The account should still not have any invoice
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext).size(), 0);
 
         return bundle;
     }
@@ -423,7 +428,7 @@ public class TestAnalytics extends TestIntegrationBase {
         final BillingPeriod term = BillingPeriod.MONTHLY;
         final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
         final PlanPhaseSpecifier phaseSpecifier = new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null);
-        final Subscription subscription = entitlementUserApi.createSubscription(bundle.getId(), phaseSpecifier, null, context);
+        final Subscription subscription = entitlementUserApi.createSubscription(bundle.getId(), phaseSpecifier, null, callContext);
         subscriptionPlan = subscription.getCurrentPlan();
 
         waitALittle();
@@ -432,12 +437,12 @@ public class TestAnalytics extends TestIntegrationBase {
         verifyBSTWithTrialAndEvergreenPhases(account, bundle, subscription);
 
         // Make sure the account balance is still zero
-        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey());
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey(), callContext);
         Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
         Assert.assertEquals(businessAccount.getTotalInvoiceBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
 
         // The account should have one invoice for the trial phase
-        final List<BusinessInvoice> invoices = analyticsUserApi.getInvoicesForAccount(account.getExternalKey());
+        final List<BusinessInvoice> invoices = analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext);
         Assert.assertEquals(invoices.size(), 1);
         final BusinessInvoice invoice = invoices.get(0);
         Assert.assertEquals(invoice.getBalance().doubleValue(), 0.0);
@@ -447,15 +452,14 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(invoice.getCurrency(), account.getCurrency());
 
         // The invoice should have a single item associated to it
-        final List<BusinessInvoiceItem> invoiceItems = analyticsUserApi.getInvoiceItemsForInvoice(invoice.getInvoiceId());
+        final List<BusinessInvoiceItem> invoiceItems = analyticsUserApi.getInvoiceItemsForInvoice(invoice.getInvoiceId(), callContext);
         Assert.assertEquals(invoiceItems.size(), 1);
         final BusinessInvoiceItem invoiceItem = invoiceItems.get(0);
         Assert.assertEquals(invoiceItem.getAmount().doubleValue(), 0.0);
         // No billing period for the trial item
         Assert.assertEquals(invoiceItem.getBillingPeriod(), subscription.getCurrentPhase().getBillingPeriod().toString());
         Assert.assertEquals(invoiceItem.getCurrency(), account.getCurrency());
-        // No end date for the trial item (fixed price of zero)
-        Assert.assertNull(invoiceItem.getEndDate());
+        Assert.assertEquals(invoiceItem.getEndDate(), invoiceItem.getStartDate().plusDays(30));
         Assert.assertEquals(invoiceItem.getExternalKey(), bundle.getKey());
         Assert.assertEquals(invoiceItem.getInvoiceId(), invoice.getInvoiceId());
         Assert.assertEquals(invoiceItem.getItemType(), "FIXED");
@@ -472,7 +476,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
     private void verifyBSTWithTrialAndEvergreenPhases(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws CatalogApiException {
         // BST should have two transitions
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(transitions.size(), 2);
 
         verifyTrialAndEvergreenPhases(account, bundle, subscription);
@@ -480,7 +484,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
     private void verifyBSTWithTrialAndEvergreenPhasesAndCancellation(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws CatalogApiException {
         // BST should have three transitions
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(transitions.size(), 3);
 
         verifyTrialAndEvergreenPhases(account, bundle, subscription);
@@ -489,7 +493,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
     private void verifyBSTWithTrialAndEvergreenPhasesAndCancellationAndSystemCancellation(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws CatalogApiException {
         // BST should have four transitions
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(transitions.size(), 4);
 
         verifyTrialAndEvergreenPhases(account, bundle, subscription);
@@ -499,7 +503,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
     private void verifyTrialAndEvergreenPhases(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws CatalogApiException {
         final Product currentProduct = subscriptionPlan.getProduct();
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
 
         // Check the first transition (into trial phase)
         final BusinessSubscriptionTransition initialTransition = transitions.get(0);
@@ -554,7 +558,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
     private void verifyCancellationTransition(final Account account, final SubscriptionBundle bundle) throws CatalogApiException {
         final Product currentProduct = subscriptionPlan.getProduct();
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
 
         final BusinessSubscriptionTransition cancellationRequest = transitions.get(2);
         Assert.assertEquals(cancellationRequest.getExternalKey(), bundle.getKey());
@@ -568,7 +572,7 @@ public class TestAnalytics extends TestIntegrationBase {
     }
 
     private void verifySystemCancellationTransition(final Account account, final SubscriptionBundle bundle) throws CatalogApiException {
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
 
         final BusinessSubscriptionTransition systemCancellation = transitions.get(3);
         Assert.assertEquals(systemCancellation.getExternalKey(), bundle.getKey());
@@ -586,12 +590,12 @@ public class TestAnalytics extends TestIntegrationBase {
         final BillingPeriod newTerm = BillingPeriod.MONTHLY;
         final String newPlanSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
         final DateTime requestedDate = clock.getUTCNow();
-        Assert.assertTrue(subscription.changePlan(newProductName, newTerm, newPlanSetName, requestedDate, context));
+        Assert.assertTrue(subscription.changePlan(newProductName, newTerm, newPlanSetName, requestedDate, callContext));
 
         waitALittle();
 
         // BST should have three transitions (a ADD_BASE, CHANGE_BASE and SYSTEM_CHANGE_BASE)
-        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(transitions.size(), 3);
         final BusinessSubscriptionTransition previousTransition = transitions.get(0);
         final BusinessSubscriptionTransition transition = transitions.get(1);
@@ -623,17 +627,18 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(transition.getNextSubscription().getState(), Subscription.SubscriptionState.ACTIVE);
 
         // The account should have two invoices for the trial phase of both subscriptions
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 2);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getBalance().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountCharged().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountCredited().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountPaid().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getCurrency(), account.getCurrency());
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getBalance().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountCharged().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountCredited().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountPaid().doubleValue(), 0.0);
-        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getCurrency(), account.getCurrency());
+        final List<BusinessInvoice> invoicesForAccount = analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext);
+        Assert.assertEquals(invoicesForAccount.size(), 2);
+        Assert.assertEquals(invoicesForAccount.get(0).getBalance().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(0).getAmountCharged().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(0).getAmountCredited().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(0).getAmountPaid().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(0).getCurrency(), account.getCurrency());
+        Assert.assertEquals(invoicesForAccount.get(1).getBalance().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(1).getAmountCharged().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(1).getAmountCredited().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(1).getAmountPaid().doubleValue(), 0.0);
+        Assert.assertEquals(invoicesForAccount.get(1).getCurrency(), account.getCurrency());
     }
 
     private void waitALittle() throws InterruptedException {
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
index f6c2124..57800ba 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
@@ -15,10 +15,6 @@
  */
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.math.BigDecimal;
 import java.util.List;
 
@@ -27,7 +23,6 @@ import org.joda.time.LocalDate;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.api.TestApiListener.NextEvent;
@@ -42,6 +37,12 @@ import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 
+import com.google.common.collect.ImmutableList;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 @Guice(modules = {BeatrixModule.class})
 public class TestBundleTransfer extends TestIntegrationBase {
 
@@ -56,7 +57,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final DateTime initialDate = new DateTime(2012, 4, 1, 0, 15, 42, 0, testTimeZone);
 
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.ANNUAL;
@@ -69,13 +70,13 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final SubscriptionData bpSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                                                                                                                        bpPlanPhaseSpecifier,
                                                                                                                        null,
-                                                                                                                       context));
+                                                                                                                       callContext));
         assertNotNull(bpSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId()).size(), 1);
+        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
 
         // Move out of trials for interesting invoices adjustments
         busHandler.pushExpectedEvent(NextEvent.PHASE);
@@ -91,11 +92,11 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, context);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId());
+        List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
@@ -116,7 +117,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final DateTime initialDate = new DateTime(2012, 4, 1, 0, 15, 42, 0, testTimeZone);
 
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -129,13 +130,13 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final SubscriptionData bpSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                                                                                                                        bpPlanPhaseSpecifier,
                                                                                                                        null,
-                                                                                                                       context));
+                                                                                                                       callContext));
         assertNotNull(bpSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId()).size(), 1);
+        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
 
         // Move out of trials for interesting invoices adjustments
         busHandler.pushExpectedEvent(NextEvent.PHASE);
@@ -151,18 +152,18 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, context);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
         // Verify the BCD of the new account
-        final BillCycleDay oldBCD = accountUserApi.getAccountById(account.getId()).getBillCycleDay();
-        final BillCycleDay newBCD = accountUserApi.getAccountById(newAccount.getId()).getBillCycleDay();
+        final BillCycleDay oldBCD = accountUserApi.getAccountById(account.getId(), callContext).getBillCycleDay();
+        final BillCycleDay newBCD = accountUserApi.getAccountById(newAccount.getId(), callContext).getBillCycleDay();
         assertEquals(oldBCD.getDayOfMonthUTC(), 1);
         // Day of the transfer
         assertEquals(newBCD.getDayOfMonthUTC(), 3);
 
-        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(newAccount.getId());
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(newAccount.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
@@ -183,7 +184,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final DateTime initialDate = new DateTime(2012, 4, 1, 0, 15, 42, 0, testTimeZone);
 
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "mycutebundle", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -196,13 +197,13 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final SubscriptionData bpSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                                                                                                                        bpPlanPhaseSpecifier,
                                                                                                                        null,
-                                                                                                                       context));
+                                                                                                                       callContext));
         assertNotNull(bpSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId()).size(), 1);
+        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
 
         // Move out of trials for interesting invoices adjustments
         busHandler.pushExpectedEvent(NextEvent.PHASE);
@@ -220,11 +221,11 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, true, context);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, true, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(account.getId());
+        List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 3);
 
 
@@ -233,19 +234,19 @@ public class TestBundleTransfer extends TestIntegrationBase {
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,9), InvoiceItemType.RECURRING, new BigDecimal("66.66")),
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,9), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-66.66")),
                 new ExpectedItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,3), InvoiceItemType.CBA_ADJ, new BigDecimal("66.66")));
-        invoiceChecker.checkInvoice(invoices.get(1).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
 
         toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,3), InvoiceItemType.RECURRING, new BigDecimal("16.67")),
                 new ExpectedItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,3), InvoiceItemType.CBA_ADJ, new BigDecimal("-16.67")));
-        invoiceChecker.checkInvoice(invoices.get(2).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
 
         // CHECK NEW ACCOUNT ITEMS
-        invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId());
+        invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,15), InvoiceItemType.RECURRING, new BigDecimal("99.98")));
-        invoiceChecker.checkInvoice(invoices.get(0).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(0).getId(), callContext, toBeChecked);
     }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
index 7d322e0..6876f32 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
@@ -23,7 +23,6 @@ import org.joda.time.LocalDate;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.beatrix.util.InvoiceChecker.ExpectedItemCheck;
@@ -37,6 +36,8 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItemType;
 
+import com.google.common.collect.ImmutableList;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
@@ -52,7 +53,7 @@ public class TestEntitlement extends TestIntegrationBase {
 
         // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
         clock.setDeltaFromReality(today.toDateTimeAtCurrentTime().getMillis() - clock.getUTCNow().getMillis());
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.ANNUAL;
@@ -66,13 +67,13 @@ public class TestEntitlement extends TestIntegrationBase {
         final SubscriptionData bpSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                                                                                                                        bpPlanPhaseSpecifier,
                                                                                                                        null,
-                                                                                                                       context));
+                                                                                                                       callContext));
         assertNotNull(bpSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId()).size(), 1);
+        assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
 
         // Move out of trials for interesting invoices adjustments
         busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
@@ -80,34 +81,34 @@ public class TestEntitlement extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
+        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         ImmutableList<ExpectedItemCheck> toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2013,5,1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
-        invoiceChecker.checkInvoice(invoices.get(1).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
 
         //
         // FORCE AN IMMEDIATE CHANGE OF THE BILLING PERIOD
         //
         busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
-        assertTrue(bpSubscription.changePlanWithPolicy(productName, BillingPeriod.MONTHLY, planSetName, clock.getUTCNow(), ActionPolicy.IMMEDIATE, context));
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
+        assertTrue(bpSubscription.changePlanWithPolicy(productName, BillingPeriod.MONTHLY, planSetName, clock.getUTCNow(), ActionPolicy.IMMEDIATE, callContext));
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 3);
         toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2013,5,1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2013,5,1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-2399.95")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("2399.95")));
-        invoiceChecker.checkInvoice(invoices.get(1).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
 
         toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,11), InvoiceItemType.RECURRING, new BigDecimal("65.76")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.RECURRING, new BigDecimal("169.32")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-235.08")));
-        invoiceChecker.checkInvoice(invoices.get(2).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
 
 
 
@@ -115,12 +116,12 @@ public class TestEntitlement extends TestIntegrationBase {
         // FORCE ANOTHER CHANGE
         //
         busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
-        assertTrue(bpSubscription.changePlanWithPolicy(productName, BillingPeriod.ANNUAL, planSetName, clock.getUTCNow(), ActionPolicy.IMMEDIATE, context));
-        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
+        assertTrue(bpSubscription.changePlanWithPolicy(productName, BillingPeriod.ANNUAL, planSetName, clock.getUTCNow(), ActionPolicy.IMMEDIATE, callContext));
+        assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 4);
 
 
@@ -130,13 +131,13 @@ public class TestEntitlement extends TestIntegrationBase {
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-235.08")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-169.32")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("169.32")));
-        invoiceChecker.checkInvoice(invoices.get(2).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
 
 
         toBeChecked = ImmutableList.<ExpectedItemCheck>of(
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.RECURRING, new BigDecimal("137.76")),
                 new ExpectedItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-137.76")));
-        invoiceChecker.checkInvoice(invoices.get(3).getId(), toBeChecked);
+        invoiceChecker.checkInvoice(invoices.get(3).getId(), callContext, toBeChecked);
 
 
     }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index d9efb35..6371c98 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -57,19 +57,19 @@ public class TestIntegration extends TestIntegrationBase {
         // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
         clock.setDay(new LocalDate(2012, 4, 1));
 
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
         final Subscription bpSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
-        invoiceChecker.checkInvoice(account.getId(), 1, new ExpectedItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
 
         //
         // ADD ADD_ON ON THE SAME DAY
         //
         createSubscriptionAndCheckForCompletion(bundle.getId(), "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), 2, new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
 
         //
         // CANCEL BP ON THE SAME DAY (we should have two cancellations, BP and AO)
@@ -77,7 +77,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         cancelSubscriptionAndCheckForCompletion(bpSubscription, clock.getUTCNow(), NextEvent.CANCEL, NextEvent.CANCEL);
         invoiceChecker.checkInvoice(account.getId(), 2,
-                                    new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")),
+                                    callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")),
                                     // The second invoice should be adjusted for the AO (we paid for the full period) and since we paid we should also see a CBA
                                     new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-399.95")),
                                     new ExpectedItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 4, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("399.95")));
@@ -94,7 +94,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // set clock to the initial start date
         clock.setTime(initialCreationDate);
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         int invoiceItemCount = 1;
 
@@ -102,16 +102,16 @@ public class TestIntegration extends TestIntegrationBase {
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
         SubscriptionData subscription = subscriptionDataFromSubscription(createSubscriptionAndCheckForCompletion(bundle.getId(), "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // CHANGE PLAN IMMEDIATELY AND EXPECT BOTH EVENTS: NextEvent.CHANGE NextEvent.INVOICE
         //
         subscription = subscriptionDataFromSubscription(changeSubscriptionAndCheckForCompletion(subscription, "Assault-Rifle", BillingPeriod.MONTHLY, NextEvent.CHANGE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // MOVE 4 * TIME THE CLOCK
@@ -120,9 +120,9 @@ public class TestIntegration extends TestIntegrationBase {
         setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 0, 3, 45, 0, testTimeZone));
         setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
         setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
                                                                                                new LocalDate(2012, 3, 31), InvoiceItemType.RECURRING, new BigDecimal("561.25")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 31));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 31), callContext);
 
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
@@ -135,23 +135,23 @@ public class TestIntegration extends TestIntegrationBase {
         final LocalDate firstRecurringPistolDate = subscription.getChargedThroughDate().toLocalDate();
         final LocalDate secondRecurringPistolDate = firstRecurringPistolDate.plusMonths(1);
         addDaysAndCheckForCompletion(31, NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 3, 31), new LocalDate(2012, 4, 30), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate);
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 31), new LocalDate(2012, 4, 30), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate, callContext);
 
         //
         // MOVE 3 * TIME AFTER NEXT BILL CYCLE DAY AND EXPECT EVENT : NextEvent.INVOICE, NextEvent.PAYMENT
         //
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 4, 30), new LocalDate(2012, 5, 31), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 5, 31));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 30), new LocalDate(2012, 5, 31), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 5, 31), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 30));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 30), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
@@ -160,7 +160,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL);
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 31));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         log.info("TEST PASSED !");
     }
@@ -176,7 +176,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // set clock to the initial start date
         clock.setTime(initialCreationDate);
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         int invoiceItemCount = 1;
 
@@ -184,16 +184,16 @@ public class TestIntegration extends TestIntegrationBase {
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
         SubscriptionData subscription = subscriptionDataFromSubscription(createSubscriptionAndCheckForCompletion(bundle.getId(), "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // CHANGE PLAN IMMEDIATELY AND EXPECT BOTH EVENTS: NextEvent.CHANGE NextEvent.INVOICE
         //
         subscription = subscriptionDataFromSubscription(changeSubscriptionAndCheckForCompletion(subscription, "Assault-Rifle", BillingPeriod.MONTHLY, NextEvent.CHANGE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // MOVE 4 * TIME THE CLOCK
@@ -202,9 +202,9 @@ public class TestIntegration extends TestIntegrationBase {
         setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 0, 3, 45, 0, testTimeZone));
         setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
         setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
                                                                                                new LocalDate(2012, 4, 2), InvoiceItemType.RECURRING, new BigDecimal("599.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 2));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 2), callContext);
 
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
@@ -217,23 +217,23 @@ public class TestIntegration extends TestIntegrationBase {
         final LocalDate firstRecurringPistolDate = subscription.getChargedThroughDate().toLocalDate();
         final LocalDate secondRecurringPistolDate = firstRecurringPistolDate.plusMonths(1);
         addDaysAndCheckForCompletion(31, NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 4, 2), new LocalDate(2012, 5, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate);
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 2), new LocalDate(2012, 5, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate, callContext);
 
         //
         // MOVE 3 * TIME AFTER NEXT BILL CYCLE DAY AND EXPECT EVENT : NextEvent.INVOICE, NextEvent.PAYMENT
         //
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 5, 2), new LocalDate(2012, 6, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 2));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 2), new LocalDate(2012, 6, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 2), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 6, 2), new LocalDate(2012, 7, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 2));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 2), new LocalDate(2012, 7, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 2), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 7, 2), new LocalDate(2012, 8, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 2));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 7, 2), new LocalDate(2012, 8, 2), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 2), callContext);
 
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
@@ -242,7 +242,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL);
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 2));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 2), callContext);
 
         log.info("TEST PASSED !");
     }
@@ -258,7 +258,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // set clock to the initial start date
         clock.setTime(initialCreationDate);
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         int invoiceItemCount = 1;
 
@@ -266,16 +266,16 @@ public class TestIntegration extends TestIntegrationBase {
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
         SubscriptionData subscription = subscriptionDataFromSubscription(createSubscriptionAndCheckForCompletion(bundle.getId(), "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // CHANGE PLAN IMMEDIATELY AND EXPECT BOTH EVENTS: NextEvent.CHANGE NextEvent.INVOICE
         //
         subscription = subscriptionDataFromSubscription(changeSubscriptionAndCheckForCompletion(subscription, "Assault-Rifle", BillingPeriod.MONTHLY, NextEvent.CHANGE, NextEvent.INVOICE));
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday());
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
         //
         // MOVE 4 * TIME THE CLOCK
@@ -285,14 +285,14 @@ public class TestIntegration extends TestIntegrationBase {
         setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
         setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
         // PRO_RATION
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
                                                                                                new LocalDate(2012, 3, 3), InvoiceItemType.RECURRING, new BigDecimal("20.70")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 3));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 3), callContext);
 
         setDateAndCheckForCompletion(new DateTime(2012, 3, 3, 0, 3, 45, 0, testTimeZone), NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 3, 3),
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 3),
                                                                                                new LocalDate(2012, 4, 3), InvoiceItemType.RECURRING, new BigDecimal("599.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 3));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 3), callContext);
 
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
@@ -305,23 +305,23 @@ public class TestIntegration extends TestIntegrationBase {
         final LocalDate firstRecurringPistolDate = subscription.getChargedThroughDate().toLocalDate();
         final LocalDate secondRecurringPistolDate = firstRecurringPistolDate.plusMonths(1);
         addDaysAndCheckForCompletion(31, NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 4, 3), new LocalDate(2012, 5, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate);
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 4, 3), new LocalDate(2012, 5, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), secondRecurringPistolDate, callContext);
 
         //
         // MOVE 3 * TIME AFTER NEXT BILL CYCLE DAY AND EXPECT EVENT : NextEvent.INVOICE, NextEvent.PAYMENT
         //
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 5, 3), new LocalDate(2012, 6, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 3));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 5, 3), new LocalDate(2012, 6, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 6, 3), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 6, 3), new LocalDate(2012, 7, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 3));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 6, 3), new LocalDate(2012, 7, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 7, 3), callContext);
 
         addDaysAndCheckForCompletion(31, NextEvent.INVOICE, NextEvent.PAYMENT);
-        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, new ExpectedItemCheck(new LocalDate(2012, 7, 3), new LocalDate(2012, 8, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 3));
+        invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 7, 3), new LocalDate(2012, 8, 3), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 3), callContext);
 
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
@@ -330,7 +330,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL);
-        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 3));
+        invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 8, 3), callContext);
 
         log.info("TEST PASSED !");
 
@@ -388,7 +388,7 @@ public class TestIntegration extends TestIntegrationBase {
         final Account account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -397,7 +397,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                         new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                         new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
@@ -411,7 +411,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                               new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+                                                                               new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, callContext));
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
@@ -419,7 +419,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         final SubscriptionData aoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                        new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+                                                                                                                        new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, callContext));
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
@@ -471,21 +471,21 @@ public class TestIntegration extends TestIntegrationBase {
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0, testTimeZone);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "someBundle", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "someBundle", callContext);
         assertNotNull(bundle);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
         final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
         entitlementUserApi.createSubscription(bundle.getId(),
-                                              new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context);
+                                              new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext);
 
         busHandler.reset();
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         assertEquals(invoices.size(), 1);
 
         // TODO: Jeff implement repair
@@ -503,7 +503,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // set clock to the initial start date
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever2", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever2", callContext);
 
         String productName = "Shotgun";
         BillingPeriod term = BillingPeriod.MONTHLY;
@@ -516,7 +516,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
 
         SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                               new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                               new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
 
         assertNotNull(subscription);
         assertTrue(busHandler.isCompleted(DELAY));
@@ -538,8 +538,8 @@ public class TestIntegration extends TestIntegrationBase {
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscription.getId()));
-        subscription.cancel(clock.getUTCNow(), context);
+        subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscription.getId(), callContext));
+        subscription.cancel(clock.getUTCNow(), callContext);
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         busHandler.pushExpectedEvent(NextEvent.CANCEL);
@@ -555,7 +555,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.RE_CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        subscription.recreate(new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), endDate, context);
+        subscription.recreate(new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), endDate, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
 
         assertListenerStatus();
@@ -577,13 +577,13 @@ public class TestIntegration extends TestIntegrationBase {
 
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(accountId, "testKey", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(accountId, "testKey", callContext);
         subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                                                                                new PlanPhaseSpecifier(productName, ProductCategory.BASE,
-                                                                                                      BillingPeriod.MONTHLY, planSetName, PhaseType.TRIAL), null, context));
+                                                                                                      BillingPeriod.MONTHLY, planSetName, PhaseType.TRIAL), null, callContext));
 
         assertTrue(busHandler.isCompleted(DELAY));
-        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         assertNotNull(invoices);
         assertTrue(invoices.size() == 1);
 
@@ -592,7 +592,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
         assertTrue(busHandler.isCompleted(DELAY));
-        invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        invoices = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         assertNotNull(invoices);
         assertEquals(invoices.size(), 2);
 
@@ -610,7 +610,7 @@ public class TestIntegration extends TestIntegrationBase {
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        invoices = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         assertNotNull(invoices);
         assertEquals(invoices.size(), 8);
 
@@ -622,7 +622,7 @@ public class TestIntegration extends TestIntegrationBase {
             assertTrue(busHandler.isCompleted(DELAY));
         }
 
-        invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        invoices = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         assertNotNull(invoices);
         assertEquals(invoices.size(), 14);
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index 900e621..910895e 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -17,16 +17,13 @@
 package com.ning.billing.beatrix.integration;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
-import java.util.concurrent.Callable;
 
 import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
-import org.joda.time.Interval;
 import org.joda.time.LocalDate;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
@@ -61,17 +58,14 @@ import com.ning.billing.entitlement.api.transfer.EntitlementTransferApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
-import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.InvoiceService;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.model.InvoicingConfiguration;
-import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.plumbing.api.BlockingSubscription;
 import com.ning.billing.mock.MockAccountBuilder;
 import com.ning.billing.mock.api.MockBillCycleDay;
@@ -83,11 +77,6 @@ import com.ning.billing.payment.api.PaymentMethodPlugin;
 import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.BusService;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.ClockMock;
 
 import com.google.common.base.Function;
@@ -95,9 +84,6 @@ import com.google.common.base.Joiner;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -125,8 +111,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
     @Inject
     protected ClockMock clock;
 
-    protected CallContext context;
-
     @Inject
     protected Lifecycle lifecycle;
 
@@ -214,7 +198,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
 
     @BeforeClass(groups = "slow")
     public void setup() throws Exception {
-        context = new DefaultCallContextFactory(clock).createCallContext("Integration Test", CallOrigin.TEST, UserType.TEST);
         busHandler = new TestApiListener(this);
     }
 
@@ -246,7 +229,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             final DateTime startDate, @Nullable final DateTime endDate,
             final BigDecimal amount, final DateTime chargeThroughDate,
             final int totalInvoiceItemCount) throws EntitlementUserApiException {
-        final SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscriptionId));
+        final SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscriptionId, callContext));
 
 
         /*
@@ -288,7 +271,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
     }
 
     protected Account createAccountWithPaymentMethod(final AccountData accountData) throws Exception {
-        final Account account = accountUserApi.createAccount(accountData, context);
+        final Account account = accountUserApi.createAccount(accountData, callContext);
         assertNotNull(account);
 
         final PaymentMethodPlugin info = new PaymentMethodPlugin() {
@@ -313,8 +296,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             }
         };
 
-        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, info, context);
-        return accountUserApi.getAccountById(account.getId());
+        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, info, callContext);
+        return accountUserApi.getAccountById(account.getId(), callContext);
     }
 
     protected AccountData getAccountData(final int billingDay) {
@@ -374,7 +357,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), new DefaultCallContext("test", null, null, clock));
+                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), callContext);
                 } catch (PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -388,7 +371,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createExternalPayment(account, invoice.getId(), invoice.getBalance(), new DefaultCallContext("test", null, null, clock));
+                    paymentApi.createExternalPayment(account, invoice.getId(), invoice.getBalance(), callContext);
                 } catch (PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -402,7 +385,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createRefund(account, payment.getId(), payment.getPaidAmount(), new DefaultCallContext("test", null, null, clock));
+                    paymentApi.createRefund(account, payment.getId(), payment.getPaidAmount(), callContext);
                 } catch (PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -416,7 +399,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    invoicePaymentApi.createChargeback(payment.getId(), payment.getAmount(), new DefaultCallContext("test", null, null, clock));
+                    invoicePaymentApi.createChargeback(payment.getId(), payment.getAmount(), callContext);
                 } catch (InvoiceApiException e) {
                     fail(e.toString());
                 }
@@ -437,7 +420,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
                     final Subscription subscription = entitlementUserApi.createSubscription(bundleId,
                             new PlanPhaseSpecifier(productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null),
                             null,
-                            context);
+                            callContext);
                     assertNotNull(subscription);
                     return subscription;
                 } catch (EntitlementUserApiException e) {
@@ -457,8 +440,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             public Subscription apply(@Nullable final Void dontcare) {
                 try {
                     // Need to fetch again to get latest CTD updated from the system
-                    final Subscription refreshedSubscription = entitlementUserApi.getSubscriptionFromId(subscription.getId());
-                    refreshedSubscription.changePlan(productName, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), context);
+                    final Subscription refreshedSubscription = entitlementUserApi.getSubscriptionFromId(subscription.getId(), callContext);
+                    refreshedSubscription.changePlan(productName, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), callContext);
                     return refreshedSubscription;
                 } catch (EntitlementUserApiException e) {
                     fail(e.getMessage());
@@ -476,8 +459,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             public Subscription apply(@Nullable final Void dontcare) {
                 try {
                     // Need to fetch again to get latest CTD updated from the system
-                    final Subscription refreshedSubscription = entitlementUserApi.getSubscriptionFromId(subscription.getId());
-                    refreshedSubscription.cancel(requestedDate, context);
+                    final Subscription refreshedSubscription = entitlementUserApi.getSubscriptionFromId(subscription.getId(), callContext);
+                    refreshedSubscription.cancel(requestedDate, callContext);
                     return refreshedSubscription;
                 } catch (EntitlementUserApiException e) {
                     fail();
@@ -493,7 +476,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             public Void apply(@Nullable final Void input) {
                 try {
                     invoiceUserApi.insertCreditForInvoice(account.getId(), invoice.getId(), invoice.getBalance(), invoice.getInvoiceDate(),
-                                                          account.getCurrency(), new DefaultCallContext("test", null, null, clock));
+                                                          account.getCurrency(), callContext);
                 } catch (InvoiceApiException e) {
                     fail(e.toString());
                 }
@@ -508,7 +491,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             public Void apply(@Nullable final Void input) {
                 try {
                     invoiceUserApi.insertInvoiceItemAdjustment(account.getId(), invoice.getId(), invoice.getInvoiceItems().get(itemNb - 1).getId(),
-                                                               invoice.getInvoiceDate(), new DefaultCallContext("test", null, null, clock));
+                                                               invoice.getInvoiceDate(), callContext);
                 } catch (InvoiceApiException e) {
                     fail(e.toString());
                 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
index eabcf09..103145e 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
@@ -25,7 +25,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -42,7 +41,8 @@ import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
+
+import com.google.inject.Inject;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -69,7 +69,7 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
-        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         productName = "Shotgun";
         term = BillingPeriod.MONTHLY;
@@ -84,32 +84,32 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         // set next invoice to fail and create network
         busHandler.pushExpectedEvents(NextEvent.CREATE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 0);
 
         clock.addDays(10); // DAY 10 still in trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 0);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE);
         clock.addDays(30); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 0);
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
         remove_AUTO_INVOICING_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1);
     }
 
@@ -120,11 +120,11 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         // set next invoice to fail and create network
         busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1); // first invoice is generated immediately after creation can't reliably stop it
 
 
@@ -134,7 +134,7 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         clock.addDays(40); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1); //No additional invoices generated
 
     }
@@ -147,19 +147,19 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         // set next invoice to fail and create network
         busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        final SubscriptionBundle bundle2 = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle2 = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
         final SubscriptionData baseSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle2.getId(),
-                                                                                                                    new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                    new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription2);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2); // first invoice is generated immediately after creation can't reliably stop it
 
         add_AUTO_INVOICING_OFF_Tag(baseSubscription.getBundleId(), ObjectType.BUNDLE);
@@ -168,19 +168,19 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         clock.addDays(40); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 3); // Only one additional invoice generated
     }
 
 
     private void add_AUTO_INVOICING_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
-        tagApi.addTag(id, type, ControlTagType.AUTO_INVOICING_OFF.getId(), context);
-        final Map<String, Tag> tags = tagApi.getTags(id, type);
+        tagApi.addTag(id, type, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
+        final Map<String, Tag> tags = tagApi.getTags(id, type, callContext);
         assertEquals(tags.size(), 1);
     }
 
 
     private void remove_AUTO_INVOICING_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
-        tagApi.removeTag(id, type, ControlTagType.AUTO_INVOICING_OFF.getId(), context);
+        tagApi.removeTag(id, type, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
     }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
index f83725d..31688f8 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
@@ -15,10 +15,6 @@
  */
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.Map;
@@ -29,7 +25,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -48,6 +43,12 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 
+import com.google.inject.Inject;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 @Guice(modules = {BeatrixModule.class})
 public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
@@ -75,7 +76,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
-        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         productName = "Shotgun";
         term = BillingPeriod.MONTHLY;
@@ -90,11 +91,11 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
         busHandler.pushExpectedEvents(NextEvent.CREATE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE);
@@ -103,7 +104,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -117,7 +118,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -138,11 +139,11 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
         busHandler.pushExpectedEvents(NextEvent.CREATE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE);
@@ -151,7 +152,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -165,7 +166,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.PAYMENT_ERROR);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -182,7 +183,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         clock.addDays(nbDaysBeforeRetry + 1);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
                 continue;
@@ -203,11 +204,11 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
         busHandler.pushExpectedEvents(NextEvent.CREATE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 1);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE);
@@ -216,7 +217,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -230,7 +231,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.PAYMENT_ERROR);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         assertEquals(invoices.size(), 2);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -264,7 +265,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
 
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
         for (Invoice cur : invoices) {
             if (cur.getChargedAmount().compareTo(BigDecimal.ZERO) == 0) {
                 continue;
@@ -278,13 +279,13 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
 
 
     private void add_AUTO_PAY_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
-        tagApi.addTag(id, type, ControlTagType.AUTO_PAY_OFF.getId(), context);
-        final Map<String, Tag> tags = tagApi.getTags(id, type);
+        tagApi.addTag(id, type, ControlTagType.AUTO_PAY_OFF.getId(), callContext);
+        final Map<String, Tag> tags = tagApi.getTags(id, type, callContext);
         assertEquals(tags.size(), 1);
     }
 
     private void remove_AUTO_PAY_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
-        tagApi.removeTag(id, type, ControlTagType.AUTO_PAY_OFF.getId(), context);
+        tagApi.removeTag(id, type, ControlTagType.AUTO_PAY_OFF.getId(), callContext);
     }
 }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
index b349782..a68afe6 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
@@ -73,7 +73,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
 
         final Account account = createAccountWithPaymentMethod(getAccountData(25));
 
-        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -82,7 +82,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, callContext));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
@@ -94,14 +94,14 @@ public class TestRepairIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         final SubscriptionData aoSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                 new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+                                                                                                                 new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, callContext));
         assertTrue(busHandler.isCompleted(DELAY));
 
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         final SubscriptionData aoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                                                                                                  new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+                                                                                                                  new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, callContext));
         assertTrue(busHandler.isCompleted(DELAY));
 
 
@@ -121,7 +121,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
         }
         final boolean ifRepair = false;
         if (ifRepair) {
-            BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+            BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
             sortEventsOnBundle(bundleRepair);
 
             // Quick check
@@ -150,21 +150,21 @@ public class TestRepairIntegration extends TestIntegrationBase {
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
             busHandler.pushExpectedEvent(NextEvent.PAYMENT);
             busHandler.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-            repairApi.repairBundle(bundleRepair, false, context);
+            repairApi.repairBundle(bundleRepair, false, callContext);
             assertTrue(busHandler.isCompleted(DELAY));
 
-            final SubscriptionData newAoSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription.getId()));
+            final SubscriptionData newAoSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription.getId(), callContext));
             assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
             assertEquals(newAoSubscription.getAllTransitions().size(), 2);
             assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-            final SubscriptionData newAoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription2.getId()));
+            final SubscriptionData newAoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription2.getId(), callContext));
             assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
             assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
             assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
 
-            final SubscriptionData newBaseSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(baseSubscription.getId()));
+            final SubscriptionData newBaseSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(baseSubscription.getId(), callContext));
             assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
             assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
index e3cca6f..4af8df7 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.beatrix.util;
 
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
@@ -33,8 +28,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 
-import com.google.common.collect.ImmutableList;
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -43,6 +36,15 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 public class InvoiceChecker {
 
@@ -57,37 +59,37 @@ public class InvoiceChecker {
         this.entitlementApi = entitlementApi;
     }
 
-    public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final ExpectedItemCheck... expected) throws InvoiceApiException {
-        checkInvoice(accountId, invoiceOrderingNumber, ImmutableList.<ExpectedItemCheck>copyOf(expected));
+    public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final TenantContext context, final ExpectedItemCheck... expected) throws InvoiceApiException {
+        checkInvoice(accountId, invoiceOrderingNumber, context, ImmutableList.<ExpectedItemCheck>copyOf(expected));
     }
 
-    public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
-        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+    public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final TenantContext context, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId, context);
         Assert.assertEquals(invoices.size(), invoiceOrderingNumber);
         final Invoice invoice = invoices.get(invoiceOrderingNumber - 1);
-        checkInvoice(invoice.getId(), expected);
+        checkInvoice(invoice.getId(), context, expected);
     }
 
-    public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final ExpectedItemCheck... expected) throws InvoiceApiException {
-        checkRepairedInvoice(accountId, invoiceNb, ImmutableList.<ExpectedItemCheck>copyOf(expected));
+    public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final TenantContext context, final ExpectedItemCheck... expected) throws InvoiceApiException {
+        checkRepairedInvoice(accountId, invoiceNb, context, ImmutableList.<ExpectedItemCheck>copyOf(expected));
     }
 
-    public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
-        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+    public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final TenantContext context, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId, context);
         Assert.assertTrue(invoices.size() > invoiceNb);
         final Invoice invoice = invoices.get(invoiceNb - 1);
-        checkInvoice(invoice.getId(), expected);
+        checkInvoice(invoice.getId(), context, expected);
     }
 
-    public void checkInvoice(final UUID invoiceId, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
-        final Invoice invoice = invoiceUserApi.getInvoice(invoiceId);
+    public void checkInvoice(final UUID invoiceId, final TenantContext context, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
+        final Invoice invoice = invoiceUserApi.getInvoice(invoiceId, context);
         Assert.assertNotNull(invoice);
 
         final List<InvoiceItem> actual = invoice.getInvoiceItems();
         Assert.assertEquals(expected.size(), actual.size());
-        for (ExpectedItemCheck cur : expected) {
+        for (final ExpectedItemCheck cur : expected) {
             boolean found = false;
-            for (InvoiceItem in : actual) {
+            for (final InvoiceItem in : actual) {
                 // Match first on type and start date
                 if (in.getInvoiceItemType() != cur.getType() || (in.getStartDate().compareTo(cur.getStartDate()) != 0)) {
                     continue;
@@ -113,13 +115,13 @@ public class InvoiceChecker {
         }
     }
 
-    public void checkNullChargedThroughDate(final UUID subscriptionId) {
-        checkChargedThroughDate(subscriptionId, null);
+    public void checkNullChargedThroughDate(final UUID subscriptionId, final TenantContext context) {
+        checkChargedThroughDate(subscriptionId, null, context);
     }
 
-    public void checkChargedThroughDate(final UUID subscriptionId, final LocalDate expectedLocalCTD) {
+    public void checkChargedThroughDate(final UUID subscriptionId, final LocalDate expectedLocalCTD, final TenantContext context) {
         try {
-            Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId);
+            final Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId, context);
             if (expectedLocalCTD == null) {
                 assertNull(subscription.getChargedThroughDate());
             } else {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
index 9283768..b30c6a1 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
@@ -16,10 +16,8 @@
 
 package com.ning.billing.entitlement.alignment;
 
-
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Duration;
@@ -33,6 +31,8 @@ import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Inject;
+
 public class MigrationPlanAligner {
 
     private final CatalogService catalogService;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index 534160a..b77e19e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -16,14 +16,14 @@
 
 package com.ning.billing.entitlement.alignment;
 
-import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -43,6 +43,8 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Inject;
+
 /**
  * PlanAligner offers specific APIs to return the correct {@code TimedPhase} when creating, changing Plan or to compute
  * next Phase on current Plan.
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
index c0c06a5..145a06e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
@@ -23,36 +23,42 @@ import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.joda.time.LocalTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.inject.Inject;
 
 public class DefaultChargeThruApi implements ChargeThruApi {
+
     private final EntitlementDao entitlementDao;
     private final SubscriptionFactory subscriptionFactory;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultChargeThruApi(final SubscriptionFactory subscriptionFactory, final EntitlementDao dao) {
-        super();
+    public DefaultChargeThruApi(final SubscriptionFactory subscriptionFactory, final EntitlementDao dao, final InternalCallContextFactory internalCallContextFactory) {
         this.subscriptionFactory = subscriptionFactory;
         this.entitlementDao = dao;
+        // TODO remove - internal API, should use InternalCallContext directly
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
-        return entitlementDao.getAccountIdFromSubscriptionId(subscriptionId);
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final TenantContext context) {
+        return entitlementDao.getAccountIdFromSubscriptionId(subscriptionId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
     public void setChargedThroughDate(final UUID subscriptionId, final LocalDate ctd, final CallContext context) {
-        final SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
+        final SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionFactory, subscriptionId, internalCallContextFactory.createInternalCallContext(context));
         final DateTime chargedThroughDate = ctd.toDateTime(new LocalTime(subscription.getStartDate(), DateTimeZone.UTC), DateTimeZone.UTC);
         final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
                 .setChargedThroughDate(chargedThroughDate)
                 .setPaidThroughDate(subscription.getPaidThroughDate());
-        entitlementDao.updateChargedThroughDate(new SubscriptionData(builder), context);
+        entitlementDao.updateChargedThroughDate(new SubscriptionData(builder), internalCallContextFactory.createInternalCallContext(context));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
index 4949d4b..a6eb3d9 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
@@ -24,7 +24,6 @@ import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.Subscrip
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
-import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
 
 public class AccountMigrationData {
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
index 1ea22b7..a2f83ad 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
@@ -25,8 +25,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.common.collect.Lists;
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.alignment.MigrationPlanAligner;
 import com.ning.billing.entitlement.alignment.TimedMigration;
@@ -50,30 +48,38 @@ import com.ning.billing.entitlement.events.user.ApiEventMigrateEntitlement;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+
 public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
+
     private final EntitlementDao dao;
     private final MigrationPlanAligner migrationAligner;
     private final SubscriptionFactory factory;
     private final Clock clock;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultEntitlementMigrationApi(final MigrationPlanAligner migrationAligner,
                                           final SubscriptionFactory factory,
                                           final EntitlementDao dao,
-                                          final Clock clock) {
+                                          final Clock clock,
+                                          final InternalCallContextFactory internalCallContextFactory) {
         this.dao = dao;
         this.migrationAligner = migrationAligner;
         this.factory = factory;
         this.clock = clock;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
     public void migrate(final EntitlementAccountMigration toBeMigrated, final CallContext context)
             throws EntitlementMigrationApiException {
         final AccountMigrationData accountMigrationData = createAccountMigrationData(toBeMigrated, context);
-        dao.migrate(toBeMigrated.getAccountKey(), accountMigrationData, context);
+        dao.migrate(toBeMigrated.getAccountKey(), accountMigrationData, internalCallContextFactory.createInternalCallContext(context));
     }
 
     private AccountMigrationData createAccountMigrationData(final EntitlementAccountMigration toBeMigrated, final CallContext context)
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
index 5e8cb20..810c2fb 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
@@ -27,8 +27,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
@@ -46,12 +44,20 @@ import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
 
 public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
+
     private final EntitlementDao dao;
     private final SubscriptionFactory factory;
     private final RepairEntitlementLifecycleDao repairDao;
     private final CatalogService catalogService;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private enum RepairType {
         BASE_REPAIR,
@@ -61,41 +67,41 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
     @Inject
     public DefaultEntitlementTimelineApi(@Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionFactory factory, final CatalogService catalogService,
-            @Named(DefaultEntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao) {
+                                         @Named(DefaultEntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao,
+                                         final InternalCallContextFactory internalCallContextFactory) {
         this.catalogService = catalogService;
         this.dao = dao;
         this.repairDao = repairDao;
         this.factory = factory;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public BundleTimeline getBundleTimeline(final SubscriptionBundle bundle)
-    throws EntitlementRepairException {
-        return getBundleTimelineInternal(bundle, bundle.getKey());
+    public BundleTimeline getBundleTimeline(final SubscriptionBundle bundle, final TenantContext context)
+            throws EntitlementRepairException {
+        return getBundleTimelineInternal(bundle, bundle.getKey(), context);
     }
 
-
     @Override
-    public BundleTimeline getBundleTimeline(final UUID accountId, final String bundleName)
-    throws EntitlementRepairException {
-        final SubscriptionBundle bundle = dao.getSubscriptionBundleFromAccountAndKey(accountId, bundleName);
-        return getBundleTimelineInternal(bundle, bundleName + " [accountId= " + accountId.toString() +"]");
+    public BundleTimeline getBundleTimeline(final UUID accountId, final String bundleName, final TenantContext context)
+            throws EntitlementRepairException {
+        final SubscriptionBundle bundle = dao.getSubscriptionBundleFromAccountAndKey(accountId, bundleName, internalCallContextFactory.createInternalTenantContext(accountId, context));
+        return getBundleTimelineInternal(bundle, bundleName + " [accountId= " + accountId.toString() + "]", context);
     }
 
-
     @Override
-    public BundleTimeline getBundleTimeline(final UUID bundleId) throws EntitlementRepairException {
+    public BundleTimeline getBundleTimeline(final UUID bundleId, final TenantContext context) throws EntitlementRepairException {
 
-        final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
-        return getBundleTimelineInternal(bundle, bundleId.toString());
+        final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId, internalCallContextFactory.createInternalTenantContext(context));
+        return getBundleTimelineInternal(bundle, bundleId.toString(), context);
     }
 
-    private BundleTimeline getBundleTimelineInternal(final SubscriptionBundle bundle, String descBundle) throws EntitlementRepairException {
+    private BundleTimeline getBundleTimelineInternal(final SubscriptionBundle bundle, final String descBundle, final TenantContext context) throws EntitlementRepairException {
         try {
             if (bundle == null) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, descBundle);
             }
-            final List<Subscription> subscriptions = dao.getSubscriptions(factory, bundle.getId());
+            final List<Subscription> subscriptions = dao.getSubscriptions(factory, bundle.getId(), internalCallContextFactory.createInternalTenantContext(context));
             if (subscriptions.size() == 0) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, bundle.getId());
             }
@@ -107,17 +113,17 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
-
     @Override
     public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context) throws EntitlementRepairException {
+        final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(context);
         try {
-            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getBundleId());
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getBundleId(), tenantContext);
             if (bundle == null) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, input.getBundleId());
             }
 
             // Subscriptions are ordered with BASE subscription first-- if exists
-            final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getBundleId());
+            final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getBundleId(), tenantContext);
             if (subscriptions.size() == 0) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, input.getBundleId());
             }
@@ -143,8 +149,8 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                     final List<EntitlementEvent> remaining = getRemainingEventsAndValidateDeletedEvents(curInputRepair, firstDeletedBPEventTime, curRepair.getDeletedEvents());
 
                     final boolean isPlanRecreate = (curRepair.getNewEvents().size() > 0
-                            && (curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.CREATE
-                                    || curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.RE_CREATE));
+                                                    && (curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.CREATE
+                                                        || curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.RE_CREATE));
 
                     final DateTime newSubscriptionStartDate = isPlanRecreate ? curRepair.getNewEvents().get(0).getRequestedDate() : null;
 
@@ -172,7 +178,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                     }
 
                     final SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair(curInputRepair, newBundleStartDate, newSubscriptionStartDate, remaining);
-                    repairDao.initializeRepair(curInputRepair.getId(), remaining);
+                    repairDao.initializeRepair(curInputRepair.getId(), remaining, tenantContext);
                     inRepair.add(curOutputRepair);
                     if (curOutputRepair.getCategory() == ProductCategory.ADD_ON) {
                         // Check if ADD_ON RE_CREATE is before BP start
@@ -188,25 +194,25 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
             final RepairType repairType = getRepairType(subscriptions.get(0), (baseSubscriptionRepair != null));
             switch (repairType) {
-            case BASE_REPAIR:
-                // We need to add any existing addon that are not in the input repair list
-                for (final Subscription cur : subscriptions) {
-                    if (cur.getCategory() == ProductCategory.ADD_ON && !inRepair.contains(cur)) {
-                        final SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair((SubscriptionDataRepair) cur, newBundleStartDate, null, ((SubscriptionDataRepair) cur).getEvents());
-                        repairDao.initializeRepair(curOutputRepair.getId(), ((SubscriptionDataRepair) cur).getEvents());
-                        inRepair.add(curOutputRepair);
-                        addOnSubscriptionInRepair.add(curOutputRepair);
+                case BASE_REPAIR:
+                    // We need to add any existing addon that are not in the input repair list
+                    for (final Subscription cur : subscriptions) {
+                        if (cur.getCategory() == ProductCategory.ADD_ON && !inRepair.contains(cur)) {
+                            final SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair((SubscriptionDataRepair) cur, newBundleStartDate, null, ((SubscriptionDataRepair) cur).getEvents());
+                            repairDao.initializeRepair(curOutputRepair.getId(), ((SubscriptionDataRepair) cur).getEvents(), tenantContext);
+                            inRepair.add(curOutputRepair);
+                            addOnSubscriptionInRepair.add(curOutputRepair);
+                        }
                     }
-                }
-                break;
-            case ADD_ON_REPAIR:
-                // We need to set the baseSubscription as it is useful to calculate addon validity
-                final SubscriptionDataRepair baseSubscription = (SubscriptionDataRepair) subscriptions.get(0);
-                baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getAlignStartDate(), baseSubscription.getEvents());
-                break;
-            case STANDALONE_REPAIR:
-            default:
-                break;
+                    break;
+                case ADD_ON_REPAIR:
+                    // We need to set the baseSubscription as it is useful to calculate addon validity
+                    final SubscriptionDataRepair baseSubscription = (SubscriptionDataRepair) subscriptions.get(0);
+                    baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getAlignStartDate(), baseSubscription.getEvents());
+                    break;
+                case STANDALONE_REPAIR:
+                default:
+                    break;
             }
 
             validateBasePlanRecreate(isBasePlanRecreate, subscriptions, input.getSubscriptions());
@@ -228,13 +234,13 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                 final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, convertDataRepair(inRepair));
                 return createGetBundleRepair(input.getBundleId(), bundle.getKey(), input.getViewId(), repairs);
             } else {
-                dao.repair(bundle.getAccountId(), input.getBundleId(), inRepair, context);
-                return getBundleTimeline(input.getBundleId());
+                dao.repair(bundle.getAccountId(), input.getBundleId(), inRepair, internalCallContextFactory.createInternalCallContext(context));
+                return getBundleTimeline(input.getBundleId(), context);
             }
         } catch (CatalogApiException e) {
             throw new EntitlementRepairException(e);
         } finally {
-            repairDao.cleanup();
+            repairDao.cleanup(tenantContext);
         }
     }
 
@@ -247,7 +253,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
     private void validateBasePlanRecreate(final boolean isBasePlanRecreate, final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
-    throws EntitlementRepairException {
+            throws EntitlementRepairException {
         if (!isBasePlanRecreate) {
             return;
         }
@@ -256,15 +262,15 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
         for (final SubscriptionTimeline cur : input) {
             if (cur.getNewEvents().size() != 0
-                    && (cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.CREATE
-                            && cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.RE_CREATE)) {
+                && (cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.CREATE
+                    && cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.RE_CREATE)) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE, subscriptions.get(0).getBundleId());
             }
         }
     }
 
     private void validateInputSubscriptionsKnown(final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
-    throws EntitlementRepairException {
+            throws EntitlementRepairException {
         for (final SubscriptionTimeline cur : input) {
             boolean found = false;
             for (final Subscription s : subscriptions) {
@@ -280,13 +286,13 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
     private void validateFirstNewEvent(final SubscriptionData data, final NewEvent firstNewEvent, final DateTime lastBPRemainingTime, final DateTime lastRemainingTime)
-    throws EntitlementRepairException {
+            throws EntitlementRepairException {
         if (lastBPRemainingTime != null &&
-                firstNewEvent.getRequestedDate().isBefore(lastBPRemainingTime)) {
+            firstNewEvent.getRequestedDate().isBefore(lastBPRemainingTime)) {
             throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING, firstNewEvent.getSubscriptionTransitionType(), data.getId());
         }
         if (lastRemainingTime != null &&
-                firstNewEvent.getRequestedDate().isBefore(lastRemainingTime)) {
+            firstNewEvent.getRequestedDate().isBefore(lastRemainingTime)) {
             throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING, firstNewEvent.getSubscriptionTransitionType(), data.getId());
         }
 
@@ -309,7 +315,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
     private List<EntitlementEvent> getRemainingEventsAndValidateDeletedEvents(final SubscriptionDataRepair data, final DateTime firstBPDeletedTime,
-            final List<SubscriptionTimeline.DeletedEvent> deletedEvents)
+                                                                              final List<SubscriptionTimeline.DeletedEvent> deletedEvents)
             throws EntitlementRepairException {
         if (deletedEvents == null || deletedEvents.size() == 0) {
             return data.getEvents();
@@ -331,8 +337,8 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_INVALID_DELETE_SET, cur.getId(), data.getId());
             }
             if (firstBPDeletedTime != null &&
-                    !cur.getEffectiveDate().isBefore(firstBPDeletedTime) &&
-                    !foundDeletedEvent) {
+                !cur.getEffectiveDate().isBefore(firstBPDeletedTime) &&
+                !foundDeletedEvent) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT, cur.getId(), data.getId());
             }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
index 0cc98bf..2090dc4 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
@@ -13,16 +13,18 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.entitlement.api.timeline;
 
 import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface RepairEntitlementLifecycleDao {
 
-    public void initializeRepair(final UUID subscriptionId, final List<EntitlementEvent> initialEvents);
+    public void initializeRepair(UUID subscriptionId, List<EntitlementEvent> initialEvents, InternalTenantContext context);
 
-    public void cleanup();
+    public void cleanup(InternalTenantContext context);
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
index 37078d5..1870bfe 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
@@ -13,24 +13,29 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.entitlement.api.timeline;
 
+package com.ning.billing.entitlement.api.timeline;
 
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.alignment.PlanAligner;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionApiService;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
 public class RepairSubscriptionApiService extends DefaultSubscriptionApiService implements SubscriptionApiService {
 
     @Inject
-    public RepairSubscriptionApiService(final Clock clock, @Named(DefaultEntitlementModule.REPAIR_NAMED) final EntitlementDao dao,
-                                        final CatalogService catalogService, final PlanAligner planAligner) {
-        super(clock, dao, catalogService, planAligner);
+    public RepairSubscriptionApiService(final Clock clock,
+                                        @Named(DefaultEntitlementModule.REPAIR_NAMED) final EntitlementDao dao,
+                                        final CatalogService catalogService,
+                                        final PlanAligner planAligner,
+                                        final InternalCallContextFactory internalCallContextFactory) {
+        super(clock, dao, catalogService, planAligner, internalCallContextFactory);
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
index f0cafe6..f32a211 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
@@ -18,8 +18,6 @@ package com.ning.billing.entitlement.api.timeline;
 
 import java.util.List;
 
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
@@ -29,25 +27,36 @@ import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
 public class RepairSubscriptionFactory extends DefaultSubscriptionFactory implements SubscriptionFactory {
+
     private final AddonUtils addonUtils;
     private final EntitlementDao repairDao;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public RepairSubscriptionFactory(@Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionApiService apiService,
                                      @Named(DefaultEntitlementModule.REPAIR_NAMED) final EntitlementDao dao,
-                                     final Clock clock, final CatalogService catalogService, final AddonUtils addonUtils) {
+                                     final Clock clock,
+                                     final CatalogService catalogService,
+                                     final AddonUtils addonUtils,
+                                     final InternalCallContextFactory internalCallContextFactory) {
         super(apiService, clock, catalogService);
         this.addonUtils = addonUtils;
         this.repairDao = dao;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
     public SubscriptionData createSubscription(final SubscriptionBuilder builder,
                                                final List<EntitlementEvent> events) {
-        final SubscriptionData subscription = new SubscriptionDataRepair(builder, events, getApiService(), repairDao, getClock(), addonUtils, getCatalogService());
+        final SubscriptionData subscription = new SubscriptionDataRepair(builder, events, getApiService(), repairDao, getClock(),
+                                                                         addonUtils, getCatalogService(), internalCallContextFactory);
         subscription.rebuildTransitions(events, getCatalogService().getFullCatalog());
         return subscription;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
index 87c71f8..e2adbff 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
@@ -22,8 +22,6 @@ import java.util.List;
 
 import org.joda.time.DateTime;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -45,27 +43,34 @@ import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCancel;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+
 public class SubscriptionDataRepair extends SubscriptionData {
+
     private final AddonUtils addonUtils;
     private final Clock clock;
     private final EntitlementDao repairDao;
     private final CatalogService catalogService;
-
     private final List<EntitlementEvent> initialEvents;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     // Low level events are ONLY used for Repair APIs
     private List<EntitlementEvent> events;
 
     public SubscriptionDataRepair(final SubscriptionBuilder builder, final List<EntitlementEvent> initialEvents, final SubscriptionApiService apiService,
-                                  final EntitlementDao dao, final Clock clock, final AddonUtils addonUtils, final CatalogService catalogService) {
+                                  final EntitlementDao dao, final Clock clock, final AddonUtils addonUtils, final CatalogService catalogService,
+                                  final InternalCallContextFactory internalCallContextFactory) {
         super(builder, apiService, clock);
         this.repairDao = dao;
         this.addonUtils = addonUtils;
         this.clock = clock;
         this.catalogService = catalogService;
         this.initialEvents = initialEvents;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     DateTime getLastUserEventEffectiveDate() {
@@ -125,7 +130,7 @@ public class SubscriptionDataRepair extends SubscriptionData {
             return;
         }
         final Product baseProduct = (pendingTransition.getTransitionType() == SubscriptionTransitionType.CANCEL) ? null :
-                pendingTransition.getNextPlan().getProduct();
+                                    pendingTransition.getNextPlan().getProduct();
 
         addAddonCancellationIfRequired(addOnSubscriptionInRepair, baseProduct, pendingTransition.getEffectiveTransitionTime(), context);
     }
@@ -138,24 +143,25 @@ public class SubscriptionDataRepair extends SubscriptionData {
         }
 
         final Product baseProduct = (getState() == SubscriptionState.CANCELLED) ?
-                null : getCurrentPlan().getProduct();
+                                    null : getCurrentPlan().getProduct();
         addAddonCancellationIfRequired(addOnSubscriptionInRepair, baseProduct, effectiveDate, context);
     }
 
-    private void addAddonCancellationIfRequired(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, final Product baseProduct, final DateTime effectiveDate, final CallContext context) {
+    private void addAddonCancellationIfRequired(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, final Product baseProduct,
+                                                final DateTime effectiveDate, final CallContext context) {
 
         final DateTime now = clock.getUTCNow();
         final Iterator<SubscriptionDataRepair> it = addOnSubscriptionInRepair.iterator();
         while (it.hasNext()) {
             final SubscriptionDataRepair cur = it.next();
             if (cur.getState() == SubscriptionState.CANCELLED ||
-                    cur.getCategory() != ProductCategory.ADD_ON) {
+                cur.getCategory() != ProductCategory.ADD_ON) {
                 continue;
             }
             final Plan addonCurrentPlan = cur.getCurrentPlan();
             if (baseProduct == null ||
-                    addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
-                    !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
+                addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
+                !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
 
                 final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
                                                                                 .setSubscriptionId(cur.getId())
@@ -165,8 +171,8 @@ public class SubscriptionDataRepair extends SubscriptionData {
                                                                                 .setRequestedDate(now)
                                                                                 .setUserToken(context.getUserToken())
                                                                                 .setFromDisk(true));
-                repairDao.cancelSubscription(cur, cancelEvent, context, 0);
-                cur.rebuildTransitions(repairDao.getEventsForSubscription(cur.getId()), catalogService.getFullCatalog());
+                repairDao.cancelSubscription(cur, cancelEvent, internalCallContextFactory.createInternalCallContext(context), 0);
+                cur.rebuildTransitions(repairDao.getEventsForSubscription(cur.getId(), internalCallContextFactory.createInternalTenantContext(context)), catalogService.getFullCatalog());
             }
         }
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
index bacb6f6..a2da70a 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
@@ -13,8 +13,8 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.entitlement.api.transfer;
 
+package com.ning.billing.entitlement.api.transfer;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -22,18 +22,14 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.common.collect.ImmutableList;
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
-import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
-import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.SubscriptionMigrationData;
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
@@ -41,101 +37,101 @@ import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
 import com.ning.billing.entitlement.api.timeline.EntitlementTimelineApi;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.ExistingEvent;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEventData;
 import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCancel;
 import com.ning.billing.entitlement.events.user.ApiEventChange;
-import com.ning.billing.entitlement.events.user.ApiEventCreate;
 import com.ning.billing.entitlement.events.user.ApiEventTransfer;
-
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
-public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
 
+public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
 
     private final Clock clock;
     private final EntitlementDao dao;
     private final CatalogService catalogService;
     private final SubscriptionFactory subscriptionFactory;
     private final EntitlementTimelineApi timelineApi;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultEntitlementTransferApi(final Clock clock, final EntitlementDao dao, final EntitlementTimelineApi timelineApi, final CatalogService catalogService,
-            final SubscriptionFactory subscriptionFactory) {
+                                         final SubscriptionFactory subscriptionFactory, final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.dao = dao;
         this.catalogService = catalogService;
         this.subscriptionFactory = subscriptionFactory;
         this.timelineApi = timelineApi;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
-
     private EntitlementEvent createEvent(final boolean firstEvent, final ExistingEvent existingEvent, final SubscriptionData subscription, final DateTime transferDate, final CallContext context)
-    throws CatalogApiException {
+            throws CatalogApiException {
 
         EntitlementEvent newEvent = null;
 
         final Catalog catalog = catalogService.getFullCatalog();
 
-
         final DateTime effectiveDate = existingEvent.getEffectiveDate().isBefore(transferDate) ? transferDate : existingEvent.getEffectiveDate();
 
         final PlanPhaseSpecifier spec = existingEvent.getPlanPhaseSpecifier();
         final PlanPhase currentPhase = existingEvent.getPlanPhaseName() != null ? catalog.findPhase(existingEvent.getPlanPhaseName(), effectiveDate, subscription.getAlignStartDate()) : null;
 
-
-        final ApiEventBuilder apiBuilder = currentPhase != null ?new ApiEventBuilder()
-        .setSubscriptionId(subscription.getId())
-        .setEventPlan(currentPhase.getPlan().getName())
-        .setEventPlanPhase(currentPhase.getName())
-        .setEventPriceList(spec.getPriceListName())
-        .setActiveVersion(subscription.getActiveVersion())
-        .setProcessedDate(clock.getUTCNow())
-        .setEffectiveDate(effectiveDate)
-        .setRequestedDate(effectiveDate)
-        .setUserToken(context.getUserToken())
-        .setFromDisk(true) : null;
-
-        switch(existingEvent.getSubscriptionTransitionType()) {
-        case TRANSFER:
-        case MIGRATE_ENTITLEMENT:
-        case RE_CREATE:
-        case CREATE:
-            newEvent = new ApiEventTransfer(apiBuilder);
-            break;
-
-        // Should we even keep future change events; product question really
-        case CHANGE:
-            newEvent = firstEvent ? new ApiEventTransfer(apiBuilder) : new ApiEventChange(apiBuilder);
-            break;
-
-        case PHASE:
-            newEvent = firstEvent ? new ApiEventTransfer(apiBuilder) :
-                    PhaseEventData.createNextPhaseEvent(currentPhase.getName(), subscription, clock.getUTCNow(), effectiveDate);
-            break;
-
-        // Ignore
-        case CANCEL:
-        case UNCANCEL:
-        case MIGRATE_BILLING:
-            break;
-        default:
-            throw new EntitlementError(String.format("Unepxected transitionType %s", existingEvent.getSubscriptionTransitionType()));
+        final ApiEventBuilder apiBuilder = currentPhase != null ? new ApiEventBuilder()
+                .setSubscriptionId(subscription.getId())
+                .setEventPlan(currentPhase.getPlan().getName())
+                .setEventPlanPhase(currentPhase.getName())
+                .setEventPriceList(spec.getPriceListName())
+                .setActiveVersion(subscription.getActiveVersion())
+                .setProcessedDate(clock.getUTCNow())
+                .setEffectiveDate(effectiveDate)
+                .setRequestedDate(effectiveDate)
+                .setUserToken(context.getUserToken())
+                .setFromDisk(true) : null;
+
+        switch (existingEvent.getSubscriptionTransitionType()) {
+            case TRANSFER:
+            case MIGRATE_ENTITLEMENT:
+            case RE_CREATE:
+            case CREATE:
+                newEvent = new ApiEventTransfer(apiBuilder);
+                break;
+
+            // Should we even keep future change events; product question really
+            case CHANGE:
+                newEvent = firstEvent ? new ApiEventTransfer(apiBuilder) : new ApiEventChange(apiBuilder);
+                break;
+
+            case PHASE:
+                newEvent = firstEvent ? new ApiEventTransfer(apiBuilder) :
+                           PhaseEventData.createNextPhaseEvent(currentPhase.getName(), subscription, clock.getUTCNow(), effectiveDate);
+                break;
+
+            // Ignore
+            case CANCEL:
+            case UNCANCEL:
+            case MIGRATE_BILLING:
+                break;
+            default:
+                throw new EntitlementError(String.format("Unepxected transitionType %s", existingEvent.getSubscriptionTransitionType()));
         }
         return newEvent;
     }
 
-
     private List<EntitlementEvent> toEvents(final List<ExistingEvent> existingEvents, final SubscriptionData subscription,
-            final DateTime transferDate, final CallContext context) throws EntitlementTransferApiException {
+                                            final DateTime transferDate, final CallContext context) throws EntitlementTransferApiException {
 
         try {
             final List<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
@@ -176,29 +172,29 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
                 prevEvent = null;
             }
 
-
             return result;
         } catch (CatalogApiException e) {
             throw new EntitlementTransferApiException(e);
         }
     }
 
-
     @Override
     public SubscriptionBundle transferBundle(final UUID sourceAccountId, final UUID destAccountId,
-            final String bundleKey, final DateTime transferDate, final boolean transferAddOn,
-            final boolean cancelImmediately, final CallContext context) throws EntitlementTransferApiException {
-        try {
+                                             final String bundleKey, final DateTime transferDate, final boolean transferAddOn,
+                                             final boolean cancelImmediately, final CallContext context) throws EntitlementTransferApiException {
+        // Source or destination account?
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(sourceAccountId, context);
 
+        try {
             final DateTime effectiveTransferDate = transferDate == null ? clock.getUTCNow() : transferDate;
 
-            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromAccountAndKey(sourceAccountId, bundleKey);
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromAccountAndKey(sourceAccountId, bundleKey, internalCallContext);
             if (bundle == null) {
                 throw new EntitlementTransferApiException(ErrorCode.ENT_CREATE_NO_BUNDLE, bundleKey);
             }
 
             // Get the bundle timeline for the old account
-            final BundleTimeline bundleTimeline = timelineApi.getBundleTimeline(bundle);
+            final BundleTimeline bundleTimeline = timelineApi.getBundleTimeline(bundle, context);
 
             final SubscriptionBundleData subscriptionBundleData = new SubscriptionBundleData(bundleKey, destAccountId, effectiveTransferDate);
             final List<SubscriptionMigrationData> subscriptionMigrationDataList = new LinkedList<SubscriptionMigrationData>();
@@ -207,10 +203,8 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
 
             DateTime bundleStartdate = null;
 
-
-            for (SubscriptionTimeline cur : bundleTimeline.getSubscriptions()) {
-
-                final SubscriptionData oldSubscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, cur.getId());
+            for (final SubscriptionTimeline cur : bundleTimeline.getSubscriptions()) {
+                final SubscriptionData oldSubscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, cur.getId(), internalCallContext);
                 final List<ExistingEvent> existingEvents = cur.getExistingEvents();
                 final ProductCategory productCategory = existingEvents.get(0).getPlanPhaseSpecifier().getProductCategory();
                 if (productCategory == ProductCategory.ADD_ON) {
@@ -221,19 +215,19 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
 
                     // If BP or STANDALONE subscription, create the cancel event on effectiveCancelDate
                     final DateTime effectiveCancelDate = !cancelImmediately && oldSubscription.getChargedThroughDate() != null &&
-                        effectiveTransferDate.isBefore(oldSubscription.getChargedThroughDate()) ?
-                            oldSubscription.getChargedThroughDate() : effectiveTransferDate;
+                                                         effectiveTransferDate.isBefore(oldSubscription.getChargedThroughDate()) ?
+                                                         oldSubscription.getChargedThroughDate() : effectiveTransferDate;
 
                     final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
-                    .setSubscriptionId(cur.getId())
-                    .setActiveVersion(cur.getActiveVersion())
-                    .setProcessedDate(clock.getUTCNow())
-                    .setEffectiveDate(effectiveCancelDate)
-                    .setRequestedDate(effectiveTransferDate)
-                    .setUserToken(context.getUserToken())
-                    .setFromDisk(true));
-
-                    TransferCancelData cancelData =  new TransferCancelData(oldSubscription, cancelEvent);
+                                                                                    .setSubscriptionId(cur.getId())
+                                                                                    .setActiveVersion(cur.getActiveVersion())
+                                                                                    .setProcessedDate(clock.getUTCNow())
+                                                                                    .setEffectiveDate(effectiveCancelDate)
+                                                                                    .setRequestedDate(effectiveTransferDate)
+                                                                                    .setUserToken(context.getUserToken())
+                                                                                    .setFromDisk(true));
+
+                    TransferCancelData cancelData = new TransferCancelData(oldSubscription, cancelEvent);
                     transferCancelDataList.add(cancelData);
                 }
 
@@ -245,12 +239,12 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
 
                 // Create the new subscription for the new bundle on the new account
                 final SubscriptionData subscriptionData = subscriptionFactory.createSubscription(new SubscriptionBuilder()
-                .setId(UUID.randomUUID())
-                .setBundleId(subscriptionBundleData.getId())
-                .setCategory(productCategory)
-                .setBundleStartDate(effectiveTransferDate)
-                .setAlignStartDate(subscriptionAlignStartDate),
-                ImmutableList.<EntitlementEvent>of());
+                                                                                                         .setId(UUID.randomUUID())
+                                                                                                         .setBundleId(subscriptionBundleData.getId())
+                                                                                                         .setCategory(productCategory)
+                                                                                                         .setBundleStartDate(effectiveTransferDate)
+                                                                                                         .setAlignStartDate(subscriptionAlignStartDate),
+                                                                                                 ImmutableList.<EntitlementEvent>of());
 
                 final List<EntitlementEvent> events = toEvents(existingEvents, subscriptionData, effectiveTransferDate, context);
                 final SubscriptionMigrationData curData = new SubscriptionMigrationData(subscriptionData, events, null);
@@ -259,7 +253,7 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
             BundleMigrationData bundleMigrationData = new BundleMigrationData(subscriptionBundleData, subscriptionMigrationDataList);
 
             // Atomically cancel all subscription on old account and create new bundle, subscriptions, events for new account
-            dao.transfer(sourceAccountId, destAccountId, bundleMigrationData, transferCancelDataList, context);
+            dao.transfer(sourceAccountId, destAccountId, bundleMigrationData, transferCancelDataList, internalCallContext);
 
             return bundle;
         } catch (EntitlementRepairException e) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEffectiveSubscriptionEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEffectiveSubscriptionEvent.java
index f8d66af..5b8a38f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEffectiveSubscriptionEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEffectiveSubscriptionEvent.java
@@ -20,9 +20,10 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.entitlement.api.SubscriptionTransitionType;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 
 public class DefaultEffectiveSubscriptionEvent extends DefaultSubscriptionEvent implements EffectiveSubscriptionEvent {
     public DefaultEffectiveSubscriptionEvent(final SubscriptionTransitionData in, final DateTime startDate) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index 11f6bef..6d32382 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -24,7 +24,6 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -42,31 +41,39 @@ import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Inject;
+
 public class DefaultEntitlementUserApi implements EntitlementUserApi {
+
     private final Clock clock;
     private final EntitlementDao dao;
     private final CatalogService catalogService;
     private final DefaultSubscriptionApiService apiService;
     private final AddonUtils addonUtils;
     private final SubscriptionFactory subscriptionFactory;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultEntitlementUserApi(final Clock clock, final EntitlementDao dao, final CatalogService catalogService,
-                                     final DefaultSubscriptionApiService apiService, final SubscriptionFactory subscriptionFactory, final AddonUtils addonUtils) {
+                                     final DefaultSubscriptionApiService apiService, final SubscriptionFactory subscriptionFactory,
+                                     final AddonUtils addonUtils, final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.apiService = apiService;
         this.dao = dao;
         this.catalogService = catalogService;
         this.addonUtils = addonUtils;
         this.subscriptionFactory = subscriptionFactory;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public SubscriptionBundle getBundleFromId(final UUID id) throws EntitlementUserApiException {
-        final SubscriptionBundle result = dao.getSubscriptionBundleFromId(id);
+    public SubscriptionBundle getBundleFromId(final UUID id, final TenantContext context) throws EntitlementUserApiException {
+        final SubscriptionBundle result = dao.getSubscriptionBundleFromId(id, internalCallContextFactory.createInternalTenantContext(context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_INVALID_BUNDLE_ID, id.toString());
         }
@@ -74,8 +81,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final UUID id) throws EntitlementUserApiException {
-        final Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id);
+    public Subscription getSubscriptionFromId(final UUID id, final TenantContext context) throws EntitlementUserApiException {
+        final Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id, internalCallContextFactory.createInternalTenantContext(context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, id);
         }
@@ -83,8 +90,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey) throws EntitlementUserApiException {
-        final SubscriptionBundle result = dao.getSubscriptionBundleFromAccountAndKey(accountId, bundleKey);
+    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) throws EntitlementUserApiException {
+        final SubscriptionBundle result = dao.getSubscriptionBundleFromAccountAndKey(accountId, bundleKey, internalCallContextFactory.createInternalTenantContext(accountId, context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_INVALID_BUNDLE_KEY, bundleKey);
         }
@@ -92,29 +99,29 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForKey(final String bundleKey)
-    throws EntitlementUserApiException {
-        return dao.getSubscriptionBundlesForKey(bundleKey);
+    public List<SubscriptionBundle> getBundlesForKey(final String bundleKey, final TenantContext context)
+            throws EntitlementUserApiException {
+        return dao.getSubscriptionBundlesForKey(bundleKey, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId) {
-        return dao.getSubscriptionBundleForAccount(accountId);
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId, final TenantContext context) {
+        return dao.getSubscriptionBundleForAccount(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey) {
-        return dao.getSubscriptionsForAccountAndKey(subscriptionFactory, accountId, bundleKey);
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) {
+        return dao.getSubscriptionsForAccountAndKey(subscriptionFactory, accountId, bundleKey, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId) {
-        return dao.getSubscriptions(subscriptionFactory, bundleId);
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId, final TenantContext context) {
+        return dao.getSubscriptions(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Subscription getBaseSubscription(final UUID bundleId) throws EntitlementUserApiException {
-        final Subscription result = dao.getBaseSubscription(subscriptionFactory, bundleId);
+    public Subscription getBaseSubscription(final UUID bundleId, final TenantContext context) throws EntitlementUserApiException {
+        final Subscription result = dao.getBaseSubscription(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION, bundleId);
         }
@@ -125,7 +132,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     public SubscriptionBundle createBundleForAccount(final UUID accountId, final String bundleName, final CallContext context)
             throws EntitlementUserApiException {
         final SubscriptionBundleData bundle = new SubscriptionBundleData(bundleName, accountId, clock.getUTCNow());
-        return dao.createSubscriptionBundle(bundle, context);
+        return dao.createSubscriptionBundle(bundle, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
@@ -149,13 +156,13 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
                                                          spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
             }
 
-            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId, internalCallContextFactory.createInternalTenantContext(context));
             if (bundle == null) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_NO_BUNDLE, bundleId);
             }
 
             DateTime bundleStartDate = null;
-            final SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(subscriptionFactory, bundleId);
+            final SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
             switch (plan.getProduct().getCategory()) {
                 case BASE:
                     if (baseSubscription != null) {
@@ -204,15 +211,15 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public DateTime getNextBillingDate(final UUID accountId) {
-        final List<SubscriptionBundle> bundles = getBundlesForAccount(accountId);
+    public DateTime getNextBillingDate(final UUID accountId, final TenantContext context) {
+        final List<SubscriptionBundle> bundles = getBundlesForAccount(accountId, context);
         DateTime result = null;
         for (final SubscriptionBundle bundle : bundles) {
-            final List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId(), context);
             for (final Subscription subscription : subscriptions) {
                 final DateTime chargedThruDate = subscription.getChargedThroughDate();
                 if (result == null ||
-                        (chargedThruDate != null && chargedThruDate.isBefore(result))) {
+                    (chargedThruDate != null && chargedThruDate.isBefore(result))) {
                     result = subscription.getChargedThroughDate();
                 }
             }
@@ -221,9 +228,10 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName, final DateTime requestedDate)
+    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName,
+                                                                    final DateTime requestedDate, final TenantContext context)
             throws EntitlementUserApiException {
-        final Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
+        final Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId, internalCallContextFactory.createInternalTenantContext(context));
         if (subscription == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId);
         }
@@ -233,7 +241,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
         final List<SubscriptionStatusDryRun> result = new LinkedList<SubscriptionStatusDryRun>();
 
-        final List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscriptionFactory, subscription.getBundleId());
+        final List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscriptionFactory, subscription.getBundleId(), internalCallContextFactory.createInternalTenantContext(context));
         for (final Subscription cur : bundleSubscriptions) {
             if (cur.getId().equals(subscriptionId)) {
                 continue;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultRequestedSubscriptionEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultRequestedSubscriptionEvent.java
index 38b6b98..55b89d0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultRequestedSubscriptionEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultRequestedSubscriptionEvent.java
@@ -20,11 +20,12 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultRequestedSubscriptionEvent extends DefaultSubscriptionEvent implements RequestedSubscriptionEvent {
     public DefaultRequestedSubscriptionEvent(final SubscriptionTransitionData in, final DateTime startDate) {
         super(in, startDate);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
index 16814cb..0cd9212 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
@@ -53,6 +53,8 @@ import com.ning.billing.entitlement.events.user.ApiEventReCreate;
 import com.ning.billing.entitlement.events.user.ApiEventUncancel;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
@@ -64,13 +66,16 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
     private final EntitlementDao dao;
     private final CatalogService catalogService;
     private final PlanAligner planAligner;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultSubscriptionApiService(final Clock clock, final EntitlementDao dao, final CatalogService catalogService, final PlanAligner planAligner) {
+    public DefaultSubscriptionApiService(final Clock clock, final EntitlementDao dao, final CatalogService catalogService,
+                                         final PlanAligner planAligner, final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.catalogService = catalogService;
         this.planAligner = planAligner;
         this.dao = dao;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
@@ -117,21 +122,23 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
     private void createFromSubscription(final SubscriptionData subscription, final Plan plan, final PhaseType initialPhase,
                                         final String realPriceList, final DateTime requestedDate, final DateTime effectiveDate, final DateTime processedDate,
                                         final boolean reCreate, final CallContext context) throws EntitlementUserApiException {
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(context);
+
         try {
             final TimedPhase[] curAndNextPhases = planAligner.getCurrentAndNextTimedPhaseOnCreate(subscription, plan, initialPhase, realPriceList, requestedDate, effectiveDate);
 
             final ApiEventBuilder createBuilder = new ApiEventBuilder()
-            .setSubscriptionId(subscription.getId())
-            .setEventPlan(plan.getName())
-            .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
-            .setEventPriceList(realPriceList)
-            .setActiveVersion(subscription.getActiveVersion())
-            .setProcessedDate(processedDate)
-            .setEffectiveDate(effectiveDate)
-            .setRequestedDate(requestedDate)
-            .setUserToken(context.getUserToken())
-            .setFromDisk(true);
-    final ApiEvent creationEvent = (reCreate) ? new ApiEventReCreate(createBuilder) : new ApiEventCreate(createBuilder);
+                    .setSubscriptionId(subscription.getId())
+                    .setEventPlan(plan.getName())
+                    .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
+                    .setEventPriceList(realPriceList)
+                    .setActiveVersion(subscription.getActiveVersion())
+                    .setProcessedDate(processedDate)
+                    .setEffectiveDate(effectiveDate)
+                    .setRequestedDate(requestedDate)
+                    .setUserToken(context.getUserToken())
+                    .setFromDisk(true);
+            final ApiEvent creationEvent = (reCreate) ? new ApiEventReCreate(createBuilder) : new ApiEventCreate(createBuilder);
 
             final TimedPhase nextTimedPhase = curAndNextPhases[1];
             final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
@@ -143,11 +150,11 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
                 events.add(nextPhaseEvent);
             }
             if (reCreate) {
-                dao.recreateSubscription(subscription, events, context);
+                dao.recreateSubscription(subscription, events, internalCallContext);
             } else {
-                dao.createSubscription(subscription, events, context);
+                dao.createSubscription(subscription, events, internalCallContext);
             }
-            subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
+            subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalogService.getFullCatalog());
         } catch (CatalogApiException e) {
             throw new EntitlementUserApiException(e);
         }
@@ -195,20 +202,20 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
 
         final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
-        .setSubscriptionId(subscription.getId())
-        .setActiveVersion(subscription.getActiveVersion())
-        .setProcessedDate(now)
-        .setEffectiveDate(effectiveDate)
-        .setRequestedDate(requestedDate)
-        .setUserToken(context.getUserToken())
-        .setFromDisk(true));
-
-        dao.cancelSubscription(subscription, cancelEvent, context, 0);
-        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
+                                                                        .setSubscriptionId(subscription.getId())
+                                                                        .setActiveVersion(subscription.getActiveVersion())
+                                                                        .setProcessedDate(now)
+                                                                        .setEffectiveDate(effectiveDate)
+                                                                        .setRequestedDate(requestedDate)
+                                                                        .setUserToken(context.getUserToken())
+                                                                        .setFromDisk(true));
+
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(context);
+        dao.cancelSubscription(subscription, cancelEvent, internalCallContext, 0);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalogService.getFullCatalog());
         return (policy == ActionPolicy.IMMEDIATE);
     }
 
-
     @Override
     public boolean uncancel(final SubscriptionData subscription, final CallContext context) throws EntitlementUserApiException {
         if (!subscription.isSubscriptionFutureCancelled()) {
@@ -236,8 +243,9 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
             uncancelEvents.add(nextPhaseEvent);
         }
 
-        dao.uncancelSubscription(subscription, uncancelEvents, context);
-        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(context);
+        dao.uncancelSubscription(subscription, uncancelEvents, internalCallContext);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalogService.getFullCatalog());
 
         return true;
     }
@@ -317,16 +325,16 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         final TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
 
         final EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
-        .setSubscriptionId(subscription.getId())
-        .setEventPlan(newPlan.getName())
-        .setEventPlanPhase(currentTimedPhase.getPhase().getName())
-        .setEventPriceList(newPriceList.getName())
-        .setActiveVersion(subscription.getActiveVersion())
-        .setProcessedDate(now)
-        .setEffectiveDate(effectiveDate)
-        .setRequestedDate(requestedDate)
-        .setUserToken(context.getUserToken())
-        .setFromDisk(true));
+                                                                        .setSubscriptionId(subscription.getId())
+                                                                        .setEventPlan(newPlan.getName())
+                                                                        .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+                                                                        .setEventPriceList(newPriceList.getName())
+                                                                        .setActiveVersion(subscription.getActiveVersion())
+                                                                        .setProcessedDate(now)
+                                                                        .setEffectiveDate(effectiveDate)
+                                                                        .setRequestedDate(requestedDate)
+                                                                        .setUserToken(context.getUserToken())
+                                                                        .setFromDisk(true));
 
         final TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
         final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
@@ -340,8 +348,9 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         }
         changeEvents.add(changeEvent);
 
-        dao.changePlan(subscription, changeEvents, context);
-        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(context);
+        dao.changePlan(subscription, changeEvents, internalCallContext);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalogService.getFullCatalog());
 
         return (policy == ActionPolicy.IMMEDIATE);
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
index 7c119cc..71f79cc 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
@@ -20,10 +20,11 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.entitlement.api.SubscriptionTransitionType;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 
 public abstract class DefaultSubscriptionEvent implements SubscriptionEvent {
     private final Long totalOrdering;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
index 1e1ebeb..599c65e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
@@ -22,7 +22,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
@@ -31,6 +30,8 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class DefaultSubscriptionFactory implements SubscriptionFactory {
     private final SubscriptionApiService apiService;
     private final Clock clock;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
index ede9ec0..3722b4b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
@@ -16,9 +16,10 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import javax.annotation.Nullable;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.BlockingState;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index 4e8c923..59d67e9 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -16,13 +16,14 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
index dae1ddf..6b45272 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
@@ -18,7 +18,6 @@ package com.ning.billing.entitlement.api.user;
 
 import java.util.LinkedList;
 import java.util.List;
-import java.util.UUID;
 
 import com.ning.billing.entitlement.events.EntitlementEvent;
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
index fd86f63..1eeffc3 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
@@ -18,7 +18,6 @@ package com.ning.billing.entitlement.engine.addon;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
@@ -29,6 +28,8 @@ import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 
+import com.google.inject.Inject;
+
 public class AddonUtils {
     private final CatalogService catalogService;
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
index 57b21d3..1fccb44 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
@@ -25,7 +25,6 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -55,6 +54,7 @@ import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationKey;
@@ -64,7 +64,10 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 
+import com.google.inject.Inject;
+
 public class Engine implements EventListener, EntitlementService {
+
     public static final String NOTIFICATION_QUEUE_NAME = "subscription-events";
     public static final String ENTITLEMENT_SERVICE_NAME = "entitlement-service";
 
@@ -79,6 +82,7 @@ public class Engine implements EventListener, EntitlementService {
     private final NotificationQueueService notificationQueueService;
     private final CallContextFactory factory;
     private final SubscriptionFactory subscriptionFactory;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private NotificationQueue subscriptionEventQueue;
 
@@ -88,7 +92,8 @@ public class Engine implements EventListener, EntitlementService {
                   final AddonUtils addonUtils, final Bus eventBus,
                   final NotificationQueueService notificationQueueService,
                   final SubscriptionFactory subscriptionFactory,
-                  final CallContextFactory factory) {
+                  final CallContextFactory factory,
+                  final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.dao = dao;
         this.planAligner = planAligner;
@@ -98,6 +103,7 @@ public class Engine implements EventListener, EntitlementService {
         this.notificationQueueService = notificationQueueService;
         this.subscriptionFactory = subscriptionFactory;
         this.factory = factory;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
@@ -117,14 +123,14 @@ public class Engine implements EventListener, EntitlementService {
                     }
 
                     final EntitlementNotificationKey key = (EntitlementNotificationKey) inputKey;
-                    final EntitlementEvent event = dao.getEventById(key.getEventId());
+                    final EntitlementEvent event = dao.getEventById(key.getEventId(), internalCallContextFactory.createInternalTenantContext());
                     if (event == null) {
                         log.warn("Failed to extract event for notification key {}", inputKey);
                         return;
                     }
 
                     final UUID userToken = (event.getType() == EventType.API_USER) ? ((ApiEvent) event).getUserToken() : null;
-                    final CallContext context = factory.createCallContext("SubscriptionEventQueue", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
+                    final CallContext context = factory.createCallContext(null, "SubscriptionEventQueue", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
                     processEventReady(event, key.getSeqId(), context);
                 }
             };
@@ -169,7 +175,7 @@ public class Engine implements EventListener, EntitlementService {
             return;
         }
 
-        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, event.getSubscriptionId());
+        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, event.getSubscriptionId(), internalCallContextFactory.createInternalTenantContext(context));
         if (subscription == null) {
             log.warn("Failed to retrieve subscription for id %s", event.getSubscriptionId());
             return;
@@ -202,10 +208,10 @@ public class Engine implements EventListener, EntitlementService {
             final DateTime now = clock.getUTCNow();
             final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, now, now);
             final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
-                    PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
-                    null;
+                                              PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
+                                              null;
             if (nextPhaseEvent != null) {
-                dao.createNextPhaseEvent(subscription, nextPhaseEvent, context);
+                dao.createNextPhaseEvent(subscription, nextPhaseEvent, internalCallContextFactory.createInternalCallContext(context));
             }
         } catch (EntitlementError e) {
             log.error(String.format("Failed to insert next phase for subscription %s", subscription.getId()), e);
@@ -216,21 +222,21 @@ public class Engine implements EventListener, EntitlementService {
         final DateTime now = clock.getUTCNow();
         final Product baseProduct = (baseSubscription.getState() == SubscriptionState.CANCELLED) ? null : baseSubscription.getCurrentPlan().getProduct();
 
-        final List<Subscription> subscriptions = dao.getSubscriptions(subscriptionFactory, baseSubscription.getBundleId());
+        final List<Subscription> subscriptions = dao.getSubscriptions(subscriptionFactory, baseSubscription.getBundleId(), internalCallContextFactory.createInternalTenantContext(context));
 
         final Map<UUID, EntitlementEvent> addOnCancellations = new HashMap<UUID, EntitlementEvent>();
         final Map<UUID, SubscriptionData> addOnCancellationSubscriptions = new HashMap<UUID, SubscriptionData>();
         for (final Subscription subscription : subscriptions) {
             final SubscriptionData cur = (SubscriptionData) subscription;
             if (cur.getState() == SubscriptionState.CANCELLED ||
-                    cur.getCategory() != ProductCategory.ADD_ON) {
+                cur.getCategory() != ProductCategory.ADD_ON) {
                 continue;
             }
 
             final Plan addonCurrentPlan = cur.getCurrentPlan();
             if (baseProduct == null ||
-                    addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
-                    !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
+                addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
+                !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
                 //
                 // Perform AO cancellation using the effectiveDate of the BP
                 //
@@ -251,7 +257,7 @@ public class Engine implements EventListener, EntitlementService {
         final int addOnSize = addOnCancellations.size();
         int cancelSeq = addOnSize - 1;
         for (final UUID key : addOnCancellations.keySet()) {
-            dao.cancelSubscription(addOnCancellationSubscriptions.get(key), addOnCancellations.get(key), context, cancelSeq);
+            dao.cancelSubscription(addOnCancellationSubscriptions.get(key), addOnCancellations.get(key), internalCallContextFactory.createInternalCallContext(context), cancelSeq);
             cancelSeq--;
         }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
index 1327a72..ac6c9b7 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
@@ -17,9 +17,10 @@ package com.ning.billing.entitlement.engine.core;
 
 import java.util.UUID;
 
+import com.ning.billing.util.notificationq.NotificationKey;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.util.notificationq.NotificationKey;
 
 public class EntitlementNotificationKey implements NotificationKey {
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
index eb31743..7ec7bca 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import javax.annotation.Nullable;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,6 +27,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
@@ -36,9 +37,6 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
@@ -71,7 +69,8 @@ import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.TableName;
@@ -80,7 +79,12 @@ import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
+
 public class AuditedEntitlementDao implements EntitlementDao {
+
     private static final Logger log = LoggerFactory.getLogger(AuditedEntitlementDao.class);
 
     private final Clock clock;
@@ -104,33 +108,32 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey) {
-        return bundlesDao.getBundleFromAccountAndKey(accountId.toString(), bundleKey);
+    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) {
+        return bundlesDao.getBundleFromAccountAndKey(accountId.toString(), bundleKey, context);
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
-        return bundlesDao.getBundleFromAccount(accountId.toString());
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId, final InternalTenantContext context) {
+        return bundlesDao.getBundleFromAccount(accountId.toString(), context);
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId) {
-        return bundlesDao.getBundleFromId(bundleId.toString());
+    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId, final InternalTenantContext context) {
+        return bundlesDao.getBundleFromId(bundleId.toString(), context);
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey) {
-        return bundlesDao.getBundlesForKey(bundleKey);
+    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey, final InternalTenantContext context) {
+        return bundlesDao.getBundlesForKey(bundleKey, context);
     }
 
-
     @Override
-    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final CallContext context) {
+    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final InternalCallContext context) {
         return bundlesDao.inTransaction(new Transaction<SubscriptionBundle, BundleSqlDao>() {
             @Override
             public SubscriptionBundle inTransaction(final BundleSqlDao transactional, final TransactionStatus status) {
                 bundlesDao.insertBundle(bundle, context);
-                final Long recordId = bundlesDao.getRecordId(bundle.getId().toString());
+                final Long recordId = bundlesDao.getRecordId(bundle.getId().toString(), context);
 
                 final EntityAudit audit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.INSERT);
                 bundlesDao.insertAuditFromTransaction(audit, context);
@@ -141,8 +144,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
-        final Subscription subscription = subscriptionsDao.getSubscriptionFromId(subscriptionId.toString());
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) {
+        final Subscription subscription = subscriptionsDao.getSubscriptionFromId(subscriptionId.toString(), context);
         if (subscription == null) {
             log.error(String.format(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getFormat(), subscriptionId.toString()));
             return null;
@@ -154,7 +157,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
             return null;
         }
 
-        final SubscriptionBundle bundle = bundlesDao.getBundleFromId(bundleId.toString());
+        final SubscriptionBundle bundle = bundlesDao.getBundleFromId(bundleId.toString(), context);
         if (bundle == null) {
             log.error(String.format(ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getFormat(), bundleId.toString()));
             return null;
@@ -164,32 +167,33 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId) {
-        return getBaseSubscription(factory, bundleId, true);
+    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+        return getBaseSubscription(factory, bundleId, true, context);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId) {
-        return buildSubscription(factory, subscriptionsDao.getSubscriptionFromId(subscriptionId.toString()));
+    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
+        return buildSubscription(factory, subscriptionsDao.getSubscriptionFromId(subscriptionId.toString(), context), context);
     }
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId) {
-        return buildBundleSubscriptions(bundleId, factory, subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString()));
+    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+        return buildBundleSubscriptions(bundleId, factory, subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString(), context), context);
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey) {
-        final SubscriptionBundle bundle = bundlesDao.getBundleFromAccountAndKey(accountId.toString(), bundleKey);
+    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId,
+                                                               final String bundleKey, final InternalTenantContext context) {
+        final SubscriptionBundle bundle = bundlesDao.getBundleFromAccountAndKey(accountId.toString(), bundleKey, context);
         if (bundle == null) {
             return Collections.emptyList();
         }
 
-        return getSubscriptions(factory, bundle.getId());
+        return getSubscriptions(factory, bundle.getId(), context);
     }
 
     @Override
-    public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context) {
+    public void updateChargedThroughDate(final SubscriptionData subscription, final InternalCallContext context) {
         final Date ctd = (subscription.getChargedThroughDate() != null) ? subscription.getChargedThroughDate().toDate() : null;
 
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
@@ -197,15 +201,15 @@ public class AuditedEntitlementDao implements EntitlementDao {
             public Void inTransaction(final SubscriptionSqlDao transactionalDao, final TransactionStatus status) throws Exception {
                 final String subscriptionId = subscription.getId().toString();
                 transactionalDao.updateChargedThroughDate(subscription.getId().toString(), ctd, context);
-                final Long subscriptionRecordId = transactionalDao.getRecordId(subscriptionId);
+                final Long subscriptionRecordId = transactionalDao.getRecordId(subscriptionId, context);
                 final EntityAudit subscriptionAudit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.UPDATE);
                 transactionalDao.insertAuditFromTransaction(subscriptionAudit, context);
 
                 final BundleSqlDao bundleSqlDao = transactionalDao.become(BundleSqlDao.class);
                 final String bundleId = subscription.getBundleId().toString();
-                bundleSqlDao.updateBundleLastSysTime(bundleId, clock.getUTCNow().toDate());
+                bundleSqlDao.updateBundleLastSysTime(bundleId, clock.getUTCNow().toDate(), context);
 
-                final Long recordId = bundleSqlDao.getRecordId(bundleId);
+                final Long recordId = bundleSqlDao.getRecordId(bundleId, context);
                 final EntityAudit bundleAudit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.UPDATE);
                 bundleSqlDao.insertAuditFromTransaction(bundleAudit, context);
 
@@ -215,7 +219,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase, final CallContext context) {
+    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase, final InternalCallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -223,13 +227,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 cancelNextPhaseEventFromTransaction(subscriptionId, transactional, context);
                 transactional.insertEvent(nextPhase, context);
 
-                final Long recordId = transactional.getRecordId(nextPhase.getId().toString());
+                final Long recordId = transactional.getRecordId(nextPhase.getId().toString(), context);
                 final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
                 recordFutureNotificationFromTransaction(transactional,
                                                         nextPhase.getEffectiveDate(),
-                                                        new EntitlementNotificationKey(nextPhase.getId()));
+                                                        new EntitlementNotificationKey(nextPhase.getId()),
+                                                        context);
 
                 // Notify the Bus of the requested change
                 notifyBusOfRequestedChange(transactional, subscription, nextPhase);
@@ -240,22 +245,22 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public EntitlementEvent getEventById(final UUID eventId) {
-        return eventsDao.getEventById(eventId.toString());
+    public EntitlementEvent getEventById(final UUID eventId, final InternalTenantContext context) {
+        return eventsDao.getEventById(eventId.toString(), context);
     }
 
     @Override
-    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
-        return eventsDao.getEventsForSubscription(subscriptionId.toString());
+    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
+        return eventsDao.getEventsForSubscription(subscriptionId.toString(), context);
     }
 
     @Override
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId, final InternalTenantContext context) {
         return subscriptionsDao.inTransaction(new Transaction<Map<UUID, List<EntitlementEvent>>, SubscriptionSqlDao>() {
             @Override
             public Map<UUID, List<EntitlementEvent>> inTransaction(final SubscriptionSqlDao transactional,
                                                                    final TransactionStatus status) throws Exception {
-                final List<Subscription> subscriptions = transactional.getSubscriptionsFromBundleId(bundleId.toString());
+                final List<Subscription> subscriptions = transactional.getSubscriptionsFromBundleId(bundleId.toString(), context);
                 if (subscriptions.size() == 0) {
                     return Collections.emptyMap();
                 }
@@ -263,7 +268,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 final EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
                 final Map<UUID, List<EntitlementEvent>> result = new HashMap<UUID, List<EntitlementEvent>>();
                 for (final Subscription cur : subscriptions) {
-                    final List<EntitlementEvent> events = eventsDaoFromSameTransaction.getEventsForSubscription(cur.getId().toString());
+                    final List<EntitlementEvent> events = eventsDaoFromSameTransaction.getEventsForSubscription(cur.getId().toString(), context);
                     result.put(cur.getId(), events);
                 }
 
@@ -273,19 +278,19 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId) {
+    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         final Date now = clock.getUTCNow().toDate();
-        return eventsDao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        return eventsDao.getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
     }
 
     @Override
-    public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents, final CallContext context) {
+    public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents, final InternalCallContext context) {
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
             @Override
             public Void inTransaction(final SubscriptionSqlDao transactional, final TransactionStatus status) throws Exception {
                 transactional.insertSubscription(subscription, context);
 
-                final Long subscriptionRecordId = transactional.getRecordId(subscription.getId().toString());
+                final Long subscriptionRecordId = transactional.getRecordId(subscription.getId().toString(), context);
                 final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
@@ -295,11 +300,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
                 for (final EntitlementEvent cur : initialEvents) {
                     eventsDaoFromSameTransaction.insertEvent(cur, context);
-                    final Long recordId = eventsDaoFromSameTransaction.getRecordId(cur.getId().toString());
+                    final Long recordId = eventsDaoFromSameTransaction.getRecordId(cur.getId().toString(), context);
                     audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                     recordFutureNotificationFromTransaction(transactional,
                                                             cur.getEffectiveDate(),
-                                                            new EntitlementNotificationKey(cur.getId()));
+                                                            new EntitlementNotificationKey(cur.getId()),
+                                                            context);
                 }
 
                 eventsDaoFromSameTransaction.insertAuditFromTransaction(audits, context);
@@ -315,7 +321,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void recreateSubscription(final SubscriptionData subscription, final List<EntitlementEvent> recreateEvents, final CallContext context) {
+    public void recreateSubscription(final SubscriptionData subscription, final List<EntitlementEvent> recreateEvents, final InternalCallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional,
@@ -323,11 +329,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 final List<EntityAudit> audits = new ArrayList<EntityAudit>();
                 for (final EntitlementEvent cur : recreateEvents) {
                     transactional.insertEvent(cur, context);
-                    final Long recordId = transactional.getRecordId(cur.getId().toString());
+                    final Long recordId = transactional.getRecordId(cur.getId().toString(), context);
                     audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                     recordFutureNotificationFromTransaction(transactional,
                                                             cur.getEffectiveDate(),
-                                                            new EntitlementNotificationKey(cur.getId()));
+                                                            new EntitlementNotificationKey(cur.getId()),
+                                                            context);
 
                 }
 
@@ -342,7 +349,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void cancelSubscription(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final CallContext context, final int seqId) {
+    public void cancelSubscription(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final InternalCallContext context, final int seqId) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -353,14 +360,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void uncancelSubscription(final SubscriptionData subscription, final List<EntitlementEvent> uncancelEvents, final CallContext context) {
+    public void uncancelSubscription(final SubscriptionData subscription, final List<EntitlementEvent> uncancelEvents, final InternalCallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
                 final UUID subscriptionId = subscription.getId();
                 EntitlementEvent cancelledEvent = null;
                 final Date now = clock.getUTCNow().toDate();
-                final List<EntitlementEvent> events = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+                final List<EntitlementEvent> events = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
 
                 for (final EntitlementEvent cur : events) {
                     if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
@@ -376,16 +383,17 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
                     final String cancelledEventId = cancelledEvent.getId().toString();
                     transactional.unactiveEvent(cancelledEventId, context);
-                    final Long cancelledRecordId = transactional.getRecordId(cancelledEventId);
+                    final Long cancelledRecordId = transactional.getRecordId(cancelledEventId, context);
                     eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, cancelledRecordId, ChangeType.UPDATE));
 
                     for (final EntitlementEvent cur : uncancelEvents) {
                         transactional.insertEvent(cur, context);
-                        final Long recordId = transactional.getRecordId(cur.getId().toString());
+                        final Long recordId = transactional.getRecordId(cur.getId().toString(), context);
                         eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                         recordFutureNotificationFromTransaction(transactional,
                                                                 cur.getEffectiveDate(),
-                                                                new EntitlementNotificationKey(cur.getId()));
+                                                                new EntitlementNotificationKey(cur.getId()),
+                                                                context);
                     }
 
                     transactional.insertAuditFromTransaction(eventAudits, context);
@@ -400,7 +408,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents, final CallContext context) {
+    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents, final InternalCallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -410,12 +418,13 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 final List<EntityAudit> eventAudits = new ArrayList<EntityAudit>();
                 for (final EntitlementEvent cur : changeEvents) {
                     transactional.insertEvent(cur, context);
-                    final Long recordId = transactional.getRecordId(cur.getId().toString());
+                    final Long recordId = transactional.getRecordId(cur.getId().toString(), context);
                     eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
 
                     recordFutureNotificationFromTransaction(transactional,
                                                             cur.getEffectiveDate(),
-                                                            new EntitlementNotificationKey(cur.getId()));
+                                                            new EntitlementNotificationKey(cur.getId()),
+                                                            context);
                 }
 
                 transactional.insertAuditFromTransaction(eventAudits, context);
@@ -429,47 +438,45 @@ public class AuditedEntitlementDao implements EntitlementDao {
         });
     }
 
-    private void cancelSubscriptionFromTransaction(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final EntitlementEventSqlDao transactional, final CallContext context, final int seqId) {
+    private void cancelSubscriptionFromTransaction(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final EntitlementEventSqlDao transactional, final InternalCallContext context, final int seqId) {
         final UUID subscriptionId = subscription.getId();
         cancelFutureEventsFromTransaction(subscriptionId, transactional, context);
         transactional.insertEvent(cancelEvent, context);
         final String cancelEventId = cancelEvent.getId().toString();
 
-        final Long recordId = transactional.getRecordId(cancelEventId);
+        final Long recordId = transactional.getRecordId(cancelEventId, context);
         final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
 
         recordFutureNotificationFromTransaction(transactional,
                                                 cancelEvent.getEffectiveDate(),
-                                                new EntitlementNotificationKey(cancelEvent.getId(), seqId));
+                                                new EntitlementNotificationKey(cancelEvent.getId(), seqId),
+                                                context);
 
         // Notify the Bus of the requested change
         notifyBusOfRequestedChange(transactional, subscription, cancelEvent);
     }
 
-
-
-    private void cancelNextPhaseEventFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final CallContext context) {
+    private void cancelNextPhaseEventFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final InternalCallContext context) {
         cancelFutureEventFromTransaction(subscriptionId, dao, EventType.PHASE, null, context);
     }
 
-
-    private void cancelFutureEventsFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final CallContext context) {
+    private void cancelFutureEventsFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final InternalCallContext context) {
         final Date now = clock.getUTCNow().toDate();
-        final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
         for (final EntitlementEvent cur : events) {
             unactivateEventFromTransaction(cur, dao, context);
         }
     }
 
     private void cancelFutureEventFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final EventType type,
-                                                  @Nullable final ApiEventType apiType, final CallContext context) {
+                                                  @Nullable final ApiEventType apiType, final InternalCallContext context) {
         EntitlementEvent futureEvent = null;
         final Date now = clock.getUTCNow().toDate();
-        final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
         for (final EntitlementEvent cur : events) {
             if (cur.getType() == type &&
-                    (apiType == null || apiType == ((ApiEvent) cur).getEventType())) {
+                (apiType == null || apiType == ((ApiEvent) cur).getEventType())) {
                 if (futureEvent != null) {
                     throw new EntitlementError(String.format("Found multiple future events for type %s for subscriptions %s",
                                                              type, subscriptionId.toString()));
@@ -480,31 +487,31 @@ public class AuditedEntitlementDao implements EntitlementDao {
         unactivateEventFromTransaction(futureEvent, dao, context);
     }
 
-    private void unactivateEventFromTransaction(final EntitlementEvent event, final EntitlementEventSqlDao dao, final CallContext context) {
+    private void unactivateEventFromTransaction(final EntitlementEvent event, final EntitlementEventSqlDao dao, final InternalCallContext context) {
         if (event != null) {
             final String eventId = event.getId().toString();
             dao.unactiveEvent(eventId, context);
-            final Long recordId = dao.getRecordId(eventId);
+            final Long recordId = dao.getRecordId(eventId, context);
             final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.UPDATE);
             dao.insertAuditFromTransaction(audit, context);
         }
     }
 
-    private Subscription buildSubscription(final SubscriptionFactory factory, final Subscription input) {
+    private Subscription buildSubscription(final SubscriptionFactory factory, final Subscription input, final InternalTenantContext context) {
         if (input == null) {
             return null;
         }
 
         final List<Subscription> bundleInput = new ArrayList<Subscription>();
         if (input.getCategory() == ProductCategory.ADD_ON) {
-            final Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false);
+            final Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false, context);
             bundleInput.add(baseSubscription);
             bundleInput.add(input);
         } else {
             bundleInput.add(input);
         }
 
-        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(input.getBundleId(), factory, bundleInput);
+        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(input.getBundleId(), factory, bundleInput, context);
         for (final Subscription cur : reloadedSubscriptions) {
             if (cur.getId().equals(input.getId())) {
                 return cur;
@@ -514,7 +521,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         throw new EntitlementError("Unexpected code path in buildSubscription");
     }
 
-    private List<Subscription> buildBundleSubscriptions(final UUID bundleId, final SubscriptionFactory factory, final List<Subscription> input) {
+    private List<Subscription> buildBundleSubscriptions(final UUID bundleId, final SubscriptionFactory factory, final List<Subscription> input, final InternalTenantContext context) {
         if (input == null || input.size() == 0) {
             return Collections.emptyList();
         }
@@ -534,7 +541,6 @@ public class AuditedEntitlementDao implements EntitlementDao {
                     log.error("o2 :Unexpected null subscription in compareMethod for bundle {}, input.size() = {}", bundleId, input.size());
                 }
 
-
                 if (o1.getCategory() == ProductCategory.BASE) {
                     return -1;
                 } else if (o2.getCategory() == ProductCategory.BASE) {
@@ -548,7 +554,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         EntitlementEvent futureBaseEvent = null;
         final List<Subscription> result = new ArrayList<Subscription>(input.size());
         for (final Subscription cur : input) {
-            final List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString());
+            final List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString(), context);
             Subscription reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
 
             switch (cur.getCategory()) {
@@ -566,12 +572,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 case ADD_ON:
                     final Plan targetAddOnPlan = reloaded.getCurrentPlan();
                     final String baseProductName = (futureBaseEvent instanceof ApiEventChange) ?
-                            ((ApiEventChange) futureBaseEvent).getEventPlan() : null;
+                                                   ((ApiEventChange) futureBaseEvent).getEventPlan() : null;
 
                     final boolean createCancelEvent = (futureBaseEvent != null && targetAddOnPlan != null) &&
-                            ((futureBaseEvent instanceof ApiEventCancel) ||
-                                    ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
-                                            (addonUtils.isAddonIncludedFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan))));
+                                                      ((futureBaseEvent instanceof ApiEventCancel) ||
+                                                       ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
+                                                        (addonUtils.isAddonIncludedFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan))));
 
                     if (createCancelEvent) {
                         final DateTime now = clock.getUTCNow();
@@ -601,7 +607,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void migrate(final UUID accountId, final AccountMigrationData accountData, final CallContext context) {
+    public void migrate(final UUID accountId, final AccountMigrationData accountData, final InternalCallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -614,7 +620,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair, final CallContext context) {
+    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair, final InternalCallContext context) {
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
             @Override
             public Void inTransaction(final SubscriptionSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -629,7 +635,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
                         if (event.getEffectiveDate().isAfter(clock.getUTCNow())) {
                             recordFutureNotificationFromTransaction(transactional,
                                                                     event.getEffectiveDate(),
-                                                                    new EntitlementNotificationKey(event.getId()));
+                                                                    new EntitlementNotificationKey(event.getId()),
+                                                                    context);
                         }
                     }
                 }
@@ -649,14 +656,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     @Override
     public void transfer(final UUID srcAccountId, final UUID destAccountId, final BundleMigrationData bundleTransferData,
-            final List<TransferCancelData> transferCancelData, final CallContext context) {
+                         final List<TransferCancelData> transferCancelData, final InternalCallContext context) {
 
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
             public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
 
                 // Cancel the subscriptions for the old bundle
-                for (TransferCancelData cancel : transferCancelData) {
+                for (final TransferCancelData cancel : transferCancelData) {
                     cancelSubscriptionFromTransaction(cancel.getSubscription(), cancel.getCancelEvent(), transactional, context, 0);
                 }
 
@@ -666,23 +673,23 @@ public class AuditedEntitlementDao implements EntitlementDao {
         });
     }
 
-
-    private Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final boolean rebuildSubscription) {
-        final List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
+    private Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final boolean rebuildSubscription, final InternalTenantContext context) {
+        final List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString(), context);
         for (final Subscription cur : subscriptions) {
             if (cur.getCategory() == ProductCategory.BASE) {
-                return rebuildSubscription ? buildSubscription(factory, cur) : cur;
+                return rebuildSubscription ? buildSubscription(factory, cur, context) : cur;
             }
         }
 
         return null;
     }
 
-    private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
+    private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate,
+                                                         final NotificationKey notificationKey, final InternalCallContext context) {
         try {
             final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
                                                                                                            Engine.NOTIFICATION_QUEUE_NAME);
-            subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, null, notificationKey);
+            subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, null, notificationKey, context);
         } catch (NoSuchNotificationQueue e) {
             throw new RuntimeException(e);
         } catch (IOException e) {
@@ -698,7 +705,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         }
     }
 
-    private void migrateBundleDataFromTransaction(final BundleMigrationData bundleTransferData, final EntitlementEventSqlDao transactional, final CallContext context) {
+    private void migrateBundleDataFromTransaction(final BundleMigrationData bundleTransferData, final EntitlementEventSqlDao transactional, final InternalCallContext context) {
 
         final SubscriptionSqlDao transSubDao = transactional.become(SubscriptionSqlDao.class);
         final BundleSqlDao transBundleDao = transactional.become(BundleSqlDao.class);
@@ -707,7 +714,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         Long recordId;
         final SubscriptionBundleData bundleData = bundleTransferData.getData();
 
-        final SubscriptionBundle existingBundle = transBundleDao.getBundleFromAccountAndKey(bundleData.getAccountId().toString(), bundleData.getKey());
+        final SubscriptionBundle existingBundle = transBundleDao.getBundleFromAccountAndKey(bundleData.getAccountId().toString(), bundleData.getKey(), context);
         if (existingBundle != null) {
             log.error(String.format("Attempted to create a bundle for account %s and key %s that already existed, skip...", bundleData.getAccountId().toString(), bundleData.getKey()));
             return;
@@ -717,15 +724,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
             final SubscriptionData subData = curSubscription.getData();
             for (final EntitlementEvent curEvent : curSubscription.getInitialEvents()) {
                 transactional.insertEvent(curEvent, context);
-                recordId = transactional.getRecordId(curEvent.getId().toString());
+                recordId = transactional.getRecordId(curEvent.getId().toString(), context);
                 audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
 
                 recordFutureNotificationFromTransaction(transactional,
-                        curEvent.getEffectiveDate(),
-                        new EntitlementNotificationKey(curEvent.getId()));
+                                                        curEvent.getEffectiveDate(),
+                                                        new EntitlementNotificationKey(curEvent.getId()),
+                                                        context);
             }
             transSubDao.insertSubscription(subData, context);
-            recordId = transSubDao.getRecordId(subData.getId().toString());
+            recordId = transSubDao.getRecordId(subData.getId().toString(), context);
             audits.add(new EntityAudit(TableName.SUBSCRIPTIONS, recordId, ChangeType.INSERT));
 
             // Notify the Bus of the latest requested change
@@ -734,7 +742,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         }
 
         transBundleDao.insertBundle(bundleData, context);
-        recordId = transBundleDao.getRecordId(bundleData.getId().toString());
+        recordId = transBundleDao.getRecordId(bundleData.getId().toString(), context);
         audits.add(new EntityAudit(TableName.BUNDLES, recordId, ChangeType.INSERT));
 
         // add audit records for bundles, subscriptions, and events
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
index c48a5f2..0750c93 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
@@ -38,8 +38,9 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
@@ -51,22 +52,29 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, EntitySqlDao<
                                       AuditSqlDao, CloseMe, Transmogrifier {
     @SqlUpdate
     public void insertBundle(@Bind(binder = SubscriptionBundleBinder.class) SubscriptionBundleData bundle,
-                             @CallContextBinder final CallContext context);
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void updateBundleLastSysTime(@Bind("id") String id, @Bind("lastSysUpdateDate") Date lastSysUpdate);
+    public void updateBundleLastSysTime(@Bind("id") String id,
+                                        @Bind("lastSysUpdateDate") Date lastSysUpdate,
+                                        @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public SubscriptionBundle getBundleFromId(@Bind("id") String id);
+    public SubscriptionBundle getBundleFromId(@Bind("id") String id,
+                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public SubscriptionBundle getBundleFromAccountAndKey(@Bind("accountId") String accountId, @Bind("externalKey") String externalKey);
+    public SubscriptionBundle getBundleFromAccountAndKey(@Bind("accountId") String accountId,
+                                                         @Bind("externalKey") String externalKey,
+                                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public List<SubscriptionBundle> getBundleFromAccount(@Bind("accountId") String accountId);
+    public List<SubscriptionBundle> getBundleFromAccount(@Bind("accountId") String accountId,
+                                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public List<SubscriptionBundle> getBundlesForKey(@Bind("externalKey") String externalKey);
+    public List<SubscriptionBundle> getBundlesForKey(@Bind("externalKey") String externalKey,
+                                                     @InternalTenantContextBinder final InternalTenantContext context);
 
     public static class SubscriptionBundleBinder extends BinderBase implements Binder<Bind, SubscriptionBundleData> {
         @Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index 0544d1f..a9b900d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -30,62 +30,64 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface EntitlementDao {
+
     // Bundle apis
-    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId);
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(UUID accountId, InternalTenantContext context);
 
-    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey);
+    public List<SubscriptionBundle> getSubscriptionBundlesForKey(String bundleKey, InternalTenantContext context);
 
-    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey);
+    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(UUID accountId, String bundleKey, InternalTenantContext context);
 
-    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId);
+    public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId, InternalTenantContext context);
 
-    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, CallContext context);
+    public SubscriptionBundle createSubscriptionBundle(SubscriptionBundleData bundle, InternalCallContext context);
 
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId);
+    public Subscription getSubscriptionFromId(SubscriptionFactory factory, UUID subscriptionId, InternalTenantContext context);
 
     // ACCOUNT retrieval
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId);
+    public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context);
 
     // Subscription retrieval
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId);
+    public Subscription getBaseSubscription(SubscriptionFactory factory, UUID bundleId, InternalTenantContext context);
 
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId);
+    public List<Subscription> getSubscriptions(SubscriptionFactory factory, UUID bundleId, InternalTenantContext context);
 
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey);
+    public List<Subscription> getSubscriptionsForAccountAndKey(SubscriptionFactory factory, UUID accountId, String bundleKey, InternalTenantContext context);
 
     // Update
-    public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context);
+    public void updateChargedThroughDate(SubscriptionData subscription, InternalCallContext context);
 
     // Event apis
-    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase, final CallContext context);
+    public void createNextPhaseEvent(SubscriptionData subscription, EntitlementEvent nextPhase, InternalCallContext context);
 
-    public EntitlementEvent getEventById(final UUID eventId);
+    public EntitlementEvent getEventById(UUID eventId, InternalTenantContext context);
 
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId);
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(UUID bundleId, InternalTenantContext context);
 
-    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId);
+    public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId, InternalTenantContext context);
 
-    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId);
+    public List<EntitlementEvent> getPendingEventsForSubscription(UUID subscriptionId, InternalTenantContext context);
 
     // Subscription creation, cancellation, changePlan apis
-    public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents, final CallContext context);
+    public void createSubscription(SubscriptionData subscription, List<EntitlementEvent> initialEvents, InternalCallContext context);
 
-    public void recreateSubscription(final SubscriptionData subscription, final List<EntitlementEvent> recreateEvents, final CallContext context);
+    public void recreateSubscription(SubscriptionData subscription, List<EntitlementEvent> recreateEvents, InternalCallContext context);
 
-    public void cancelSubscription(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final CallContext context, final int cancelSeq);
+    public void cancelSubscription(SubscriptionData subscription, EntitlementEvent cancelEvent, InternalCallContext context, int cancelSeq);
 
-    public void uncancelSubscription(final SubscriptionData subscription, final List<EntitlementEvent> uncancelEvents, final CallContext context);
+    public void uncancelSubscription(SubscriptionData subscription, List<EntitlementEvent> uncancelEvents, InternalCallContext context);
 
-    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents, final CallContext context);
+    public void changePlan(SubscriptionData subscription, List<EntitlementEvent> changeEvents, InternalCallContext context);
 
-    public void migrate(final UUID accountId, final AccountMigrationData data, final CallContext context);
+    public void migrate(UUID accountId, AccountMigrationData data, InternalCallContext context);
 
-    public void transfer(final UUID srcAccountId, final UUID destAccountId, final BundleMigrationData data, final List<TransferCancelData> transferCancelData, final CallContext context);
+    public void transfer(UUID srcAccountId, UUID destAccountId, BundleMigrationData data, List<TransferCancelData> transferCancelData, InternalCallContext context);
 
     // Repair
-    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair, final CallContext context);
+    public void repair(UUID accountId, UUID bundleId, List<SubscriptionDataRepair> inRepair, InternalCallContext context);
 }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
index 4c89cf6..18a4d6f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
@@ -54,8 +54,9 @@ import com.ning.billing.entitlement.events.user.ApiEventTransfer;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.ApiEventUncancel;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
@@ -63,38 +64,43 @@ import com.ning.billing.util.entity.dao.EntitySqlDao;
 
 @ExternalizedSqlViaStringTemplate3()
 public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSqlDao>, AuditSqlDao,
-        EntitySqlDao<EntitlementEvent>, CloseMe, Transmogrifier {
+                                                EntitySqlDao<EntitlementEvent>, CloseMe, Transmogrifier {
 
     @SqlQuery
     @Mapper(EventSqlMapper.class)
-    public EntitlementEvent getEventById(@Bind("id") String id);
+    public EntitlementEvent getEventById(@Bind("id") String id,
+                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     public void insertEvent(@Bind(binder = EventSqlDaoBinder.class) EntitlementEvent evt,
-                            @CallContextBinder final CallContext context);
+                            @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void unactiveEvent(@Bind("id") String id,
-                              @CallContextBinder final CallContext context);
+                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void reactiveEvent(@Bind("id") String id,
-                              @CallContextBinder final CallContext context);
+                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void updateVersion(@Bind("id") String id,
                               @Bind("currentVersion") Long currentVersion,
-                              @CallContextBinder final CallContext context);
+                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     @Mapper(EventSqlMapper.class)
-    public List<EntitlementEvent> getFutureActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId, @Bind("now") Date now);
+    public List<EntitlementEvent> getFutureActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId,
+                                                                      @Bind("now") Date now,
+                                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @Mapper(EventSqlMapper.class)
-    public List<EntitlementEvent> getEventsForSubscription(@Bind("subscriptionId") String subscriptionId);
+    public List<EntitlementEvent> getEventsForSubscription(@Bind("subscriptionId") String subscriptionId,
+                                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     public static class EventSqlDaoBinder extends BinderBase implements Binder<Bind, EntitlementEvent> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final EntitlementEvent evt) {
 
@@ -126,6 +132,7 @@ public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSq
     }
 
     public static class EventSqlMapper extends MapperBase implements ResultSetMapper<EntitlementEvent> {
+
         @Override
         public EntitlementEvent map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
@@ -146,8 +153,8 @@ public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSq
             final UUID userToken = r.getString("user_token") != null ? UUID.fromString(r.getString("user_token")) : null;
 
             final EventBaseBuilder<?> base = ((eventType == EventType.PHASE) ?
-                    new PhaseEventBuilder() :
-                    new ApiEventBuilder())
+                                              new PhaseEventBuilder() :
+                                              new ApiEventBuilder())
                     .setTotalOrdering(totalOrdering)
                     .setUuid(id)
                     .setSubscriptionId(subscriptionId)
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
index ad82bd5..032e13c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
@@ -27,8 +27,6 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
@@ -41,20 +39,24 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
 
 public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLifecycleDao {
+
     private static final String NOT_IMPLEMENTED = "Not implemented";
 
     private final ThreadLocal<Map<UUID, SubscriptionRepairEvent>> preThreadsInRepairSubscriptions = new ThreadLocal<Map<UUID, SubscriptionRepairEvent>>();
 
-
-    private final static class EntitlementEventWithOrderingId {
+    private static final class EntitlementEventWithOrderingId {
 
         private final EntitlementEvent event;
         private final long orderingId;
 
-        public EntitlementEventWithOrderingId(EntitlementEvent event, long orderingId) {
+        public EntitlementEventWithOrderingId(final EntitlementEvent event, final long orderingId) {
             this.event = event;
             this.orderingId = orderingId;
         }
@@ -62,13 +64,14 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
         public EntitlementEvent getEvent() {
             return event;
         }
+
         public long getOrderingId() {
             return orderingId;
         }
 
         @Override
         public String toString() {
-            StringBuilder tmp  = new StringBuilder();
+            final StringBuilder tmp = new StringBuilder();
             tmp.append("[");
             tmp.append(event.getType());
             tmp.append(": effDate=");
@@ -91,7 +94,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
             this.events = new TreeSet<EntitlementEventWithOrderingId>(new Comparator<EntitlementEventWithOrderingId>() {
                 @Override
                 public int compare(final EntitlementEventWithOrderingId o1, final EntitlementEventWithOrderingId o2) {
-                    int result = o1.getEvent().getEffectiveDate().compareTo(o2.getEvent().getEffectiveDate());
+                    final int result = o1.getEvent().getEffectiveDate().compareTo(o2.getEvent().getEffectiveDate());
                     if (result == 0) {
                         if (o1.getOrderingId() < o2.getOrderingId()) {
                             return -1;
@@ -122,7 +125,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
         }
 
         public void addEvents(final List<EntitlementEvent> newEvents) {
-            for (EntitlementEvent cur : newEvents) {
+            for (final EntitlementEvent cur : newEvents) {
                 events.add(new EntitlementEventWithOrderingId(cur, curOrderingId++));
             }
         }
@@ -141,26 +144,23 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
+    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         final SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
         return new LinkedList<EntitlementEvent>(target.getEvents());
     }
 
     @Override
-    public void createSubscription(final SubscriptionData subscription,
-                                   final List<EntitlementEvent> createEvents, final CallContext context) {
+    public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> createEvents, final InternalCallContext context) {
         addEvents(subscription.getId(), createEvents);
     }
 
     @Override
-    public void recreateSubscription(final SubscriptionData subscription,
-                                     final List<EntitlementEvent> recreateEvents, final CallContext context) {
+    public void recreateSubscription(final SubscriptionData subscription, final List<EntitlementEvent> recreateEvents, final InternalCallContext context) {
         addEvents(subscription.getId(), recreateEvents);
     }
 
     @Override
-    public void cancelSubscription(final SubscriptionData subscription,
-                                   final EntitlementEvent cancelEvent, final CallContext context, final int cancelSeq) {
+    public void cancelSubscription(final SubscriptionData subscription, final EntitlementEvent cancelEvent, final InternalCallContext context, final int cancelSeq) {
         final UUID subscriptionId = subscription.getId();
         final long activeVersion = cancelEvent.getActiveVersion();
         addEvents(subscriptionId, Collections.singletonList(cancelEvent));
@@ -176,13 +176,12 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public void changePlan(final SubscriptionData subscription,
-                           final List<EntitlementEvent> changeEvents, final CallContext context) {
+    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents, final InternalCallContext context) {
         addEvents(subscription.getId(), changeEvents);
     }
 
     @Override
-    public void initializeRepair(final UUID subscriptionId, final List<EntitlementEvent> initialEvents) {
+    public void initializeRepair(final UUID subscriptionId, final List<EntitlementEvent> initialEvents, final InternalTenantContext context) {
         final Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
         if (map.get(subscriptionId) == null) {
             final SubscriptionRepairEvent value = new SubscriptionRepairEvent(initialEvents);
@@ -193,7 +192,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public void cleanup() {
+    public void cleanup(final InternalTenantContext context) {
         final Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
         map.clear();
     }
@@ -204,110 +203,99 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public void uncancelSubscription(final SubscriptionData subscription,
-                                     final List<EntitlementEvent> uncancelEvents, final CallContext context) {
+    public void uncancelSubscription(final SubscriptionData subscription, final List<EntitlementEvent> uncancelEvents, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey) {
+    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId) {
+    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public SubscriptionBundle createSubscriptionBundle(
-            final SubscriptionBundleData bundle, final CallContext context) {
+    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory,
-                                              final UUID subscriptionId) {
+    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory,
-                                            final UUID bundleId) {
+    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory,
-                                               final UUID bundleId) {
+    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey) {
+    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId,
+                                                               final String bundleKey, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public void updateChargedThroughDate(final SubscriptionData subscription,
-                                         final CallContext context) {
+    public void updateChargedThroughDate(final SubscriptionData subscription, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public void createNextPhaseEvent(final SubscriptionData subscription,
-                                     final EntitlementEvent nextPhase, final CallContext context) {
+    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public EntitlementEvent getEventById(final UUID eventId) {
+    public EntitlementEvent getEventById(final UUID eventId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<EntitlementEvent> getPendingEventsForSubscription(
-            final UUID subscriptionId) {
+    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public void migrate(final UUID accountId, final AccountMigrationData data,
-                        final CallContext context) {
+    public void migrate(final UUID accountId, final AccountMigrationData data, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair,
-                       final CallContext context) {
+    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public void transfer(UUID srcAccountId, UUID destAccountId,
-            BundleMigrationData data,
-            List<TransferCancelData> transferCancelData, CallContext context) {
+    public void transfer(final UUID srcAccountId, final UUID destAccountId, final BundleMigrationData data,
+                         final List<TransferCancelData> transferCancelData, final InternalCallContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundlesForKey(
-            String bundleKey) {
+    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
index 5debc59..fec77f7 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
@@ -40,41 +40,46 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
 
 @ExternalizedSqlViaStringTemplate3()
 public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, AuditSqlDao, CloseMe, Transmogrifier {
+
     @SqlUpdate
     public void insertSubscription(@Bind(binder = SubscriptionBinder.class) SubscriptionData sub,
-                                   @CallContextBinder final CallContext context);
+                                   @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     @Mapper(SubscriptionMapper.class)
-    public Subscription getSubscriptionFromId(@Bind("id") String id);
+    public Subscription getSubscriptionFromId(@Bind("id") String id,
+                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @Mapper(SubscriptionMapper.class)
-    public List<Subscription> getSubscriptionsFromBundleId(@Bind("bundleId") String bundleId);
+    public List<Subscription> getSubscriptionsFromBundleId(@Bind("bundleId") String bundleId,
+                                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     public void updateChargedThroughDate(@Bind("id") String id, @Bind("chargedThroughDate") Date chargedThroughDate,
-                                         @CallContextBinder final CallContext context);
+                                         @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     void updateActiveVersion(@Bind("id") String id, @Bind("activeVersion") long activeVersion,
-                             @CallContextBinder final CallContext context);
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void updateForRepair(@Bind("id") String id, @Bind("activeVersion") long activeVersion,
                                 @Bind("startDate") Date startDate,
                                 @Bind("bundleStartDate") Date bundleStartDate,
-                                @CallContextBinder final CallContext context);
+                                @InternalTenantContextBinder final InternalCallContext context);
 
     public static class SubscriptionBinder extends BinderBase implements Binder<Bind, SubscriptionData> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final SubscriptionData sub) {
             stmt.bind("id", sub.getId().toString());
@@ -89,6 +94,7 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, A
     }
 
     public static class SubscriptionMapper extends MapperBase implements ResultSetMapper<SubscriptionData> {
+
         @Override
         public SubscriptionData map(final int arg0, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
index 0d3fd20..c5e035f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
@@ -18,8 +18,6 @@ package com.ning.billing.entitlement.glue;
 
 import org.skife.config.ConfigurationObjectFactory;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.name.Names;
 import com.ning.billing.config.EntitlementConfig;
 import com.ning.billing.entitlement.alignment.MigrationPlanAligner;
 import com.ning.billing.entitlement.alignment.PlanAligner;
@@ -49,6 +47,9 @@ import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
 import com.ning.billing.glue.EntitlementModule;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.name.Names;
+
 public class DefaultEntitlementModule extends AbstractModule implements EntitlementModule {
 
     public static final String REPAIR_NAMED = "repair";
diff --git a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/BundleSqlDao.sql.stg b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/BundleSqlDao.sql.stg
index e4d5a68..84fe7d3 100644
--- a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/BundleSqlDao.sql.stg
+++ b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/BundleSqlDao.sql.stg
@@ -1,15 +1,20 @@
 group BundleSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>id,
     <prefix>external_key,
     <prefix>account_id,
-    <prefix>last_sys_update_date
+    <prefix>last_sys_update_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertBundle() ::= <<
     insert into bundles (<fields()>)
-    values (:id, :externalKey, :accountId, :lastSysUpdateDate);
+    values (:id, :externalKey, :accountId, :lastSysUpdateDate, :accountRecordId, :tenantRecordId);
 >>
 
 updateBundleLastSysTime()  ::= <<
@@ -17,6 +22,7 @@ updateBundleLastSysTime()  ::= <<
     set
         last_sys_update_date = :lastSysUpdateDate
     where id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -25,6 +31,7 @@ getBundleFromId() ::= <<
     from bundles
     where
       id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -33,6 +40,7 @@ getBundlesForKey() ::= <<
     from bundles
     where
       external_key = :externalKey
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -41,6 +49,7 @@ getBundleFromAccountAndKey() ::= <<
     from bundles
     where
       external_key = :externalKey AND account_id = :accountId
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -49,13 +58,16 @@ getBundleFromAccount() ::= <<
     from bundles
     where
       account_id = :accountId
+    <AND_CHECK_TENANT()>
     ;
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM bundles
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -66,10 +78,12 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
diff --git a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.sql.stg b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.sql.stg
index f10428d..b8d63d3 100644
--- a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.sql.stg
+++ b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group EventSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>id,
     <prefix>event_type,
@@ -16,7 +19,9 @@ fields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 getEventById() ::= <<
@@ -24,6 +29,7 @@ getEventById() ::= <<
   from subscription_events
   where
       id = :id
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -46,7 +52,9 @@ insertEvent() ::= <<
     , :createdDate
     , :userName
     , :updatedDate
-    );   
+    , :accountRecordId
+    , :tenantRecordId
+    );
 >>
 
 updateVersion() ::= <<
@@ -55,6 +63,7 @@ updateVersion() ::= <<
       current_version = :currentVersion
     where
       id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -66,6 +75,7 @@ unactiveEvent() ::= <<
       , updated_date = :updatedDate
     where
       id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -77,6 +87,7 @@ reactiveEvent() ::= <<
       , updated_date = :updatedDate
     where
       event_id = :eventId
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -88,6 +99,7 @@ getFutureActiveEventForSubscription() ::= <<
       subscription_id = :subscriptionId
       and is_active = 1
       and effective_date > :now
+    <AND_CHECK_TENANT()>
     order by
       effective_date asc
       , record_id asc
@@ -99,6 +111,7 @@ getEventsForSubscription() ::= <<
     from subscription_events
     where
       subscription_id = :subscriptionId
+    <AND_CHECK_TENANT()>
     order by
       effective_date asc
       , record_id asc
@@ -108,7 +121,9 @@ getEventsForSubscription() ::= <<
 getRecordId() ::= <<
     SELECT record_id
     FROM subscription_events
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -119,12 +134,14 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 
diff --git a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.sql.stg b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.sql.stg
index 6d57415..17e9c89 100644
--- a/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.sql.stg
+++ b/entitlement/src/main/resources/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group SubscriptionSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 insertSubscription() ::= <<
     insert into subscriptions (
         id
@@ -14,6 +17,8 @@ insertSubscription() ::= <<
       , created_date
       , updated_by
       , updated_date
+      , account_record_id
+      , tenant_record_id
     ) values (
         :id
       , :bundleId
@@ -27,6 +32,8 @@ insertSubscription() ::= <<
       , :createdDate
       , :userName
       , :updatedDate
+      , :accountRecordId
+      , :tenantRecordId
     );
 >>
 
@@ -42,6 +49,7 @@ getSubscriptionFromId() ::= <<
       , paid_through_date    
     from subscriptions
     where id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -57,6 +65,7 @@ getSubscriptionsFromBundleId() ::= <<
       , paid_through_date    
     from subscriptions
     where bundle_id = :bundleId
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -67,6 +76,7 @@ updateChargedThroughDate() ::= <<
       , updated_by = :userName
       , updated_date = :updatedDate
     where id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
@@ -89,13 +99,16 @@ updateForRepair() ::= <<
       , updated_by = :userName
       , updated_date = :updatedDate
     where id = :id
+    <AND_CHECK_TENANT()>
     ;
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM subscriptions
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -106,10 +119,12 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/alignment/TestPlanAligner.java b/entitlement/src/test/java/com/ning/billing/entitlement/alignment/TestPlanAligner.java
index aafeb08..8ec636a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/alignment/TestPlanAligner.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/alignment/TestPlanAligner.java
@@ -26,8 +26,6 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.KillbillTestSuite;
 import com.ning.billing.catalog.DefaultCatalogService;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -47,6 +45,9 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
 public class TestPlanAligner extends KillbillTestSuite {
     private static final String priceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
index 0e6bfe2..db80a34 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
@@ -16,26 +16,18 @@
 
 package com.ning.billing.entitlement.api.migration;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.Assert;
 
 import com.ning.billing.api.TestApiListener.NextEvent;
-import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.TestApiBase;
 import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementAccountMigration;
-import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementBundleMigration;
-import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementSubscriptionMigration;
-import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementSubscriptionMigrationCase;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
@@ -54,14 +46,14 @@ public abstract class TestMigration extends TestApiBase {
             final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 1);
             final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
@@ -88,14 +80,14 @@ public abstract class TestMigration extends TestApiBase {
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 2);
 
             final Subscription baseSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) ?
@@ -135,15 +127,15 @@ public abstract class TestMigration extends TestApiBase {
             final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
             //assertEquals(bundle.getStartDate(), effectiveDate);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 1);
             final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
@@ -181,14 +173,14 @@ public abstract class TestMigration extends TestApiBase {
             final EntitlementAccountMigration toBeMigrated = createAccountForMigrationFuturePendingPhase(trialDate);
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 1);
             final Subscription subscription = subscriptions.get(0);
 
@@ -228,14 +220,14 @@ public abstract class TestMigration extends TestApiBase {
             final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 1);
             final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
index e07e1c1..f0bfaaa 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.migration;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestMigrationMemory extends TestMigration {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
index 2d0b100..a9b15b0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.migration;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestMigrationSql extends TestMigration {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index eb52dec..ffe6463 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.entitlement.api;
 
-import javax.annotation.Nullable;
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -24,6 +23,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.Period;
@@ -36,8 +37,6 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 
-import com.google.inject.Injector;
-import com.google.inject.Key;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.api.TestApiListener;
@@ -55,7 +54,6 @@ import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.api.TimeUnit;
 import com.ning.billing.config.EntitlementConfig;
-import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
 import com.ning.billing.entitlement.api.billing.ChargeThruApi;
 import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi;
@@ -80,18 +78,20 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.mock.MockAccountBuilder;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TestCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.Injector;
+import com.google.inject.Key;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB implements TestListenerStatus {
+
     protected static final Logger log = LoggerFactory.getLogger(TestApiBase.class);
 
     protected EntitlementService entitlementService;
@@ -113,9 +113,6 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
     protected TestApiListener testListener;
     protected SubscriptionBundle bundle;
 
-    private MysqlTestingHelper helper;
-    protected CallContext context = new TestCallContext("Api Test");
-
     private boolean isListenerFailed;
     private String listenerFailedMsg;
 
@@ -175,7 +172,6 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
         config = g.getInstance(EntitlementConfig.class);
         dao = g.getInstance(EntitlementDao.class);
         clock = (ClockMock) g.getInstance(Clock.class);
-        helper = (isSqlTest(dao)) ? g.getInstance(MysqlTestingHelper.class) : null;
         init();
     }
 
@@ -239,7 +235,7 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
 
         // CREATE NEW BUNDLE FOR TEST
         final UUID accountId = UUID.randomUUID();
-        bundle = entitlementApi.createBundleForAccount(accountId, "myDefaultBundle", context);
+        bundle = entitlementApi.createBundleForAccount(accountId, "myDefaultBundle", callContext);
         assertNotNull(bundle);
     }
 
@@ -277,14 +273,14 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
         testListener.pushExpectedEvent(NextEvent.CREATE);
         final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundleId,
                                                                                                    new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSet, null),
-                                                                                                   requestedDate == null ? clock.getUTCNow() : requestedDate, context);
+                                                                                                   requestedDate == null ? clock.getUTCNow() : requestedDate, callContext);
         assertNotNull(subscription);
         assertTrue(testListener.isCompleted(5000));
         return subscription;
     }
 
     protected void checkNextPhaseChange(final SubscriptionData subscription, final int expPendingEvents, final DateTime expPhaseChange) {
-        final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+        final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalCallContext);
         assertNotNull(events);
         printEvents(events);
         assertEquals(events.size(), expPendingEvents);
@@ -407,10 +403,11 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
         }
     }
 
-
-    /**************************************************************
-        Utilities for migration tests
-    ***************************************************************/
+    /**
+     * ***********************************************************
+     * Utilities for migration tests
+     * *************************************************************
+     */
 
     protected EntitlementAccountMigration createAccountForMigrationTest(final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> cases) {
         return new EntitlementAccountMigration() {
@@ -555,6 +552,7 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
     }
 
     public static class EntitlementSubscriptionMigrationCaseWithCTD implements EntitlementSubscriptionMigrationCase {
+
         private final PlanPhaseSpecifier pps;
         private final DateTime effDt;
         private final DateTime cancelDt;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index 0593c2a..d23ae9a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -25,9 +25,6 @@ import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -48,12 +45,17 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionEvents;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 public class TestRepairBP extends TestApiBaseRepair {
+
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
@@ -74,7 +76,7 @@ public class TestRepairBP extends TestApiBaseRepair {
 
         final SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         final List<SubscriptionTimeline> subscriptionRepair = bundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 2);
 
@@ -134,7 +136,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(10));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
@@ -147,7 +149,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         sortEventsOnBundle(dryRunBundleRepair);
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
@@ -165,7 +167,7 @@ public class TestRepairBP extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, events.get(index++));
         }
 
-        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
@@ -184,7 +186,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
@@ -195,7 +197,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         for (final ExistingEvent e : expected) {
             validateExistingEventForAssertion(e, events.get(index++));
         }
-        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), 2);
 
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -249,7 +251,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         assertTrue(testListener.isCompleted(5000));
 
         // CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
-        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId, callContext);
 
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(subscription.getBundleId(), bundle.getId());
@@ -306,7 +308,7 @@ public class TestRepairBP extends TestApiBaseRepair {
             }
         }
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         final DateTime newCreateTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
@@ -324,7 +326,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
         SubscriptionTimeline cur = subscriptionRepair.get(0);
@@ -336,7 +338,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         for (final ExistingEvent e : expectedEvents) {
             validateExistingEventForAssertion(e, events.get(index++));
         }
-        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
@@ -359,7 +361,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
@@ -375,7 +377,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         for (final ExistingEvent e : expectedEvents) {
             validateExistingEventForAssertion(e, events.get(index++));
         }
-        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), 2);
 
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -419,7 +421,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
-        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId, callContext);
 
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(subscription.getBundleId(), bundle.getId());
@@ -476,7 +478,7 @@ public class TestRepairBP extends TestApiBaseRepair {
             assertTrue(testListener.isCompleted(5000));
         }
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         final DateTime changeTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
@@ -494,7 +496,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
 
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
@@ -507,7 +509,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         for (final ExistingEvent e : expectedEvents) {
             validateExistingEventForAssertion(e, events.get(index++));
         }
-        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
@@ -530,7 +532,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
@@ -544,7 +546,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         for (final ExistingEvent e : expectedEvents) {
             validateExistingEventForAssertion(e, events.get(index++));
         }
-        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), expectedTransitions);
 
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -583,11 +585,11 @@ public class TestRepairBP extends TestApiBaseRepair {
 
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
         final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-        baseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+        baseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         final DateTime requestedChange = clock.getUTCNow();
-        baseSubscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, context);
+        baseSubscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, callContext);
 
         // CHECK CHANGE DID NOT OCCUR YET
         Plan currentPlan = baseSubscription.getCurrentPlan();
@@ -597,7 +599,7 @@ public class TestRepairBP extends TestApiBaseRepair {
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
         final DateTime repairTime = clock.getUTCNow().minusDays(1);
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
@@ -613,10 +615,10 @@ public class TestRepairBP extends TestApiBaseRepair {
 
         final boolean dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        repairApi.repairBundle(bRepair, dryRun, context);
+        repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
-        baseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        baseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         assertEquals(((SubscriptionData) baseSubscription).getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(baseSubscription.getBundleId(), bundle.getId());
@@ -647,7 +649,7 @@ public class TestRepairBP extends TestApiBaseRepair {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -660,10 +662,10 @@ public class TestRepairBP extends TestApiBaseRepair {
 
                 testListener.pushExpectedEvent(NextEvent.CHANGE);
                 final DateTime changeTime = clock.getUTCNow();
-                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
+                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, callContext);
                 assertTrue(testListener.isCompleted(5000));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
                 assertListenerStatus();
             }
         }, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
@@ -680,7 +682,7 @@ public class TestRepairBP extends TestApiBaseRepair {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -696,10 +698,10 @@ public class TestRepairBP extends TestApiBaseRepair {
                 // Move clock at least a sec to make sure the last_sys_update from bundle is different-- and therefore generates a different viewId
                 clock.setDeltaFromReality(1000);
 
-                billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-                entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+                billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+                entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
 
                 assertListenerStatus();
             }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
index c1159c6..7b92f4d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
@@ -24,9 +24,6 @@ import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
@@ -44,11 +41,16 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionEvents;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public class TestRepairWithAO extends TestApiBaseRepair {
+
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
@@ -75,7 +77,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -101,7 +103,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
@@ -146,24 +148,24 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+        SubscriptionData newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId(), callContext);
         assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -187,17 +189,17 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+        newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId(), callContext);
         assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -226,7 +228,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(7000));
 
-        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -246,7 +248,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -280,19 +282,19 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -311,12 +313,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -347,10 +349,10 @@ public class TestRepairWithAO extends TestApiBaseRepair {
 
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
         final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-        baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+        baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
-        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -366,7 +368,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -401,19 +403,19 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -432,12 +434,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -450,12 +452,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(7000));
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -480,7 +482,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -501,7 +503,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
@@ -518,19 +520,19 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         for (final ExistingEvent e : expected) {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -540,12 +542,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -570,7 +572,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -593,7 +595,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
@@ -607,7 +609,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         for (final ExistingEvent e : expected) {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getStartDate(), aoSubscription.getStartDate());
@@ -616,7 +618,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         // NOW COMMIT
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -626,7 +628,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getStartDate(), aoRecreateDate);
@@ -661,7 +663,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
         sortEventsOnBundle(bundleRepair);
 
         // Quick check
@@ -682,7 +684,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
 
         boolean dryRun = true;
-        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -700,14 +702,14 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         for (final ExistingEvent e : expected) {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
 
         // AND NOW COMMIT
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, callContext);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -717,7 +719,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
             validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
 
@@ -741,7 +743,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
 
-        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
         currentPhase = newAoSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
index 83d2f1e..3ddf408 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
@@ -26,9 +26,6 @@ import org.joda.time.Interval;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -44,6 +41,10 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
@@ -78,7 +79,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 assertTrue(testListener.isCompleted(5000));
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -87,7 +88,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
             }
         }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING);
     }
@@ -103,7 +104,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 testListener.pushExpectedEvent(NextEvent.CHANGE);
                 final DateTime changeTime = clock.getUTCNow();
-                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
+                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, callContext);
                 assertTrue(testListener.isCompleted(5000));
 
                 // MOVE AFTER TRIAL
@@ -112,7 +113,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 clock.addDeltaFromReality(it.toDurationMillis());
                 assertTrue(testListener.isCompleted(5000));
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -121,7 +122,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.singletonList(de), Collections.singletonList(ne));
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
             }
         }, ErrorCode.ENT_REPAIR_INVALID_DELETE_SET);
     }
@@ -132,7 +133,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
             @Override
             public void doTest() throws EntitlementRepairException {
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -141,7 +142,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
             }
         }, ErrorCode.ENT_REPAIR_NON_EXISTENT_DELETE_EVENT);
     }
@@ -158,7 +159,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 clock.addDeltaFromReality(it.toDurationMillis());
                 assertTrue(testListener.isCompleted(5000));
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -168,7 +169,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
 
             }
         }, ErrorCode.ENT_REPAIR_SUB_RECREATE_NOT_EMPTY);
@@ -187,7 +188,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 clock.addDeltaFromReality(it.toDurationMillis());
                 assertTrue(testListener.isCompleted(5000));
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
                 final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
@@ -198,7 +199,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                repairApi.repairBundle(bRepair, true, context);
+                repairApi.repairBundle(bRepair, true, callContext);
             }
         }, ErrorCode.ENT_REPAIR_SUB_EMPTY);
     }
@@ -217,7 +218,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
 
                 // Quick check
@@ -240,7 +241,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
 
                 final boolean dryRun = true;
-                repairApi.repairBundle(bRepair, dryRun, context);
+                repairApi.repairBundle(bRepair, dryRun, callContext);
             }
         }, ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START);
     }
@@ -260,7 +261,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
 
-                BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
 
                 // Quick check
@@ -281,7 +282,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
 
                 final boolean dryRun = true;
-                repairApi.repairBundle(bundleRepair, dryRun, context);
+                repairApi.repairBundle(bundleRepair, dryRun, callContext);
             }
         }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING);
     }
@@ -300,7 +301,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 final SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
-                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
                 sortEventsOnBundle(bundleRepair);
 
                 final DateTime newCreateTime = baseSubscription.getStartDate().plusDays(3);
@@ -318,7 +319,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 final boolean dryRun = true;
-                repairApi.repairBundle(bRepair, dryRun, context);
+                repairApi.repairBundle(bRepair, dryRun, callContext);
             }
         }, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO);
     }
@@ -366,7 +367,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 BundleRepair bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), allRepairs);
                 
                 boolean dryRun = true;
-                repairApi.repairBundle(bRepair, dryRun, context);
+                repairApi.repairBundle(bRepair, dryRun, callContext);
                 */
             }
         }, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE);
@@ -394,7 +395,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 assertTrue(testListener.isCompleted(5000));
 
                 DateTime requestedChange = clock.getUTCNow();
-                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, context);
+                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, callContext);
 
                 DateTime reapairTime = clock.getUTCNow().minusDays(1);
 
@@ -417,7 +418,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), allRepairs);
                 
                 boolean dryRun = false;
-                repairApi.repairBundle(bundleRepair, dryRun, context);
+                repairApi.repairBundle(bundleRepair, dryRun, callContext);
                 */
             }
         }, ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
index 146db74..fb65d93 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
@@ -15,11 +15,6 @@
  */
 package com.ning.billing.entitlement.api.transfer;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.List;
 import java.util.UUID;
 
@@ -29,9 +24,6 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
@@ -40,14 +32,23 @@ import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.TestApiBase;
-import com.ning.billing.entitlement.api.migration.EntitlementMigrationApiException;
 import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementAccountMigration;
+import com.ning.billing.entitlement.api.migration.EntitlementMigrationApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestTransfer extends TestApiBase {
 
     protected static final Logger log = LoggerFactory.getLogger(TestTransfer.class);
@@ -72,14 +73,14 @@ public class TestTransfer extends TestApiBase {
             final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
-            migrationApi.migrate(toBeMigrated, context);
+            migrationApi.migrate(toBeMigrated, callContext);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey(), callContext);
             assertEquals(bundles.size(), 1);
             final SubscriptionBundle bundle = bundles.get(0);
 
-            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), callContext);
             assertEquals(subscriptions.size(), 1);
             final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
@@ -103,10 +104,10 @@ public class TestTransfer extends TestApiBase {
 
             testListener.pushExpectedEvent(NextEvent.TRANSFER);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, true, context);
+            transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, true, callContext);
             assertTrue(testListener.isCompleted(3000));
 
-            final Subscription oldBaseSubscription = entitlementApi.getBaseSubscription(bundle.getId());
+            final Subscription oldBaseSubscription = entitlementApi.getBaseSubscription(bundle.getId(), callContext);
             assertTrue(oldBaseSubscription.getState() == SubscriptionState.CANCELLED);
             // The MIGRATE_BILLING event should have been invalidated
             assertEquals(oldBaseSubscription.getBillingTransitions().size(), 1);
@@ -141,20 +142,20 @@ public class TestTransfer extends TestApiBase {
 
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
         testListener.pushExpectedEvent(NextEvent.CANCEL);
-        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, context);
+        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, callContext);
         assertTrue(testListener.isCompleted(3000));
         final DateTime afterTransferDate = clock.getUTCNow();
 
         // CHECK OLD BASE IS CANCEL AT THE TRANSFER DATE
-        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertNotNull(oldBaseSubscription.getEndDate());
         assertDateWithin(oldBaseSubscription.getEndDate(), beforeTransferDate, afterTransferDate);
         assertTrue(oldBaseSubscription.getEndDate().compareTo(transferRequestedDate) == 0);
 
-        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION SARTING ON TRANSFER_DATE
-        SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey());
+        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION STARTING ON TRANSFER_DATE
+        final SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey(), callContext);
 
-        List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId());
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId(), callContext);
         assertEquals(subscriptions.size(), 1);
 
         final Subscription newBaseSubscription = subscriptions.get(0);
@@ -164,7 +165,7 @@ public class TestTransfer extends TestApiBase {
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertTrue(newBaseSubscription.getAllTransitions().get(1).getEffectiveTransitionTime().compareTo(evergreenPhaseDate) == 0);
 
-        Plan newPlan = newBaseSubscription.getCurrentPlan();
+        final Plan newPlan = newBaseSubscription.getCurrentPlan();
         assertEquals(newPlan.getProduct().getName(), baseProduct);
         assertEquals(newBaseSubscription.getCurrentPhase().getPhaseType(), PhaseType.TRIAL);
     }
@@ -183,7 +184,7 @@ public class TestTransfer extends TestApiBase {
         final Subscription baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30);
 
-        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), context);
+        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), callContext);
 
         final DateTime evergreenPhaseDate = baseSubscription.getPendingTransition().getEffectiveTransitionTime();
 
@@ -192,18 +193,18 @@ public class TestTransfer extends TestApiBase {
 
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
         final DateTime transferRequestedDate = clock.getUTCNow();
-        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, context);
+        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, callContext);
         assertTrue(testListener.isCompleted(3000));
 
         // CHECK OLD BASE IS CANCEL AT THE TRANSFER DATE
-        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertNotNull(oldBaseSubscription.getFutureEndDate());
         assertTrue(oldBaseSubscription.getFutureEndDate().compareTo(ctd) == 0);
 
-        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION SARTING ON TRANSFER_DATE
-        SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey());
+        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION STARTING ON TRANSFER_DATE
+        final SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey(), callContext);
 
-        List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId());
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId(), callContext);
         assertEquals(subscriptions.size(), 1);
 
         final Subscription newBaseSubscription = subscriptions.get(0);
@@ -213,7 +214,7 @@ public class TestTransfer extends TestApiBase {
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertTrue(newBaseSubscription.getAllTransitions().get(1).getEffectiveTransitionTime().compareTo(evergreenPhaseDate) == 0);
 
-        Plan newPlan = newBaseSubscription.getCurrentPlan();
+        final Plan newPlan = newBaseSubscription.getCurrentPlan();
         assertEquals(newPlan.getProduct().getName(), baseProduct);
         assertEquals(newBaseSubscription.getCurrentPhase().getPhaseType(), PhaseType.TRIAL);
     }
@@ -240,20 +241,20 @@ public class TestTransfer extends TestApiBase {
         final DateTime transferRequestedDate = clock.getUTCNow();
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
         testListener.pushExpectedEvent(NextEvent.CANCEL);
-        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, context);
+        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, callContext);
         assertTrue(testListener.isCompleted(3000));
         final DateTime afterTransferDate = clock.getUTCNow();
 
         // CHECK OLD BASE IS CANCEL AT THE TRANSFER DATE
-        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertNotNull(oldBaseSubscription.getEndDate());
         assertDateWithin(oldBaseSubscription.getEndDate(), beforeTransferDate, afterTransferDate);
         assertTrue(oldBaseSubscription.getEndDate().compareTo(transferRequestedDate) == 0);
 
-        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION SARTING ON TRANSFER_DATE
-        SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey());
+        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION STARTING ON TRANSFER_DATE
+        final SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey(), callContext);
 
-        List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId());
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId(), callContext);
         assertEquals(subscriptions.size(), 1);
 
         final Subscription newBaseSubscription = subscriptions.get(0);
@@ -262,7 +263,7 @@ public class TestTransfer extends TestApiBase {
         // CHECK ONLY ONE PHASE EXISTS
         assertEquals(newBaseSubscription.getAllTransitions().size(), 1);
 
-        Plan newPlan = newBaseSubscription.getCurrentPlan();
+        final Plan newPlan = newBaseSubscription.getCurrentPlan();
         assertEquals(newPlan.getProduct().getName(), baseProduct);
         assertEquals(newBaseSubscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
     }
@@ -286,23 +287,23 @@ public class TestTransfer extends TestApiBase {
 
         // SET CTD
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), context);
+        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), callContext);
 
 
         final DateTime transferRequestedDate = clock.getUTCNow();
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
-        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, context);
+        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, false, false, callContext);
         assertTrue(testListener.isCompleted(3000));
 
         // CHECK OLD BASE IS CANCEL AT THE TRANSFER DATE
-        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final Subscription oldBaseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
         assertNotNull(oldBaseSubscription.getFutureEndDate());
         assertTrue(oldBaseSubscription.getFutureEndDate().compareTo(ctd) == 0);
 
-        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION SARTING ON TRANSFER_DATE
-        SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey());
+        // CHECK NEW BUNDLE EXIST, WITH ONE SUBSCRIPTION STARTING ON TRANSFER_DATE
+        final SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey(), callContext);
 
-        List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId());
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId(), callContext);
         assertEquals(subscriptions.size(), 1);
 
         final Subscription newBaseSubscription = subscriptions.get(0);
@@ -321,7 +322,7 @@ public class TestTransfer extends TestApiBase {
         final String newBaseProduct1 = "Assault-Rifle";
         final BillingPeriod newBaseTerm1 = BillingPeriod.ANNUAL;
         final DateTime changeDate1 = clock.getUTCNow();
-        newBaseSubscription.changePlan(newBaseProduct1, newBaseTerm1, basePriceList, changeDate1, context);
+        newBaseSubscription.changePlan(newBaseProduct1, newBaseTerm1, basePriceList, changeDate1, callContext);
 
         newPlan = newBaseSubscription.getCurrentPlan();
         assertEquals(newPlan.getProduct().getName(), newBaseProduct1);
@@ -330,14 +331,14 @@ public class TestTransfer extends TestApiBase {
         // SET CTD AND MAKE CHANGE EOT
         clock.addDays(2);
 
-        DateTime newCtd = newBaseSubscription.getStartDate().plusYears(1);
-        billingApi.setChargedThroughDate(newBaseSubscription.getId(), newCtd.toLocalDate(), context);
-        final Subscription newBaseSubscriptionWithCtd = entitlementApi.getSubscriptionFromId(newBaseSubscription.getId());
+        final DateTime newCtd = newBaseSubscription.getStartDate().plusYears(1);
+        billingApi.setChargedThroughDate(newBaseSubscription.getId(), newCtd.toLocalDate(), callContext);
+        final Subscription newBaseSubscriptionWithCtd = entitlementApi.getSubscriptionFromId(newBaseSubscription.getId(), callContext);
 
         final String newBaseProduct2 = "Pistol";
         final BillingPeriod newBaseTerm2 = BillingPeriod.ANNUAL;
         final DateTime changeDate2 = clock.getUTCNow();
-        newBaseSubscriptionWithCtd.changePlan(newBaseProduct2, newBaseTerm2, basePriceList, changeDate2, context);
+        newBaseSubscriptionWithCtd.changePlan(newBaseProduct2, newBaseTerm2, basePriceList, changeDate2, callContext);
 
         newPlan = newBaseSubscriptionWithCtd.getCurrentPlan();
         assertEquals(newPlan.getProduct().getName(), newBaseProduct1);
@@ -382,23 +383,23 @@ public class TestTransfer extends TestApiBase {
 
         // SET CTD TO TRIGGER CANCELLATION EOT
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), context);
+        billingApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), callContext);
 
         final DateTime transferRequestedDate = clock.getUTCNow();
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
-        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, true, false, context);
+        transferApi.transferBundle(bundle.getAccountId(), newAccountId, bundle.getKey(), transferRequestedDate, true, false, callContext);
         assertTrue(testListener.isCompleted(3000));
 
         // RETRIEVE NEW BUNDLE AND CHECK SUBSCRIPTIONS
-        SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey());
-        List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId());
+        final SubscriptionBundle newBundle = entitlementApi.getBundleForAccountAndKey(newAccountId, bundle.getKey(), callContext);
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(newBundle.getId(), callContext);
         assertEquals(subscriptions.size(), 3);
         boolean foundBP = false;
         boolean foundAO1 = false;
         boolean foundAO2 = false;
-        for (Subscription cur : subscriptions) {
-            Plan curPlan = cur.getCurrentPlan();
-            Product curProduct = curPlan.getProduct();
+        for (final Subscription cur : subscriptions) {
+            final Plan curPlan = cur.getCurrentPlan();
+            final Product curProduct = curPlan.getProduct();
             if (curProduct.getName().equals(baseProduct)) {
                 foundBP = true;
                 assertTrue(((SubscriptionData) cur).getAlignStartDate().compareTo(((SubscriptionData) baseSubscription).getAlignStartDate()) == 0);
@@ -431,7 +432,7 @@ public class TestTransfer extends TestApiBase {
         final UUID finalNewAccountId = UUID.randomUUID();
         final DateTime newTransferRequestedDate = clock.getUTCNow();
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
-        transferApi.transferBundle(newBundle.getAccountId(), finalNewAccountId, newBundle.getKey(), newTransferRequestedDate, true, false, context);
+        transferApi.transferBundle(newBundle.getAccountId(), finalNewAccountId, newBundle.getKey(), newTransferRequestedDate, true, false, callContext);
         assertTrue(testListener.isCompleted(3000));
 
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
index 3dd0927..64ca089 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
@@ -23,9 +23,6 @@ import org.joda.time.Interval;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -43,6 +40,10 @@ import com.ning.billing.entitlement.api.user.SubscriptionStatusDryRun.DryRunChan
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
@@ -71,7 +72,7 @@ public class TestUserApiAddOn extends TestApiBase {
             assertEquals(aoSubscription.getState(), SubscriptionState.ACTIVE);
 
             final DateTime now = clock.getUTCNow();
-            aoSubscription.cancel(now, context);
+            aoSubscription.cancel(now, callContext);
 
             testListener.reset();
             testListener.pushExpectedEvent(NextEvent.CANCEL);
@@ -115,14 +116,14 @@ public class TestUserApiAddOn extends TestApiBase {
             final Duration ctd = getDurationMonth(1);
             // Why not just use clock.getUTCNow().plusMonths(1) ?
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // FUTURE CANCELLATION
-            baseSubscription.cancel(now, context);
+            baseSubscription.cancel(now, callContext);
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS IS ACTIVE
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             assertEquals(aoSubscription.getState(), SubscriptionState.ACTIVE);
             assertTrue(aoSubscription.isSubscriptionFutureCancelled());
 
@@ -136,7 +137,7 @@ public class TestUserApiAddOn extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS IS CANCELLED
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
 
             assertListenerStatus();
@@ -175,15 +176,16 @@ public class TestUserApiAddOn extends TestApiBase {
             final DateTime now = clock.getUTCNow();
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON INCLUDED ADDON
             final String newBaseProduct = "Assault-Rifle";
             final BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
             final String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
+            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(),
+                                                                                                     newBaseProduct, now, callContext);
             assertEquals(aoStatus.size(), 1);
             assertEquals(aoStatus.get(0).getId(), aoSubscription.getId());
             assertEquals(aoStatus.get(0).getProductName(), aoProduct);
@@ -195,11 +197,11 @@ public class TestUserApiAddOn extends TestApiBase {
             testListener.reset();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, context);
+            baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, callContext);
             assertTrue(testListener.isCompleted(5000));
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS CANCELLED
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
 
             assertListenerStatus();
@@ -237,15 +239,16 @@ public class TestUserApiAddOn extends TestApiBase {
             final DateTime now = clock.getUTCNow();
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+            billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON AVAILABLE ADDON
             final String newBaseProduct = "Pistol";
             final BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
             final String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
+            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(),
+                                                                                                     newBaseProduct, now, callContext);
             assertEquals(aoStatus.size(), 1);
             assertEquals(aoStatus.get(0).getId(), aoSubscription.getId());
             assertEquals(aoStatus.get(0).getProductName(), aoProduct);
@@ -254,10 +257,10 @@ public class TestUserApiAddOn extends TestApiBase {
             assertEquals(aoStatus.get(0).getPriceList(), aoSubscription.getCurrentPriceList().getName());
             assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN);
 
-            baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, context);
+            baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, callContext);
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS IS ACTIVE
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             assertEquals(aoSubscription.getState(), SubscriptionState.ACTIVE);
             assertTrue(aoSubscription.isSubscriptionFutureCancelled());
 
@@ -270,7 +273,7 @@ public class TestUserApiAddOn extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS CANCELLED
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
 
             assertListenerStatus();
@@ -377,7 +380,7 @@ public class TestUserApiAddOn extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // CHECK EVERYTHING AGAIN
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
 
             aoCurrentPlan = aoSubscription.getCurrentPlan();
             assertNotNull(aoCurrentPlan);
@@ -389,7 +392,7 @@ public class TestUserApiAddOn extends TestApiBase {
             assertNotNull(aoCurrentPhase);
             assertEquals(aoCurrentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
-            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+            aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId(), callContext);
             aoPendingTranstion = aoSubscription.getPendingTransition();
             assertNull(aoPendingTranstion);
         } catch (EntitlementUserApiException e) {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 6e3becc..0ac6e09 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -64,7 +64,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
 
 
             // CANCEL in trial period to get IMM policy
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             currentPhase = subscription.getCurrentPhase();
             testListener.isCompleted(3000);
 
@@ -110,8 +110,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             assertEquals(subscription.getLastActiveProductName(), prod);
             assertEquals(subscription.getLastActivePriceListName(), planSet);
@@ -121,7 +121,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
             // CANCEL
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
@@ -131,7 +131,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
             assertEquals(subscription.getLastActiveBillingPeriod(), term.toString());
             assertEquals(subscription.getLastActiveCategoryName(), "BASE");
 
-            DateTime futureEndDate = subscription.getFutureEndDate();
+            final DateTime futureEndDate = subscription.getFutureEndDate();
             Assert.assertNotNull(futureEndDate);
 
             // MOVE TO EOT + RECHECK
@@ -186,7 +186,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.CANCEL);
 
             // CANCEL
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             assertTrue(testListener.isCompleted(5000));
 
             final PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -228,13 +228,13 @@ public abstract class TestUserApiCancel extends TestApiBase {
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CANCEL EOT
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
 
-            subscription.uncancel(context);
+            subscription.uncancel(callContext);
 
             // MOVE TO EOT + RECHECK
             testListener.pushExpectedEvent(NextEvent.UNCANCEL);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
index 60d978f..1494e35 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
@@ -18,11 +18,12 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
-import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestUserApiCancelMemory extends TestUserApiCancel {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
index 535add2..83d71b3 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
@@ -18,11 +18,12 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
-import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestUserApiCancelSql extends TestUserApiCancel {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index 577a776..58d6268 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -81,7 +81,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
 
             // CHANGE PLAN
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
+            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), callContext);
             assertTrue(testListener.isCompleted(5000));
 
             // CHECK CHANGE PLAN
@@ -118,13 +118,13 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             // SET CTD
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
 
             // RE READ SUBSCRIPTION + CHANGE PLAN
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
-            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
+            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
@@ -137,7 +137,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             checkNextPhaseChange(subscription, 2, nextExpectedPhaseChange);
 
             // ALSO VERIFY PENDING CHANGE EVENT
-            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalCallContext);
             assertTrue(events.get(0) instanceof ApiEvent);
 
             // MOVE TO EOT
@@ -146,7 +146,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
             currentPhase = subscription.getCurrentPhase();
             checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.DISCOUNT);
 
@@ -172,7 +172,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             clock.addDeltaFromReality(it.toDurationMillis());
 
             // CHANGE PLAN IMM
-            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
+            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), callContext);
             checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.TRIAL);
 
             assertTrue(testListener.isCompleted(5000));
@@ -221,17 +221,17 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             // SET CTD
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
 
             // RE READ SUBSCRIPTION + CHECK CURRENT PHASE
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
             PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             // CHANGE PLAN
             currentTime = clock.getUTCNow();
-            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
+            subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), callContext);
 
             checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.EVERGREEN);
 
@@ -302,19 +302,19 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CHANGE EOT
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
             // CHANGE
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertTrue(testListener.isCompleted(5000));
 
             final Plan currentPlan = subscription.getCurrentPlan();
@@ -350,20 +350,20 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CHANGE EOT
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Shotgun", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Shotgun", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
             // CHANGE EOT
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
@@ -400,7 +400,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(6));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
@@ -431,7 +431,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             // CHANGE IMMEDIATE TO A 3 PHASES PLAN
             testListener.reset();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertTrue(testListener.isCompleted(5000));
             testListener.reset();
 
@@ -455,7 +455,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.DISCOUNT);
 
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             final DateTime expectedNextPhaseDate = subscription.getStartDate().plusDays(30).plusMonths(6);
             final EffectiveSubscriptionEvent nextPhase = subscription.getPendingTransition();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
index 1bf654b..8e3a263 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
@@ -18,11 +18,12 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
-import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
index 406b575..ed4ad46 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
@@ -18,11 +18,12 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
-import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
index 9ab3af1..c6a4362 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
+import org.mockito.Mockito;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -34,6 +35,8 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.TestApiBase;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.DefaultClock;
 
 import static org.testng.Assert.assertEquals;
@@ -41,8 +44,12 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public abstract class TestUserApiCreate extends TestApiBase {
+
     private static final Logger log = LoggerFactory.getLogger(TestUserApiCreate.class);
 
+    private final InternalTenantContext internalTenantContext = Mockito.mock(InternalTenantContext.class);
+    private final TenantContext tenantContext = Mockito.mock(TenantContext.class);
+
     public void testCreateWithRequestedDate() {
         try {
             final DateTime init = clock.getUTCNow();
@@ -56,7 +63,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                                       getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                                       getProductSpecifier(productName, planSetName, term, null), requestedDate, callContext);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -85,7 +92,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                                       getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), context);
+                                                                                                       getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), callContext);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -123,7 +130,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
 
             final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
                                                                                                        getProductSpecifier(productName, planSetName, term, null),
-                                                                                                       clock.getUTCNow(), context);
+                                                                                                       clock.getUTCNow(), callContext);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -143,7 +150,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
             assertTrue(testListener.isCompleted(5000));
 
-            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalTenantContext);
             assertNotNull(events);
             printEvents(events);
             assertTrue(events.size() == 1);
@@ -177,7 +184,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
 
             // CREATE SUBSCRIPTION
             SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                                 getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
+                                                                                                 getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), callContext);
             assertNotNull(subscription);
 
             PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -200,7 +207,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), tenantContext);
             currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
@@ -220,7 +227,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                                       getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
+                                                                                                       getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), callContext);
             assertNotNull(subscription);
 
             assertListenerStatus();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
index a7cd464..6e06c1c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestUserApiCreateMemory extends TestUserApiCreate {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
index 64c436a..ebee85c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestUserApiCreateSql extends TestUserApiCreate {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
index 29e8a87..746f524 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
@@ -25,9 +25,6 @@ import org.joda.time.Interval;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Duration;
@@ -40,6 +37,10 @@ import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
@@ -80,7 +81,7 @@ public class TestUserApiDemos extends TestApiBase {
 
             /* STEP 2. CHANGE PLAN WHILE IN TRIAL */
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertTrue(testListener.isCompleted(5000));
 
             displayState(subscription.getId(), "STEP 2. CHANGED PLAN WHILE IN TRIAL");
@@ -100,12 +101,12 @@ public class TestUserApiDemos extends TestApiBase {
 
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
@@ -114,7 +115,7 @@ public class TestUserApiDemos extends TestApiBase {
             /* STEP 5. CHANGE AGAIN */
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
@@ -143,7 +144,7 @@ public class TestUserApiDemos extends TestApiBase {
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(6));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
@@ -159,7 +160,7 @@ public class TestUserApiDemos extends TestApiBase {
 
             /* STEP 8. CANCEL IMM (NO CTD) */
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
 
             displayState(subscription.getId(), "STEP 8.  CANCELLATION");
 
@@ -174,7 +175,7 @@ public class TestUserApiDemos extends TestApiBase {
         System.out.println("");
         System.out.println("******\t STEP " + stepMsg + " **************");
         try {
-            final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscriptionId);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscriptionId, callContext);
 
             final Plan currentPlan = subscription.getCurrentPlan();
             final PlanPhase currentPhase = subscription.getCurrentPhase();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
index f26bc35..21bc3d1 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
@@ -16,17 +16,16 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import javax.annotation.Nullable;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
+import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.ActionPolicy;
@@ -37,13 +36,21 @@ import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.entitlement.api.TestApiBase;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 public class TestUserApiError extends TestApiBase {
+
+    private final TenantContext tenantContext = Mockito.mock(TenantContext.class);
+
     @Override
     protected Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleMemory());
@@ -88,7 +95,7 @@ public class TestUserApiError extends TestApiBase {
         try {
             final SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
             try {
-                subscription.recreate(getProductSpecifier("Pistol", PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, null), clock.getUTCNow(), context);
+                subscription.recreate(getProductSpecifier("Pistol", PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, null), clock.getUTCNow(), callContext);
                 Assert.assertFalse(true);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_RECREATE_BAD_STATE.getCode());
@@ -102,7 +109,7 @@ public class TestUserApiError extends TestApiBase {
     public void testCreateSubscriptionAddOnNotAvailable() {
         try {
             final UUID accountId = UUID.randomUUID();
-            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
+            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", callContext);
             createSubscriptionWithBundle(aoBundle.getId(), "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
             tCreateSubscriptionInternal(aoBundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_AO_NOT_AVAILABLE);
         } catch (Exception e) {
@@ -115,7 +122,7 @@ public class TestUserApiError extends TestApiBase {
         log.info("Starting testCreateSubscriptionAddOnIncluded");
         try {
             final UUID accountId = UUID.randomUUID();
-            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
+            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", callContext);
             createSubscriptionWithBundle(aoBundle.getId(), "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
             tCreateSubscriptionInternal(aoBundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_AO_ALREADY_INCLUDED);
         } catch (Exception e) {
@@ -128,7 +135,7 @@ public class TestUserApiError extends TestApiBase {
         try {
             entitlementApi.createSubscription(bundleId,
                                               getProductSpecifier(productName, planSet, term, null),
-                                              clock.getUTCNow(), context);
+                                              clock.getUTCNow(), callContext);
             Assert.fail("Exception expected, error code: " + expected);
         } catch (EntitlementUserApiException e) {
             assertEquals(e.getCode(), expected.getCode());
@@ -146,9 +153,9 @@ public class TestUserApiError extends TestApiBase {
             final Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), context);
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), callContext);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_NON_ACTIVE.getCode());
                 try {
@@ -167,15 +174,15 @@ public class TestUserApiError extends TestApiBase {
         final Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
 
         try {
-            subscription.changePlanWithPolicy("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), ActionPolicy.ILLEGAL, context);
+            subscription.changePlanWithPolicy("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), ActionPolicy.ILLEGAL, callContext);
             Assert.fail();
         } catch (EntitlementError error) {
             assertTrue(true);
-            assertEquals(entitlementApi.getSubscriptionFromId(subscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
+            assertEquals(entitlementApi.getSubscriptionFromId(subscription.getId(), tenantContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
         }
 
-        assertTrue(subscription.changePlanWithPolicy("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), ActionPolicy.IMMEDIATE, context));
-        assertEquals(entitlementApi.getSubscriptionFromId(subscription.getId()).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
+        assertTrue(subscription.changePlanWithPolicy("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), ActionPolicy.IMMEDIATE, callContext));
+        assertEquals(entitlementApi.getSubscriptionFromId(subscription.getId(), tenantContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
     }
 
     @Test(groups = "fast")
@@ -195,13 +202,13 @@ public class TestUserApiError extends TestApiBase {
             final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             final Duration ctd = getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
 
-            subscription = entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = entitlementApi.getSubscriptionFromId(subscription.getId(), tenantContext);
 
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), context);
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), callContext);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_FUTURE_CANCELLED.getCode());
                 try {
@@ -227,7 +234,7 @@ public class TestUserApiError extends TestApiBase {
             final Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             try {
-                subscription.uncancel(context);
+                subscription.uncancel(callContext);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_UNCANCEL_BAD_STATE.getCode());
                 try {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
index f2d7f22..4bd593c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
@@ -16,9 +16,10 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import com.google.inject.Injector;
 import com.ning.billing.entitlement.api.TestApiBase;
 
+import com.google.inject.Injector;
+
 public class TestUserApiPriceList extends TestApiBase {
     @Override
     protected Injector getInjector() {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
index 026f262..d3c4158 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
@@ -64,7 +64,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
         testListener.pushExpectedEvent(NextEvent.PHASE);
         testListener.pushExpectedEvent(NextEvent.CREATE);
         SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                             getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                             getProductSpecifier(productName, planSetName, term, null), requestedDate, callContext);
         assertNotNull(subscription);
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(subscription.getBundleId(), bundle.getId());
@@ -81,9 +81,9 @@ public abstract class TestUserApiRecreate extends TestApiBase {
 
             if (fromUserAPi) {
                 subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                    getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                    getProductSpecifier(productName, planSetName, term, null), requestedDate, callContext);
             } else {
-                subscription.recreate(getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                subscription.recreate(getProductSpecifier(productName, planSetName, term, null), requestedDate, callContext);
             }
             Assert.fail("Expected Create API to fail since BP already exists");
         } catch (EntitlementUserApiException e) {
@@ -92,7 +92,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
 
         // NOW CANCEL ADN THIS SHOULD WORK
         testListener.pushExpectedEvent(NextEvent.CANCEL);
-        subscription.cancel(null, context);
+        subscription.cancel(null, callContext);
 
         testListener.pushExpectedEvent(NextEvent.PHASE);
         testListener.pushExpectedEvent(NextEvent.RE_CREATE);
@@ -106,9 +106,9 @@ public abstract class TestUserApiRecreate extends TestApiBase {
 
         if (fromUserAPi) {
             subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                                                                                getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                getProductSpecifier(productName, planSetName, term, null), requestedDate, callContext);
         } else {
-            subscription.recreate(getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
+            subscription.recreate(getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), callContext);
         }
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(subscription.getBundleId(), bundle.getId());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
index e033b2e..70d6d87 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestUserApiRecreateMemory extends TestUserApiRecreate {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
index 5dfcea1..4c1b753 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
@@ -18,10 +18,11 @@ package com.ning.billing.entitlement.api.user;
 
 import org.testng.annotations.Test;
 
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestUserApiRecreateSql extends TestUserApiRecreate {
     @Override
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
index 8859d69..326aade 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
@@ -21,9 +21,6 @@ import org.joda.time.Interval;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Duration;
@@ -34,6 +31,10 @@ import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
@@ -52,7 +53,7 @@ public class TestUserApiScenarios extends TestApiBase {
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), callContext);
             testListener.isCompleted(5000);
 
             // MOVE TO NEXT PHASE
@@ -65,23 +66,23 @@ public class TestUserApiScenarios extends TestApiBase {
             final Duration ctd = getDurationMonth(1);
             final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), context);
-            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), callContext);
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CANCEL EOT
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            subscription.cancel(clock.getUTCNow(), context);
+            subscription.cancel(clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(5000));
             testListener.reset();
 
             // UNCANCEL
-            subscription.uncancel(context);
+            subscription.uncancel(callContext);
 
             // CHANGE EOT
             testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
+            subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), callContext);
             assertFalse(testListener.isCompleted(5000));
             testListener.reset();
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index 8463775..2567e37 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -31,7 +31,6 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.api.TimeUnit;
@@ -52,15 +51,18 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
+import com.google.inject.Inject;
 
 public class MockEntitlementDaoMemory implements EntitlementDao {
+
     protected static final Logger log = LoggerFactory.getLogger(EntitlementDao.class);
 
     private final List<SubscriptionBundle> bundles;
@@ -90,7 +92,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId, final InternalTenantContext context) {
         final List<SubscriptionBundle> results = new ArrayList<SubscriptionBundle>();
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getAccountId().equals(accountId)) {
@@ -101,7 +103,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey) {
+    public List<SubscriptionBundle> getSubscriptionBundlesForKey(final String bundleKey, final InternalTenantContext context) {
         final List<SubscriptionBundle> results = new ArrayList<SubscriptionBundle>();
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getKey().equals(bundleKey)) {
@@ -111,9 +113,8 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
         return results;
     }
 
-
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId) {
+    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId, final InternalTenantContext context) {
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getId().equals(bundleId)) {
                 return cur;
@@ -123,7 +124,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey) {
+    public SubscriptionBundle getSubscriptionBundleFromAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) {
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getKey().equals(bundleKey) && cur.getAccountId().equals(accountId)) {
                 return cur;
@@ -133,32 +134,32 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final CallContext context) {
+    public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final InternalCallContext context) {
         bundles.add(bundle);
-        return getSubscriptionBundleFromId(bundle.getId());
+        return getSubscriptionBundleFromId(bundle.getId(), context);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId) {
+    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
         for (final Subscription cur : subscriptions) {
             if (cur.getId().equals(subscriptionId)) {
-                return buildSubscription(factory, (SubscriptionData) cur);
+                return buildSubscription(factory, (SubscriptionData) cur, context);
             }
         }
         return null;
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey) {
+    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey, final InternalTenantContext context) {
 
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getKey().equals(bundleKey) && cur.getAccountId().equals(bundleKey)) {
-                return getSubscriptions(factory, cur.getId());
+                return getSubscriptions(factory, cur.getId(), context);
             }
         }
         return Collections.emptyList();
@@ -166,43 +167,40 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
 
     @Override
     public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents,
-                                   final CallContext context) {
+                                   final InternalCallContext context) {
         synchronized (events) {
             events.addAll(initialEvents);
             for (final EntitlementEvent cur : initialEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()), context);
             }
         }
-        final Subscription updatedSubscription = buildSubscription(null, subscription);
+        final Subscription updatedSubscription = buildSubscription(null, subscription, context);
         subscriptions.add(updatedSubscription);
     }
 
     @Override
-    public void recreateSubscription(final SubscriptionData subscription,
-                                     final List<EntitlementEvent> recreateEvents, final CallContext context) {
-
+    public void recreateSubscription(final SubscriptionData subscription, final List<EntitlementEvent> recreateEvents, final InternalCallContext context) {
         synchronized (events) {
             events.addAll(recreateEvents);
             for (final EntitlementEvent cur : recreateEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()), context);
             }
         }
     }
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId) {
-
+    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
         final List<Subscription> results = new ArrayList<Subscription>();
         for (final Subscription cur : subscriptions) {
             if (cur.getBundleId().equals(bundleId)) {
-                results.add(buildSubscription(factory, (SubscriptionData) cur));
+                results.add(buildSubscription(factory, (SubscriptionData) cur, context));
             }
         }
         return results;
     }
 
     @Override
-    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
+    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         synchronized (events) {
             final List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
             for (final EntitlementEvent cur : events) {
@@ -215,13 +213,13 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId) {
+    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         synchronized (events) {
             final List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
             for (final EntitlementEvent cur : events) {
                 if (cur.isActive() &&
-                        cur.getEffectiveDate().isAfter(clock.getUTCNow()) &&
-                        cur.getSubscriptionId().equals(subscriptionId)) {
+                    cur.getEffectiveDate().isAfter(clock.getUTCNow()) &&
+                    cur.getSubscriptionId().equals(subscriptionId)) {
                     results.add(cur);
                 }
             }
@@ -230,38 +228,36 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId) {
+    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
         for (final Subscription cur : subscriptions) {
             if (cur.getBundleId().equals(bundleId) &&
-                    cur.getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) {
-                return buildSubscription(factory, (SubscriptionData) cur);
+                cur.getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) {
+                return buildSubscription(factory, (SubscriptionData) cur, context);
             }
         }
         return null;
     }
 
     @Override
-    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase,
-                                     final CallContext context) {
-        cancelNextPhaseEvent(subscription.getId());
-        insertEvent(nextPhase);
+    public void createNextPhaseEvent(final SubscriptionData subscription, final EntitlementEvent nextPhase, final InternalCallContext context) {
+        cancelNextPhaseEvent(subscription.getId(), context);
+        insertEvent(nextPhase, context);
     }
 
-    private Subscription buildSubscription(final SubscriptionFactory factory, final SubscriptionData in) {
+    private Subscription buildSubscription(final SubscriptionFactory factory, final SubscriptionData in, final InternalTenantContext context) {
         if (factory != null) {
-            return factory.createSubscription(new SubscriptionBuilder(in), getEventsForSubscription(in.getId()));
+            return factory.createSubscription(new SubscriptionBuilder(in), getEventsForSubscription(in.getId(), context));
         } else {
             final SubscriptionData subscription = new SubscriptionData(new SubscriptionBuilder(in), null, clock);
             if (events.size() > 0) {
-                subscription.rebuildTransitions(getEventsForSubscription(in.getId()), catalogService.getFullCatalog());
+                subscription.rebuildTransitions(getEventsForSubscription(in.getId(), context), catalogService.getFullCatalog());
             }
             return subscription;
         }
     }
 
     @Override
-    public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context) {
-
+    public void updateChargedThroughDate(final SubscriptionData subscription, final InternalCallContext context) {
         boolean found = false;
         final Iterator<Subscription> it = subscriptions.iterator();
         while (it.hasNext()) {
@@ -279,38 +275,36 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
 
     @Override
     public void cancelSubscription(final SubscriptionData subscription, final EntitlementEvent cancelEvent,
-                                   final CallContext context, final int seqId) {
+                                   final InternalCallContext context, final int seqId) {
         synchronized (events) {
-            cancelNextPhaseEvent(subscription.getId());
-            insertEvent(cancelEvent);
+            cancelNextPhaseEvent(subscription.getId(), context);
+            insertEvent(cancelEvent, context);
         }
     }
 
     @Override
-    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents,
-                           final CallContext context) {
+    public void changePlan(final SubscriptionData subscription, final List<EntitlementEvent> changeEvents, final InternalCallContext context) {
         synchronized (events) {
             cancelNextChangeEvent(subscription.getId());
-            cancelNextPhaseEvent(subscription.getId());
+            cancelNextPhaseEvent(subscription.getId(), context);
             events.addAll(changeEvents);
             for (final EntitlementEvent cur : changeEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()), context);
             }
         }
     }
 
-    private void insertEvent(final EntitlementEvent event) {
+    private void insertEvent(final EntitlementEvent event, final InternalCallContext context) {
         synchronized (events) {
             events.add(event);
-            recordFutureNotificationFromTransaction(null, event.getEffectiveDate(), new EntitlementNotificationKey(event.getId()));
+            recordFutureNotificationFromTransaction(null, event.getEffectiveDate(), new EntitlementNotificationKey(event.getId()), context);
         }
     }
 
-    private void cancelNextPhaseEvent(final UUID subscriptionId) {
-
-        final Subscription curSubscription = getSubscriptionFromId(null, subscriptionId);
+    private void cancelNextPhaseEvent(final UUID subscriptionId, final InternalTenantContext context) {
+        final Subscription curSubscription = getSubscriptionFromId(null, subscriptionId, context);
         if (curSubscription.getCurrentPhase() == null ||
-                curSubscription.getCurrentPhase().getDuration().getUnit() == TimeUnit.UNLIMITED) {
+            curSubscription.getCurrentPhase().getDuration().getUnit() == TimeUnit.UNLIMITED) {
             return;
         }
 
@@ -323,7 +317,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
                     continue;
                 }
                 if (cur.getType() == EventType.PHASE &&
-                        cur.getEffectiveDate().isAfter(clock.getUTCNow())) {
+                    cur.getEffectiveDate().isAfter(clock.getUTCNow())) {
                     cur.deactivate();
                     break;
                 }
@@ -343,8 +337,8 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
                     continue;
                 }
                 if (cur.getType() == EventType.API_USER &&
-                        ApiEventType.CHANGE == ((ApiEvent) cur).getEventType() &&
-                        cur.getEffectiveDate().isAfter(clock.getUTCNow())) {
+                    ApiEventType.CHANGE == ((ApiEvent) cur).getEventType() &&
+                    cur.getEffectiveDate().isAfter(clock.getUTCNow())) {
                     cur.deactivate();
                     break;
                 }
@@ -354,7 +348,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
 
     @Override
     public void uncancelSubscription(final SubscriptionData subscription, final List<EntitlementEvent> uncancelEvents,
-                                     final CallContext context) {
+                                     final InternalCallContext context) {
 
         synchronized (events) {
             boolean foundCancel = false;
@@ -365,7 +359,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
                     continue;
                 }
                 if (cur.getType() == EventType.API_USER &&
-                        ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
+                    ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
                     cur.deactivate();
                     foundCancel = true;
                     break;
@@ -373,14 +367,14 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
             }
             if (foundCancel) {
                 for (final EntitlementEvent cur : uncancelEvents) {
-                    insertEvent(cur);
+                    insertEvent(cur, context);
                 }
             }
         }
     }
 
     @Override
-    public void migrate(final UUID accountId, final AccountMigrationData accountData, final CallContext context) {
+    public void migrate(final UUID accountId, final AccountMigrationData accountData, final InternalCallContext context) {
         synchronized (events) {
 
             for (final BundleMigrationData curBundle : accountData.getData()) {
@@ -389,7 +383,8 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
                     final SubscriptionData subData = curSubscription.getData();
                     for (final EntitlementEvent curEvent : curSubscription.getInitialEvents()) {
                         events.add(curEvent);
-                        recordFutureNotificationFromTransaction(null, curEvent.getEffectiveDate(), new EntitlementNotificationKey(curEvent.getId()));
+                        recordFutureNotificationFromTransaction(null, curEvent.getEffectiveDate(),
+                                                                new EntitlementNotificationKey(curEvent.getId()), context);
 
                     }
                     subscriptions.add(subData);
@@ -400,7 +395,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public EntitlementEvent getEventById(final UUID eventId) {
+    public EntitlementEvent getEventById(final UUID eventId, final InternalTenantContext context) {
         synchronized (events) {
             for (final EntitlementEvent cur : events) {
                 if (cur.getId().equals(eventId)) {
@@ -411,11 +406,12 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
         return null;
     }
 
-    private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
+    private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate,
+                                                         final NotificationKey notificationKey, final InternalCallContext context) {
         try {
             final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
                                                                                                            Engine.NOTIFICATION_QUEUE_NAME);
-            subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, null, notificationKey);
+            subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, null, notificationKey, context);
         } catch (NoSuchNotificationQueue e) {
             throw new RuntimeException(e);
         } catch (IOException e) {
@@ -424,18 +420,17 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId, final InternalTenantContext context) {
         return null;
     }
 
     @Override
     public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair,
-                       final CallContext context) {
+                       final InternalCallContext context) {
     }
 
     @Override
-    public void transfer(UUID srcAccountId, UUID destAccountId,
-            BundleMigrationData data,
-            List<TransferCancelData> transferCancelData, CallContext context) {
+    public void transfer(final UUID srcAccountId, final UUID destAccountId, final BundleMigrationData data,
+                         final List<TransferCancelData> transferCancelData, final InternalCallContext context) {
     }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
index 0c104fc..d4aeaab 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
@@ -18,13 +18,14 @@ package com.ning.billing.entitlement.engine.dao;
 
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.Inject;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.Inject;
+
 public class MockEntitlementDaoSql extends AuditedEntitlementDao {
     @Inject
     public MockEntitlementDaoSql(final IDBI dbi, final Clock clock, final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
index 13a9012..fff17a9 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
@@ -16,17 +16,24 @@
 
 package com.ning.billing.entitlement.glue;
 
-import com.google.inject.name.Names;
+import org.mockito.Mockito;
+import org.skife.jdbi.v2.IDBI;
+
 import com.ning.billing.entitlement.api.timeline.RepairEntitlementLifecycleDao;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.MockEntitlementDaoMemory;
 import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
+import com.ning.billing.util.callcontext.CallContextSqlDao;
+import com.ning.billing.util.callcontext.MockCallContextSqlDao;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
 import com.ning.billing.util.notificationq.MockNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.name.Names;
+
 public class MockEngineModuleMemory extends MockEngineModule {
+
     @Override
     protected void installEntitlementDao() {
         bind(EntitlementDao.class).to(MockEntitlementDaoMemory.class).asEagerSingleton();
@@ -39,8 +46,15 @@ public class MockEngineModuleMemory extends MockEngineModule {
         bind(NotificationQueueService.class).to(MockNotificationQueueService.class).asEagerSingleton();
     }
 
+    protected void installDBI() {
+        final IDBI idbi = Mockito.mock(IDBI.class);
+        Mockito.when(idbi.onDemand(CallContextSqlDao.class)).thenReturn(new MockCallContextSqlDao());
+        bind(IDBI.class).toInstance(idbi);
+    }
+
     @Override
     protected void configure() {
+        installDBI();
         super.configure();
         install(new BusModule(BusType.MEMORY));
         installNotificationQueue();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
index fd3d266..8c73897 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
@@ -19,7 +19,6 @@ package com.ning.billing.entitlement.glue;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.name.Names;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
@@ -33,6 +32,8 @@ import com.ning.billing.util.glue.BusModule.BusType;
 import com.ning.billing.util.glue.CustomFieldModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 
+import com.google.inject.name.Names;
+
 public class MockEngineModuleSql extends MockEngineModule {
     @Override
     protected void installEntitlementDao() {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index ab7cccc..2414a36 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -25,9 +25,6 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
@@ -38,48 +35,62 @@ import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
 
 public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
 
     private static final WithInvoiceApiException<InvoicePayment> invoicePaymentWithException = new WithInvoiceApiException<InvoicePayment>();
 
     private final InvoiceDao dao;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultInvoicePaymentApi(final InvoiceDao dao) {
+    public DefaultInvoicePaymentApi(final InvoiceDao dao, final InternalCallContextFactory internalCallContextFactory) {
         this.dao = dao;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) {
-        dao.notifyOfPayment(invoicePayment, context);
+    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) throws InvoiceApiException {
+        // Retrieve the account id for the internal call context
+        final Invoice invoice = dao.getById(invoicePayment.getInvoiceId(), internalCallContextFactory.createInternalTenantContext(context));
+        final UUID accountId = invoice.getAccountId();
+        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
-    public List<Invoice> getAllInvoicesByAccount(final UUID accountId) {
-        return dao.getAllInvoicesByAccount(accountId);
+    public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final TenantContext context) {
+        return dao.getAllInvoicesByAccount(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public Invoice getInvoice(final UUID invoiceId) throws InvoiceApiException {
-        return dao.getById(invoiceId);
+    public Invoice getInvoice(final UUID invoiceId, final TenantContext context) throws InvoiceApiException {
+        return dao.getById(invoiceId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Invoice getInvoiceForPaymentId(final UUID paymentId) throws InvoiceApiException {
-        final UUID invoiceIdStr = dao.getInvoiceIdByPaymentId(paymentId);
-        return invoiceIdStr == null ? null : dao.getById(invoiceIdStr);
+    public Invoice getInvoiceForPaymentId(final UUID paymentId, final TenantContext context) throws InvoiceApiException {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        final UUID invoiceIdStr = dao.getInvoiceIdByPaymentId(paymentId, internalTenantContext);
+        return invoiceIdStr == null ? null : dao.getById(invoiceIdStr, internalTenantContext);
     }
 
     @Override
-    public List<InvoicePayment> getInvoicePayments(final UUID paymentId) {
-        return dao.getInvoicePayments(paymentId);
+    public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
+        return dao.getInvoicePayments(paymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
 
     @Override
-    public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId) {
-        List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId);
+    public InvoicePayment getInvoicePaymentForAttempt(final UUID paymentId, final TenantContext context) {
+        final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, internalCallContextFactory.createInternalTenantContext(context));
         if (invoicePayments.size() == 0) {
             return null;
         }
@@ -91,37 +102,40 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         }).iterator().next();
     }
 
-
     @Override
-    public void notifyOfPayment(final UUID invoiceId, final BigDecimal amount, final Currency currency, final UUID paymentId, final DateTime paymentDate, final CallContext context) {
+    public void notifyOfPayment(final UUID invoiceId, final BigDecimal amount, final Currency currency, final UUID paymentId, final DateTime paymentDate, final CallContext context) throws InvoiceApiException {
         final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, paymentDate, amount, currency);
-        dao.notifyOfPayment(invoicePayment, context);
-    }
 
+        // Retrieve the account id for the internal call context
+        final Invoice invoice = dao.getById(invoiceId, internalCallContextFactory.createInternalCallContext(context));
+        final UUID accountId = invoice.getAccountId();
+
+        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
+    }
 
     @Override
-    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId) {
-        return dao.getRemainingAmountPaid(invoicePaymentId);
+    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final TenantContext context) {
+        return dao.getRemainingAmountPaid(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId) {
-        return dao.getChargebacksByAccountId(accountId);
+    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId, final TenantContext context) {
+        return dao.getChargebacksByAccountId(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId) {
-        return dao.getChargebacksByPaymentId(paymentId);
+    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId, final TenantContext context) {
+        return dao.getChargebacksByPaymentId(paymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public InvoicePayment getChargebackById(final UUID chargebackId) throws InvoiceApiException {
-        return dao.getChargebackById(chargebackId);
+    public InvoicePayment getChargebackById(final UUID chargebackId, final TenantContext context) throws InvoiceApiException {
+        return dao.getChargebackById(chargebackId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId) throws InvoiceApiException {
-        return dao.getAccountIdFromInvoicePaymentId(invoicePaymentId);
+    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId, final TenantContext context) throws InvoiceApiException {
+        return dao.getAccountIdFromInvoicePaymentId(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
@@ -136,7 +150,13 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
                 if (amount.compareTo(BigDecimal.ZERO) <= 0) {
                     throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
                 }
-                return dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, context);
+
+                // Retrieve the account id for the internal call context
+                final InternalCallContext internalCallContextNoAccountId = internalCallContextFactory.createInternalCallContext(context);
+                final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, internalCallContextNoAccountId);
+                final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayments.get(0).getId(), internalCallContextNoAccountId);
+
+                return dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, internalCallContextFactory.createInternalCallContext(accountId, context));
             }
         });
     }
@@ -146,19 +166,17 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         return createChargeback(invoicePaymentId, null, context);
     }
 
-
     @Override
     public InvoicePayment createChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
-
         return invoicePaymentWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<InvoicePayment>() {
 
             @Override
             public InvoicePayment doHandle() throws InvoiceApiException {
-                return dao.postChargeback(invoicePaymentId, amount, context);
+                // Retrieve the account id for the internal call context
+                final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePaymentId, internalCallContextFactory.createInternalCallContext(context));
+                return dao.postChargeback(invoicePaymentId, amount, internalCallContextFactory.createInternalCallContext(accountId, context));
             }
-
         });
-
     }
 
     //
@@ -169,14 +187,13 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     private static final class WithInvoiceApiException<T> {
-        public T executeAndThrow(WithInvoiceApiExceptionCallback<T> callback) throws InvoiceApiException  {
+        public T executeAndThrow(final WithInvoiceApiExceptionCallback<T> callback) throws InvoiceApiException  {
 
             try {
                 return callback.doHandle();
             } catch (TransactionFailedException e) {
                 if (e.getCause() instanceof InvoiceApiException) {
-                    InvoiceApiException realException = (InvoiceApiException) e.getCause();
-                    throw realException;
+                    throw (InvoiceApiException) e.getCause();
                 } else {
                     throw e;
                 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
index 1148b22..44d2a1b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
@@ -33,9 +33,7 @@ import com.ning.billing.invoice.api.InvoiceMigrationApi;
 import com.ning.billing.invoice.dao.AuditedInvoiceDao;
 import com.ning.billing.invoice.model.MigrationInvoiceItem;
 import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.inject.Inject;
@@ -46,30 +44,34 @@ public class DefaultInvoiceMigrationApi implements InvoiceMigrationApi {
     private final AccountUserApi accountUserApi;
     private final AuditedInvoiceDao dao;
     private final Clock clock;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultInvoiceMigrationApi(final AccountUserApi accountUserApi, final AuditedInvoiceDao dao, final Clock clock) {
+    public DefaultInvoiceMigrationApi(final AccountUserApi accountUserApi,
+                                      final AuditedInvoiceDao dao,
+                                      final Clock clock,
+                                      final InternalCallContextFactory internalCallContextFactory) {
         this.accountUserApi = accountUserApi;
         this.dao = dao;
         this.clock = clock;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public UUID createMigrationInvoice(final UUID accountId, final LocalDate targetDate, final BigDecimal balance, final Currency currency) {
+    public UUID createMigrationInvoice(final UUID accountId, final LocalDate targetDate, final BigDecimal balance, final Currency currency, final CallContext context) {
         final Account account;
         try {
-            account = accountUserApi.getAccountById(accountId);
+            account = accountUserApi.getAccountById(accountId, context);
         } catch (AccountApiException e) {
             log.warn("Unable to find account for id {}", accountId);
             return null;
         }
 
-        final CallContext context = new DefaultCallContextFactory(clock).createMigrationCallContext("Migration", CallOrigin.INTERNAL, UserType.MIGRATION, clock.getUTCNow(), clock.getUTCNow());
         final Invoice migrationInvoice = new MigrationInvoice(accountId, clock.getUTCToday(), targetDate, currency);
         final InvoiceItem migrationInvoiceItem = new MigrationInvoiceItem(migrationInvoice.getId(), accountId, targetDate, balance, currency);
         migrationInvoice.addInvoiceItem(migrationInvoiceItem);
 
-        dao.create(migrationInvoice, account.getBillCycleDay().getDayOfMonthUTC(), true, context);
+        dao.create(migrationInvoice, account.getBillCycleDay().getDayOfMonthUTC(), true, internalCallContextFactory.createInternalCallContext(accountId, context));
         return migrationInvoice.getId();
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 6e05ad7..ab33eac 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -45,6 +45,8 @@ import com.ning.billing.invoice.template.HtmlInvoiceGenerator;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
@@ -58,57 +60,61 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     private final AccountUserApi accountUserApi;
     private final TagUserApi tagUserApi;
     private final HtmlInvoiceGenerator generator;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultInvoiceUserApi(final InvoiceDao dao, final InvoiceDispatcher dispatcher, final AccountUserApi accountUserApi,
-                                 final TagUserApi tagUserApi, final HtmlInvoiceGenerator generator) {
+                                 final TagUserApi tagUserApi, final HtmlInvoiceGenerator generator, final InternalCallContextFactory internalCallContextFactory) {
         this.dao = dao;
         this.dispatcher = dispatcher;
         this.accountUserApi = accountUserApi;
         this.tagUserApi = tagUserApi;
         this.generator = generator;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId) {
-        return dao.getInvoicesByAccount(accountId);
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final TenantContext context) {
+        return dao.getInvoicesByAccount(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate) {
-        return dao.getInvoicesByAccount(accountId, fromDate);
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate, final TenantContext context) {
+        return dao.getInvoicesByAccount(accountId, fromDate, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) {
-        dao.notifyOfPayment(invoicePayment, context);
+    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) throws InvoiceApiException {
+        // Retrieve the account id for the internal call context
+        final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayment.getId(), internalCallContextFactory.createInternalCallContext(context));
+        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
-    public BigDecimal getAccountBalance(final UUID accountId) {
-        final BigDecimal result = dao.getAccountBalance(accountId);
+    public BigDecimal getAccountBalance(final UUID accountId, final TenantContext context) {
+        final BigDecimal result = dao.getAccountBalance(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
         return result == null ? BigDecimal.ZERO : result;
     }
 
     @Override
-    public BigDecimal getAccountCBA(final UUID accountId) {
-        final BigDecimal result = dao.getAccountCBA(accountId);
+    public BigDecimal getAccountCBA(final UUID accountId, final TenantContext context) {
+        final BigDecimal result = dao.getAccountCBA(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
         return result == null ? BigDecimal.ZERO : result;
     }
 
     @Override
-    public Invoice getInvoice(final UUID invoiceId) throws InvoiceApiException {
-        return dao.getById(invoiceId);
+    public Invoice getInvoice(final UUID invoiceId, final TenantContext context) throws InvoiceApiException {
+        return dao.getById(invoiceId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Invoice getInvoiceByNumber(final Integer number) throws InvoiceApiException {
-        return dao.getByNumber(number);
+    public Invoice getInvoiceByNumber(final Integer number, final TenantContext context) throws InvoiceApiException {
+        return dao.getByNumber(number, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate) {
-        return dao.getUnpaidInvoicesByAccountId(accountId, upToDate);
+    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate, final TenantContext context) {
+        return dao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
@@ -116,7 +122,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                             final CallContext context) throws InvoiceApiException {
         final Account account;
         try {
-            account = accountUserApi.getAccountById(accountId);
+            account = accountUserApi.getAccountById(accountId, context);
         } catch (AccountApiException e) {
             throw new InvoiceApiException(e, ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, e.toString());
         }
@@ -131,18 +137,22 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     }
 
     @Override
-    public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException {
-        dao.setWrittenOff(invoiceId, context);
+    public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException, InvoiceApiException {
+        // Retrieve the invoice for the internal call context
+        final Invoice invoice = dao.getById(invoiceId, internalCallContextFactory.createInternalCallContext(context));
+        dao.setWrittenOff(invoiceId, internalCallContextFactory.createInternalCallContext(invoice.getAccountId(), context));
     }
 
     @Override
-    public void tagInvoiceAsNotWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException {
-        dao.removeWrittenOff(invoiceId, context);
+    public void tagInvoiceAsNotWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException, InvoiceApiException {
+        // Retrieve the invoice for the internal call context
+        final Invoice invoice = dao.getById(invoiceId, internalCallContextFactory.createInternalCallContext(context));
+        dao.removeWrittenOff(invoiceId, internalCallContextFactory.createInternalCallContext(invoice.getAccountId(), context));
     }
 
     @Override
-    public InvoiceItem getExternalChargeById(final UUID externalChargeId) throws InvoiceApiException {
-        final InvoiceItem externalChargeItem = dao.getExternalChargeById(externalChargeId);
+    public InvoiceItem getExternalChargeById(final UUID externalChargeId, final TenantContext context) throws InvoiceApiException {
+        final InvoiceItem externalChargeItem = dao.getExternalChargeById(externalChargeId, internalCallContextFactory.createInternalTenantContext(context));
         if (externalChargeItem == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NO_SUCH_EXTERNAL_CHARGE, externalChargeId);
         }
@@ -178,12 +188,12 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
             throw new InvoiceApiException(ErrorCode.EXTERNAL_CHARGE_AMOUNT_INVALID, amount);
         }
 
-        return dao.insertExternalCharge(accountId, invoiceId, bundleId, description, amount, effectiveDate, currency, context);
+        return dao.insertExternalCharge(accountId, invoiceId, bundleId, description, amount, effectiveDate, currency, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
-    public InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException {
-        final InvoiceItem creditItem = dao.getCreditById(creditId);
+    public InvoiceItem getCreditById(final UUID creditId, final TenantContext context) throws InvoiceApiException {
+        final InvoiceItem creditItem = dao.getCreditById(creditId, internalCallContextFactory.createInternalTenantContext(context));
         if (creditItem == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NO_SUCH_CREDIT, creditId);
         }
@@ -205,7 +215,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
             throw new InvoiceApiException(ErrorCode.CREDIT_AMOUNT_INVALID, amount);
         }
 
-        return dao.insertCredit(accountId, invoiceId, amount, effectiveDate, currency, context);
+        return dao.insertCredit(accountId, invoiceId, amount, effectiveDate, currency, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
@@ -222,26 +232,26 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
             throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_INVALID, amount);
         }
 
-        return dao.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, amount, currency, context);
+        return dao.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, amount, currency, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
     public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final CallContext context) throws InvoiceApiException {
-        dao.deleteCBA(accountId, invoiceId, invoiceItemId, context);
+        dao.deleteCBA(accountId, invoiceId, invoiceItemId, internalCallContextFactory.createInternalCallContext(accountId, context));
     }
 
     @Override
-    public String getInvoiceAsHTML(final UUID invoiceId) throws AccountApiException, IOException, InvoiceApiException {
-        final Invoice invoice = getInvoice(invoiceId);
+    public String getInvoiceAsHTML(final UUID invoiceId, final TenantContext context) throws AccountApiException, IOException, InvoiceApiException {
+        final Invoice invoice = getInvoice(invoiceId, context);
         if (invoice == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
         }
 
-        final Account account = accountUserApi.getAccountById(invoice.getAccountId());
+        final Account account = accountUserApi.getAccountById(invoice.getAccountId(), context);
 
         // Check if this account has the MANUAL_PAY system tag
         boolean manualPay = false;
-        final Map<String, Tag> accountTags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT);
+        final Map<String, Tag> accountTags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT, context);
         for (final Tag tag : accountTags.values()) {
             if (ControlTagType.MANUAL_PAY.getId().equals(tag.getTagDefinitionId())) {
                 manualPay = true;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
index 760b8df..55377f6 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
@@ -59,7 +59,8 @@ import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.ObjectType;
@@ -102,35 +103,37 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId) {
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId.toString());
-                populateChildren(invoices, invoiceDao);
+                final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId.toString(), context);
+                populateChildren(invoices, invoiceDao, context);
                 return invoices;
             }
         });
     }
 
     @Override
-    public List<Invoice> getAllInvoicesByAccount(final UUID accountId) {
+    public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                return getAllInvoicesByAccountFromTransaction(accountId, invoiceDao);
+                return getAllInvoicesByAccountFromTransaction(accountId, invoiceDao, context);
             }
         });
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate) {
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                final List<Invoice> invoices = invoiceDao.getInvoicesByAccountAfterDate(accountId.toString(), fromDate.toDateTimeAtStartOfDay().toDate());
+                final List<Invoice> invoices = invoiceDao.getInvoicesByAccountAfterDate(accountId.toString(),
+                                                                                        fromDate.toDateTimeAtStartOfDay().toDate(),
+                                                                                        context);
 
-                populateChildren(invoices, invoiceDao);
+                populateChildren(invoices, invoiceDao, context);
 
                 return invoices;
             }
@@ -138,13 +141,13 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> get() {
+    public List<Invoice> get(final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                final List<Invoice> invoices = invoiceDao.get();
+                final List<Invoice> invoices = invoiceDao.get(context);
 
-                populateChildren(invoices, invoiceDao);
+                populateChildren(invoices, invoiceDao, context);
 
                 return invoices;
             }
@@ -152,16 +155,16 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public Invoice getById(final UUID invoiceId) throws InvoiceApiException {
+    public Invoice getById(final UUID invoiceId, final InternalTenantContext context) throws InvoiceApiException {
         try {
             return invoiceSqlDao.inTransaction(new Transaction<Invoice, InvoiceSqlDao>() {
                 @Override
                 public Invoice inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                    final Invoice invoice = invoiceDao.getById(invoiceId.toString());
+                    final Invoice invoice = invoiceDao.getById(invoiceId.toString(), context);
                     if (invoice == null) {
                         throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
                     }
-                    populateChildren(invoice, invoiceDao);
+                    populateChildren(invoice, invoiceDao, context);
                     return invoice;
                 }
             });
@@ -175,9 +178,9 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public Invoice getByNumber(final Integer number) throws InvoiceApiException {
+    public Invoice getByNumber(final Integer number, final InternalTenantContext context) throws InvoiceApiException {
         // The invoice number is just the record id
-        final Invoice result = invoiceSqlDao.getByRecordId(number.longValue());
+        final Invoice result = invoiceSqlDao.getByRecordId(number.longValue(), context);
         if (result == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, number);
         }
@@ -185,11 +188,11 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void create(final Invoice invoice, final int billCycleDayUTC, final boolean isRealInvoice, final CallContext context) {
+    public void create(final Invoice invoice, final int billCycleDayUTC, final boolean isRealInvoice, final InternalCallContext context) {
         invoiceSqlDao.inTransaction(new Transaction<Void, InvoiceSqlDao>() {
             @Override
             public Void inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
-                final Invoice currentInvoice = transactional.getById(invoice.getId().toString());
+                final Invoice currentInvoice = transactional.getById(invoice.getId().toString(), context);
                 if (currentInvoice == null) {
                     final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
@@ -198,7 +201,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
 
                     if (isRealInvoice) {
                         transactional.create(invoice, context);
-                        final Long recordId = transactional.getRecordId(invoice.getId().toString());
+                        final Long recordId = transactional.getRecordId(invoice.getId().toString(), context);
                         audits.add(new EntityAudit(TableName.INVOICES, recordId, ChangeType.INSERT));
                     }
 
@@ -207,7 +210,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     final List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
                     final InvoiceItemSqlDao transInvoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
                     transInvoiceItemSqlDao.batchCreateFromTransaction(invoiceItems, context);
-                    recordIdList = transInvoiceItemSqlDao.getRecordIds(invoice.getId().toString());
+                    recordIdList = transInvoiceItemSqlDao.getRecordIds(invoice.getId().toString(), context);
                     audits.addAll(createAudits(TableName.INVOICE_ITEMS, recordIdList));
 
                     final List<InvoiceItem> recurringInvoiceItems = invoice.getInvoiceItems(RecurringInvoiceItem.class);
@@ -216,7 +219,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     final List<InvoicePayment> invoicePayments = invoice.getPayments();
                     final InvoicePaymentSqlDao invoicePaymentSqlDao = transactional.become(InvoicePaymentSqlDao.class);
                     invoicePaymentSqlDao.batchCreateFromTransaction(invoicePayments, context);
-                    recordIdList = invoicePaymentSqlDao.getRecordIds(invoice.getId().toString());
+                    recordIdList = invoicePaymentSqlDao.getRecordIds(invoice.getId().toString(), context);
                     audits.addAll(createAudits(TableName.INVOICE_PAYMENTS, recordIdList));
 
                     transactional.insertAuditFromTransaction(audits, context);
@@ -236,13 +239,13 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getInvoicesBySubscription(final UUID subscriptionId) {
+    public List<Invoice> getInvoicesBySubscription(final UUID subscriptionId, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
-                final List<Invoice> invoices = invoiceDao.getInvoicesBySubscription(subscriptionId.toString());
+                final List<Invoice> invoices = invoiceDao.getInvoicesBySubscription(subscriptionId.toString(), context);
 
-                populateChildren(invoices, invoiceDao);
+                populateChildren(invoices, invoiceDao, context);
 
                 return invoices;
             }
@@ -250,7 +253,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public BigDecimal getAccountBalance(final UUID accountId) {
+    public BigDecimal getAccountBalance(final UUID accountId, final InternalTenantContext context) {
 
         return invoiceSqlDao.inTransaction(new Transaction<BigDecimal, InvoiceSqlDao>() {
             @Override
@@ -258,7 +261,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                 BigDecimal cba = BigDecimal.ZERO;
 
                 BigDecimal accountBalance = BigDecimal.ZERO;
-                final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, transactional);
+                final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, transactional, context);
                 for (final Invoice cur : invoices) {
                     accountBalance = accountBalance.add(cur.getBalance());
                     cba = cba.add(cur.getCBAAmount());
@@ -269,24 +272,24 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public BigDecimal getAccountCBA(final UUID accountId) {
+    public BigDecimal getAccountCBA(final UUID accountId, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<BigDecimal, InvoiceSqlDao>() {
             @Override
             public BigDecimal inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
-                return getAccountCBAFromTransaction(accountId, transactional);
+                return getAccountCBAFromTransaction(accountId, transactional, context);
             }
         });
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) {
+    public void notifyOfPayment(final InvoicePayment invoicePayment, final InternalCallContext context) {
         invoicePaymentSqlDao.inTransaction(new Transaction<Void, InvoicePaymentSqlDao>() {
             @Override
             public Void inTransaction(final InvoicePaymentSqlDao transactional, final TransactionStatus status) throws Exception {
                 transactional.notifyOfPayment(invoicePayment, context);
 
                 final String invoicePaymentId = invoicePayment.getId().toString();
-                final Long recordId = transactional.getRecordId(invoicePaymentId);
+                final Long recordId = transactional.getRecordId(invoicePaymentId, context);
                 final EntityAudit audit = new EntityAudit(TableName.INVOICE_PAYMENTS, recordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
@@ -296,12 +299,12 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, @Nullable final LocalDate upToDate) {
+    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, @Nullable final LocalDate upToDate, final InternalTenantContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
             public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
 
-                final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, invoiceDao);
+                final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, invoiceDao, context);
                 final Collection<Invoice> unpaidInvoices = Collections2.filter(invoices, new Predicate<Invoice>() {
                     @Override
                     public boolean apply(final Invoice in) {
@@ -314,24 +317,24 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public UUID getInvoiceIdByPaymentId(final UUID paymentId) {
-        return invoiceSqlDao.getInvoiceIdByPaymentId(paymentId.toString());
+    public UUID getInvoiceIdByPaymentId(final UUID paymentId, final InternalTenantContext context) {
+        return invoiceSqlDao.getInvoiceIdByPaymentId(paymentId.toString(), context);
     }
 
     @Override
-    public List<InvoicePayment> getInvoicePayments(final UUID paymentId) {
-        return invoicePaymentSqlDao.getInvoicePayments(paymentId.toString());
+    public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final InternalTenantContext context) {
+        return invoicePaymentSqlDao.getInvoicePayments(paymentId.toString(), context);
     }
 
     @Override
-    public void setWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException {
+    public void setWrittenOff(final UUID invoiceId, final InternalCallContext context) throws TagApiException {
         invoiceSqlDao.inTransaction(new Transaction<Void, InvoiceSqlDao>() {
             @Override
             public Void inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
                 // Note: the tagUserApi is audited
-                tagUserApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), context);
+                tagUserApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), context.toCallContext());
 
-                final Invoice invoice = transactional.getById(invoiceId.toString());
+                final Invoice invoice = transactional.getById(invoiceId.toString(), context);
                 notifyBusOfInvoiceAdjustment(transactional, invoiceId, invoice.getAccountId(), context.getUserToken());
 
                 return null;
@@ -340,14 +343,14 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void removeWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException {
+    public void removeWrittenOff(final UUID invoiceId, final InternalCallContext context) throws TagApiException {
         invoiceSqlDao.inTransaction(new Transaction<Void, InvoiceSqlDao>() {
             @Override
             public Void inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
                 // Note: the tagUserApi is audited
-                tagUserApi.removeTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), context);
+                tagUserApi.removeTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), context.toCallContext());
 
-                final Invoice invoice = transactional.getById(invoiceId.toString());
+                final Invoice invoice = transactional.getById(invoiceId.toString(), context);
                 notifyBusOfInvoiceAdjustment(transactional, invoiceId, invoice.getAccountId(), context.getUserToken());
 
                 return null;
@@ -357,10 +360,9 @@ public class AuditedInvoiceDao implements InvoiceDao {
 
     @Override
     public InvoicePayment createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
-            final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final UUID paymentCookieId,
-            final CallContext context)
-                    throws InvoiceApiException {
-
+                                       final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final UUID paymentCookieId,
+                                       final InternalCallContext context)
+            throws InvoiceApiException {
         final boolean isInvoiceItemAdjusted = isInvoiceAdjusted && invoiceItemIdsWithNullAmounts.size() > 0;
 
         return invoicePaymentSqlDao.inTransaction(new Transaction<InvoicePayment, InvoicePaymentSqlDao>() {
@@ -370,22 +372,23 @@ public class AuditedInvoiceDao implements InvoiceDao {
 
                 final InvoiceSqlDao transInvoiceDao = transactional.become(InvoiceSqlDao.class);
 
-                final InvoicePayment payment = transactional.getByPaymentId(paymentId.toString());
+                final InvoicePayment payment = transactional.getByPaymentId(paymentId.toString(), context);
                 if (payment == null) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_BY_ATTEMPT_NOT_FOUND, paymentId);
                 }
 
                 // Retrieve the amounts to adjust, if needed
                 final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts = computeItemAdjustments(payment.getInvoiceId().toString(),
-                        transInvoiceDao,
-                        invoiceItemIdsWithNullAmounts);
+                                                                                               transInvoiceDao,
+                                                                                               invoiceItemIdsWithNullAmounts,
+                                                                                               context);
 
                 // Compute the actual amount to refund
                 final BigDecimal requestedPositiveAmount = computePositiveRefundAmount(payment, requestedRefundAmount, invoiceItemIdsWithAmounts);
 
                 // Before we go further, check if that refund already got inserted -- the payment system keeps a state machine
                 // and so this call may be called several time for the same  paymentCookieId (which is really the refundId)
-                final InvoicePayment existingRefund = transactional.getPaymentsForCookieId(paymentCookieId.toString());
+                final InvoicePayment existingRefund = transactional.getPaymentsForCookieId(paymentCookieId.toString(), context);
                 if (existingRefund != null) {
                     return existingRefund;
                 }
@@ -394,13 +397,13 @@ public class AuditedInvoiceDao implements InvoiceDao {
                         payment.getInvoiceId(), context.getCreatedDate(), requestedPositiveAmount.negate(),
                         payment.getCurrency(), paymentCookieId, payment.getId());
                 transactional.create(refund, context);
-                final Long refundRecordId = transactional.getRecordId(refund.getId().toString());
+                final Long refundRecordId = transactional.getRecordId(refund.getId().toString(), context);
                 audits.add(new EntityAudit(TableName.REFUNDS, refundRecordId, ChangeType.INSERT));
 
                 // Retrieve invoice after the Refund
-                final Invoice invoice = transInvoiceDao.getById(payment.getInvoiceId().toString());
+                final Invoice invoice = transInvoiceDao.getById(payment.getInvoiceId().toString(), context);
                 if (invoice != null) {
-                    populateChildren(invoice, transInvoiceDao);
+                    populateChildren(invoice, transInvoiceDao, context);
                 } else {
                     throw new IllegalStateException("Invoice shouldn't be null for payment " + payment.getId());
                 }
@@ -418,7 +421,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     if (requestedPositiveAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
                         final InvoiceItem adjItem = new RefundAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(), requestedPositiveAmountToAdjust.negate(), invoice.getCurrency());
                         transInvoiceItemDao.create(adjItem, context);
-                        final Long adjItemRecordId = transInvoiceItemDao.getRecordId(adjItem.getId().toString());
+                        final Long adjItemRecordId = transInvoiceItemDao.getRecordId(adjItem.getId().toString(), context);
                         audits.add(new EntityAudit(TableName.INVOICE_ITEMS, adjItemRecordId, ChangeType.INSERT));
                     }
                 } else if (isInvoiceAdjusted) {
@@ -426,9 +429,10 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     for (final UUID invoiceItemId : invoiceItemIdsWithAmounts.keySet()) {
                         final BigDecimal adjAmount = invoiceItemIdsWithAmounts.get(invoiceItemId);
                         final InvoiceItem item = createAdjustmentItem(transInvoiceDao, invoice.getId(), invoiceItemId, adjAmount,
-                                invoice.getCurrency(), context.getCreatedDate().toLocalDate());
+                                                                      invoice.getCurrency(), context.getCreatedDate().toLocalDate(),
+                                                                      context);
                         transInvoiceItemDao.create(item, context);
-                        final Long itemRecordId = transInvoiceItemDao.getRecordId(item.getId().toString());
+                        final Long itemRecordId = transInvoiceItemDao.getRecordId(item.getId().toString(), context);
                         audits.add(new EntityAudit(TableName.INVOICE_ITEMS, itemRecordId, ChangeType.INSERT));
                     }
                 }
@@ -453,11 +457,14 @@ public class AuditedInvoiceDao implements InvoiceDao {
      * @param invoiceId                     original invoice id
      * @param transInvoiceDao               the transactional InvoiceSqlDao
      * @param invoiceItemIdsWithNullAmounts the original mapping between invoice item ids and amount to refund (contains null)
+     * @param context                       the tenant context
      * @return the final mapping between invoice item ids and amount to refund
      * @throws InvoiceApiException
      */
-    private Map<UUID, BigDecimal> computeItemAdjustments(final String invoiceId, final InvoiceSqlDao transInvoiceDao,
-            final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts) throws InvoiceApiException {
+    private Map<UUID, BigDecimal> computeItemAdjustments(final String invoiceId,
+                                                         final InvoiceSqlDao transInvoiceDao,
+                                                         final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts,
+                                                         final InternalTenantContext context) throws InvoiceApiException {
         // Populate the missing amounts for individual items, if needed
         final Builder<UUID, BigDecimal> invoiceItemIdsWithAmountsBuilder = new Builder<UUID, BigDecimal>();
         if (invoiceItemIdsWithNullAmounts.size() == 0) {
@@ -465,9 +472,9 @@ public class AuditedInvoiceDao implements InvoiceDao {
         }
 
         // Retrieve invoice before the Refund
-        final Invoice invoice = transInvoiceDao.getById(invoiceId);
+        final Invoice invoice = transInvoiceDao.getById(invoiceId, context);
         if (invoice != null) {
-            populateChildren(invoice, transInvoiceDao);
+            populateChildren(invoice, transInvoiceDao, context);
         } else {
             throw new IllegalStateException("Invoice shouldn't be null for id " + invoiceId);
         }
@@ -543,12 +550,12 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final InternalCallContext context) throws InvoiceApiException {
 
         return invoicePaymentSqlDao.inTransaction(new Transaction<InvoicePayment, InvoicePaymentSqlDao>() {
             @Override
             public InvoicePayment inTransaction(final InvoicePaymentSqlDao transactional, final TransactionStatus status) throws Exception {
-                final BigDecimal maxChargedBackAmount = getRemainingAmountPaidFromTransaction(invoicePaymentId, transactional);
+                final BigDecimal maxChargedBackAmount = getRemainingAmountPaidFromTransaction(invoicePaymentId, transactional, context);
                 final BigDecimal requestedChargedBackAmout = (amount == null) ? maxChargedBackAmount : amount;
                 if (requestedChargedBackAmout.compareTo(BigDecimal.ZERO) <= 0) {
                     throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_IS_NEGATIVE);
@@ -557,7 +564,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_TOO_HIGH, requestedChargedBackAmout, maxChargedBackAmount);
                 }
 
-                final InvoicePayment payment = invoicePaymentSqlDao.getById(invoicePaymentId.toString());
+                final InvoicePayment payment = invoicePaymentSqlDao.getById(invoicePaymentId.toString(), context);
                 if (payment == null) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, invoicePaymentId.toString());
                 } else {
@@ -566,12 +573,12 @@ public class AuditedInvoiceDao implements InvoiceDao {
                     transactional.create(chargeBack, context);
 
                     // Add audit
-                    final Long recordId = transactional.getRecordId(chargeBack.getId().toString());
+                    final Long recordId = transactional.getRecordId(chargeBack.getId().toString(), context);
                     final EntityAudit audit = new EntityAudit(TableName.INVOICE_PAYMENTS, recordId, ChangeType.INSERT);
                     transactional.insertAuditFromTransaction(audit, context);
 
                     // Notify the bus since the balance of the invoice changed
-                    final UUID accountId = transactional.getAccountIdFromInvoicePaymentId(chargeBack.getId().toString());
+                    final UUID accountId = transactional.getAccountIdFromInvoicePaymentId(chargeBack.getId().toString(), context);
                     notifyBusOfInvoiceAdjustment(transactional, payment.getInvoiceId(), accountId, context.getUserToken());
 
                     return chargeBack;
@@ -581,13 +588,13 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId) {
-        return getRemainingAmountPaidFromTransaction(invoicePaymentId, invoicePaymentSqlDao);
+    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final InternalTenantContext context) {
+        return getRemainingAmountPaidFromTransaction(invoicePaymentId, invoicePaymentSqlDao, context);
     }
 
     @Override
-    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId) throws InvoiceApiException {
-        final UUID accountId = invoicePaymentSqlDao.getAccountIdFromInvoicePaymentId(invoicePaymentId.toString());
+    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId, final InternalTenantContext context) throws InvoiceApiException {
+        final UUID accountId = invoicePaymentSqlDao.getAccountIdFromInvoicePaymentId(invoicePaymentId.toString(), context);
         if (accountId == null) {
             throw new InvoiceApiException(ErrorCode.CHARGE_BACK_COULD_NOT_FIND_ACCOUNT_ID, invoicePaymentId);
         } else {
@@ -596,18 +603,18 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId) {
-        return invoicePaymentSqlDao.getChargeBacksByAccountId(accountId.toString());
+    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId, final InternalTenantContext context) {
+        return invoicePaymentSqlDao.getChargeBacksByAccountId(accountId.toString(), context);
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId) {
-        return invoicePaymentSqlDao.getChargebacksByPaymentId(paymentId.toString());
+    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId, final InternalTenantContext context) {
+        return invoicePaymentSqlDao.getChargebacksByPaymentId(paymentId.toString(), context);
     }
 
     @Override
-    public InvoicePayment getChargebackById(final UUID chargebackId) throws InvoiceApiException {
-        final InvoicePayment chargeback = invoicePaymentSqlDao.getById(chargebackId.toString());
+    public InvoicePayment getChargebackById(final UUID chargebackId, final InternalTenantContext context) throws InvoiceApiException {
+        final InvoicePayment chargeback = invoicePaymentSqlDao.getById(chargebackId.toString(), context);
         if (chargeback == null) {
             throw new InvoiceApiException(ErrorCode.CHARGE_BACK_DOES_NOT_EXIST, chargebackId);
         } else {
@@ -616,14 +623,14 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public InvoiceItem getExternalChargeById(final UUID externalChargeId) throws InvoiceApiException {
-        return invoiceItemSqlDao.getById(externalChargeId.toString());
+    public InvoiceItem getExternalChargeById(final UUID externalChargeId, final InternalTenantContext context) throws InvoiceApiException {
+        return invoiceItemSqlDao.getById(externalChargeId.toString(), context);
     }
 
     @Override
     public InvoiceItem insertExternalCharge(final UUID accountId, @Nullable final UUID invoiceId, @Nullable final UUID bundleId, final String description,
-            final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context)
-                    throws InvoiceApiException {
+                                            final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final InternalCallContext context)
+            throws InvoiceApiException {
         return invoiceSqlDao.inTransaction(new Transaction<InvoiceItem, InvoiceSqlDao>() {
             @Override
             public InvoiceItem inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -634,7 +641,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                 if (invoiceIdForExternalCharge == null) {
                     final Invoice invoiceForExternalCharge = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency);
                     transactional.create(invoiceForExternalCharge, context);
-                    final Long invoiceRecordId = transactional.getRecordId(invoiceForExternalCharge.getId().toString());
+                    final Long invoiceRecordId = transactional.getRecordId(invoiceForExternalCharge.getId().toString(), context);
                     audits.add(new EntityAudit(TableName.INVOICES, invoiceRecordId, ChangeType.INSERT));
 
                     invoiceIdForExternalCharge = invoiceForExternalCharge.getId();
@@ -646,22 +653,22 @@ public class AuditedInvoiceDao implements InvoiceDao {
 
                 final InvoiceItemSqlDao transInvoiceItemDao = transactional.become(InvoiceItemSqlDao.class);
                 transInvoiceItemDao.create(externalCharge, context);
-                final Long invoiceItemRecordId = transInvoiceItemDao.getRecordId(externalCharge.getId().toString());
+                final Long invoiceItemRecordId = transInvoiceItemDao.getRecordId(externalCharge.getId().toString(), context);
                 audits.add(new EntityAudit(TableName.INVOICE_ITEMS, invoiceItemRecordId, ChangeType.INSERT));
 
                 // At this point, reread the invoice and figure out if we need to consume some of the CBA
-                final Invoice invoice = transactional.getById(invoiceIdForExternalCharge.toString());
+                final Invoice invoice = transactional.getById(invoiceIdForExternalCharge.toString(), context);
                 if (invoice == null) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceIdForExternalCharge);
                 }
-                populateChildren(invoice, transactional);
+                populateChildren(invoice, transactional, context);
 
-                final BigDecimal accountCbaAvailable = getAccountCBAFromTransaction(invoice.getAccountId(), transactional);
+                final BigDecimal accountCbaAvailable = getAccountCBAFromTransaction(invoice.getAccountId(), transactional, context);
                 if (accountCbaAvailable.compareTo(BigDecimal.ZERO) > 0 && invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                     final BigDecimal cbaAmountToConsume = accountCbaAvailable.compareTo(invoice.getBalance()) > 0 ? invoice.getBalance().negate() : accountCbaAvailable.negate();
                     final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(), cbaAmountToConsume, invoice.getCurrency());
                     transInvoiceItemDao.create(cbaAdjItem, context);
-                    final Long cbaAdjItemRecordId = transInvoiceItemDao.getRecordId(cbaAdjItem.getId().toString());
+                    final Long cbaAdjItemRecordId = transInvoiceItemDao.getRecordId(cbaAdjItem.getId().toString(), context);
                     audits.add(new EntityAudit(TableName.INVOICE_ITEMS, cbaAdjItemRecordId, ChangeType.INSERT));
                 }
 
@@ -677,13 +684,13 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException {
-        return invoiceItemSqlDao.getById(creditId.toString());
+    public InvoiceItem getCreditById(final UUID creditId, final InternalTenantContext context) throws InvoiceApiException {
+        return invoiceItemSqlDao.getById(creditId.toString(), context);
     }
 
     @Override
     public InvoiceItem insertCredit(final UUID accountId, @Nullable final UUID invoiceId, final BigDecimal positiveCreditAmount,
-            final LocalDate effectiveDate, final Currency currency, final CallContext context) {
+                                    final LocalDate effectiveDate, final Currency currency, final InternalCallContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<InvoiceItem, InvoiceSqlDao>() {
             @Override
             public InvoiceItem inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -694,7 +701,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                 if (invoiceIdForCredit == null) {
                     final Invoice invoiceForCredit = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency);
                     transactional.create(invoiceForCredit, context);
-                    final Long invoiceForCreditRecordId = transactional.getRecordId(invoiceForCredit.getId().toString());
+                    final Long invoiceForCreditRecordId = transactional.getRecordId(invoiceForCredit.getId().toString(), context);
                     audits.add(new EntityAudit(TableName.INVOICES, invoiceForCreditRecordId, ChangeType.INSERT));
 
                     invoiceIdForCredit = invoiceForCredit.getId();
@@ -717,14 +724,14 @@ public class AuditedInvoiceDao implements InvoiceDao {
 
     @Override
     public InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId,
-            final LocalDate effectiveDate, @Nullable final BigDecimal positiveAdjAmount,
-            @Nullable final Currency currency, final CallContext context) {
+                                                   final LocalDate effectiveDate, @Nullable final BigDecimal positiveAdjAmount,
+                                                   @Nullable final Currency currency, final InternalCallContext context) {
         return invoiceSqlDao.inTransaction(new Transaction<InvoiceItem, InvoiceSqlDao>() {
             @Override
             public InvoiceItem inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
                 final List<EntityAudit> audits = new ArrayList<EntityAudit>();
                 final InvoiceItem invoiceItemAdjustment = createAdjustmentItem(transactional, invoiceId, invoiceItemId, positiveAdjAmount,
-                                                                               currency, effectiveDate);
+                                                                               currency, effectiveDate, context);
                 insertItemAndAddCBAIfNeeded(transactional, invoiceItemAdjustment, audits, context);
                 notifyBusOfInvoiceAdjustment(transactional, invoiceId, accountId, context.getUserToken());
 
@@ -737,21 +744,21 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final CallContext context) throws InvoiceApiException {
+    public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final InternalCallContext context) throws InvoiceApiException {
         invoiceSqlDao.inTransaction(new Transaction<Void, InvoiceSqlDao>() {
             @Override
             public Void inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
                 final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
                 // Retrieve the invoice and make sure it belongs to the right account
-                final Invoice invoice = transactional.getById(invoiceId.toString());
+                final Invoice invoice = transactional.getById(invoiceId.toString(), context);
                 if (invoice == null || !invoice.getAccountId().equals(accountId)) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
                 }
 
                 // Retrieve the invoice item and make sure it belongs to the right invoice
                 final InvoiceItemSqlDao invoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
-                final InvoiceItem cbaItem = invoiceItemSqlDao.getById(invoiceItemId.toString());
+                final InvoiceItem cbaItem = invoiceItemSqlDao.getById(invoiceItemId.toString(), context);
                 if (cbaItem == null || !cbaItem.getInvoiceId().equals(invoice.getId())) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
                 }
@@ -760,25 +767,26 @@ public class AuditedInvoiceDao implements InvoiceDao {
                 final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(),
                         cbaItem.getId(), cbaItem.getAmount().negate(), cbaItem.getCurrency());
                 invoiceItemSqlDao.create(cbaAdjItem, context);
-                final Long cbaAdjItemRecordId = invoiceItemSqlDao.getRecordId(cbaAdjItem.getId().toString());
+                final Long cbaAdjItemRecordId = invoiceItemSqlDao.getRecordId(cbaAdjItem.getId().toString(), context);
                 audits.add(new EntityAudit(TableName.INVOICE_ITEMS, cbaAdjItemRecordId, ChangeType.INSERT));
 
                 // Verify the final invoice balance is not negative
-                populateChildren(invoice, transactional);
+                populateChildren(invoice, transactional, context);
                 if (invoice.getBalance().compareTo(BigDecimal.ZERO) < 0) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_WOULD_BE_NEGATIVE);
                 }
 
                 // If there is more account credit than CBA we adjusted, we're done.
                 // Otherwise, we need to find further invoices on which this credit was consumed
-                final BigDecimal accountCBA = getAccountCBAFromTransaction(accountId, invoiceSqlDao);
+                final BigDecimal accountCBA = getAccountCBAFromTransaction(accountId, invoiceSqlDao, context);
                 if (accountCBA.compareTo(BigDecimal.ZERO) < 0) {
                     if (accountCBA.compareTo(cbaItem.getAmount().negate()) < 0) {
                         throw new IllegalStateException("The account balance can't be lower than the amount adjusted");
                     }
                     final List<Invoice> invoicesFollowing = transactional.getInvoicesByAccountAfterDate(accountId.toString(),
-                            invoice.getInvoiceDate().toDateTimeAtStartOfDay().toDate());
-                    populateChildren(invoicesFollowing, transactional);
+                                                                                                        invoice.getInvoiceDate().toDateTimeAtStartOfDay().toDate(),
+                                                                                                        context);
+                    populateChildren(invoicesFollowing, transactional, context);
 
                     // The remaining amount to adjust (i.e. the amount of credits used on following invoices)
                     // is the current account CBA balance (minus the sign)
@@ -819,7 +827,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
                         final InvoiceItem nextCBAAdjItem = new CreditBalanceAdjInvoiceItem(invoiceFollowing.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(),
                                 cbaItem.getId(), positiveCBAAdjItemAmount, cbaItem.getCurrency());
                         invoiceItemSqlDao.create(nextCBAAdjItem, context);
-                        final Long nextCBAAdjItemRecordId = invoiceItemSqlDao.getRecordId(nextCBAAdjItem.getId().toString());
+                        final Long nextCBAAdjItemRecordId = invoiceItemSqlDao.getRecordId(nextCBAAdjItem.getId().toString(), context);
                         audits.add(new EntityAudit(TableName.INVOICE_ITEMS, nextCBAAdjItemRecordId, ChangeType.INSERT));
 
                         if (positiveRemainderToAdjust.compareTo(BigDecimal.ZERO) == 0) {
@@ -837,8 +845,8 @@ public class AuditedInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void test() {
-        invoiceSqlDao.test();
+    public void test(final InternalTenantContext context) {
+        invoiceSqlDao.test(context);
     }
 
     /**
@@ -852,10 +860,11 @@ public class AuditedInvoiceDao implements InvoiceDao {
      * @return the adjustment item
      */
     private InvoiceItem createAdjustmentItem(final InvoiceSqlDao transactional, final UUID invoiceId, final UUID invoiceItemId,
-            final BigDecimal positiveAdjAmount, final Currency currency, final LocalDate effectiveDate) throws InvoiceApiException {
+                                             final BigDecimal positiveAdjAmount, final Currency currency,
+                                             final LocalDate effectiveDate, final InternalTenantContext context) throws InvoiceApiException {
         // First, retrieve the invoice item in question
         final InvoiceItemSqlDao invoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
-        final InvoiceItem invoiceItemToBeAdjusted = invoiceItemSqlDao.getById(invoiceItemId.toString());
+        final InvoiceItem invoiceItemToBeAdjusted = invoiceItemSqlDao.getById(invoiceItemId.toString(), context);
         if (invoiceItemToBeAdjusted == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
         }
@@ -884,11 +893,11 @@ public class AuditedInvoiceDao implements InvoiceDao {
      * @param context       the call context
      */
     private void insertItemAndAddCBAIfNeeded(final InvoiceSqlDao transactional, final InvoiceItem item,
-                                             final List<EntityAudit> audits, final CallContext context) {
+                                             final List<EntityAudit> audits, final InternalCallContext context) {
         final InvoiceItemSqlDao transInvoiceItemDao = transactional.become(InvoiceItemSqlDao.class);
         transInvoiceItemDao.create(item, context);
 
-        final Long invoiceItemRecordId = transInvoiceItemDao.getRecordId(item.getId().toString());
+        final Long invoiceItemRecordId = transInvoiceItemDao.getRecordId(item.getId().toString(), context);
         audits.add(new EntityAudit(TableName.INVOICE_ITEMS, invoiceItemRecordId, ChangeType.INSERT));
 
         addCBAIfNeeded(transactional, item.getInvoiceId(), audits, context);
@@ -903,10 +912,10 @@ public class AuditedInvoiceDao implements InvoiceDao {
      * @param context       the call context
      */
     private void addCBAIfNeeded(final InvoiceSqlDao transactional, final UUID invoiceId,
-                                final List<EntityAudit> audits, final CallContext context) {
-        final Invoice invoice = transactional.getById(invoiceId.toString());
+                                final List<EntityAudit> audits, final InternalCallContext context) {
+        final Invoice invoice = transactional.getById(invoiceId.toString(), context);
         if (invoice != null) {
-            populateChildren(invoice, transactional);
+            populateChildren(invoice, transactional, context);
         } else {
             throw new IllegalStateException("Invoice shouldn't be null for this item at this stage " + invoiceId);
         }
@@ -917,65 +926,65 @@ public class AuditedInvoiceDao implements InvoiceDao {
             final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(),
                     invoice.getBalance().negate(), invoice.getCurrency());
             transInvoiceItemDao.create(cbaAdjItem, context);
-            final Long cbaAdjItemRecordId = transInvoiceItemDao.getRecordId(cbaAdjItem.getId().toString());
+            final Long cbaAdjItemRecordId = transInvoiceItemDao.getRecordId(cbaAdjItem.getId().toString(), context);
             audits.add(new EntityAudit(TableName.INVOICE_ITEMS, cbaAdjItemRecordId, ChangeType.INSERT));
         }
     }
 
-    private BigDecimal getAccountCBAFromTransaction(final UUID accountId, final InvoiceSqlDao transactional) {
+    private BigDecimal getAccountCBAFromTransaction(final UUID accountId, final InvoiceSqlDao transactional, final InternalTenantContext context) {
         BigDecimal cba = BigDecimal.ZERO;
-        final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, transactional);
+        final List<Invoice> invoices = getAllInvoicesByAccountFromTransaction(accountId, transactional, context);
         for (final Invoice cur : invoices) {
             cba = cba.add(cur.getCBAAmount());
         }
         return cba;
     }
 
-    private void populateChildren(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao) {
-        getInvoiceItemsWithinTransaction(invoice, invoiceSqlDao);
-        getInvoicePaymentsWithinTransaction(invoice, invoiceSqlDao);
+    private void populateChildren(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao, final InternalTenantContext context) {
+        getInvoiceItemsWithinTransaction(invoice, invoiceSqlDao, context);
+        getInvoicePaymentsWithinTransaction(invoice, invoiceSqlDao, context);
     }
 
-    private void populateChildren(final List<Invoice> invoices, final InvoiceSqlDao invoiceSqlDao) {
-        getInvoiceItemsWithinTransaction(invoices, invoiceSqlDao);
-        getInvoicePaymentsWithinTransaction(invoices, invoiceSqlDao);
+    private void populateChildren(final List<Invoice> invoices, final InvoiceSqlDao invoiceSqlDao, final InternalTenantContext context) {
+        getInvoiceItemsWithinTransaction(invoices, invoiceSqlDao, context);
+        getInvoicePaymentsWithinTransaction(invoices, invoiceSqlDao, context);
     }
 
-    private List<Invoice> getAllInvoicesByAccountFromTransaction(final UUID accountId, final InvoiceSqlDao transactional) {
-        final List<Invoice> invoices = transactional.getAllInvoicesByAccount(accountId.toString());
-        populateChildren(invoices, transactional);
+    private List<Invoice> getAllInvoicesByAccountFromTransaction(final UUID accountId, final InvoiceSqlDao transactional, final InternalTenantContext context) {
+        final List<Invoice> invoices = transactional.getAllInvoicesByAccount(accountId.toString(), context);
+        populateChildren(invoices, transactional, context);
         return invoices;
     }
 
-    private BigDecimal getRemainingAmountPaidFromTransaction(final UUID invoicePaymentId, final InvoicePaymentSqlDao transactional) {
-        final BigDecimal amount = transactional.getRemainingAmountPaid(invoicePaymentId.toString());
+    private BigDecimal getRemainingAmountPaidFromTransaction(final UUID invoicePaymentId, final InvoicePaymentSqlDao transactional, final InternalTenantContext context) {
+        final BigDecimal amount = transactional.getRemainingAmountPaid(invoicePaymentId.toString(), context);
         return amount == null ? BigDecimal.ZERO : amount;
     }
 
-    private void getInvoiceItemsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceDao) {
+    private void getInvoiceItemsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceDao, final InternalTenantContext context) {
         for (final Invoice invoice : invoices) {
-            getInvoiceItemsWithinTransaction(invoice, invoiceDao);
+            getInvoiceItemsWithinTransaction(invoice, invoiceDao, context);
         }
     }
 
-    private void getInvoiceItemsWithinTransaction(final Invoice invoice, final InvoiceSqlDao transactional) {
+    private void getInvoiceItemsWithinTransaction(final Invoice invoice, final InvoiceSqlDao transactional, final InternalTenantContext context) {
         final String invoiceId = invoice.getId().toString();
 
         final InvoiceItemSqlDao transInvoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
-        final List<InvoiceItem> items = transInvoiceItemSqlDao.getInvoiceItemsByInvoice(invoiceId);
+        final List<InvoiceItem> items = transInvoiceItemSqlDao.getInvoiceItemsByInvoice(invoiceId, context);
         invoice.addInvoiceItems(items);
     }
 
-    private void getInvoicePaymentsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceDao) {
+    private void getInvoicePaymentsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceDao, final InternalTenantContext context) {
         for (final Invoice invoice : invoices) {
-            getInvoicePaymentsWithinTransaction(invoice, invoiceDao);
+            getInvoicePaymentsWithinTransaction(invoice, invoiceDao, context);
         }
     }
 
-    private void getInvoicePaymentsWithinTransaction(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao) {
+    private void getInvoicePaymentsWithinTransaction(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao, final InternalTenantContext context) {
         final InvoicePaymentSqlDao invoicePaymentSqlDao = invoiceSqlDao.become(InvoicePaymentSqlDao.class);
         final String invoiceId = invoice.getId().toString();
-        final List<InvoicePayment> invoicePayments = invoicePaymentSqlDao.getPaymentsForInvoice(invoiceId);
+        final List<InvoicePayment> invoicePayments = invoicePaymentSqlDao.getPaymentsForInvoice(invoiceId, context);
         invoice.addPayments(invoicePayments);
     }
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index 936fc83..a97492e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -31,45 +31,46 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.util.api.TagApiException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface InvoiceDao {
 
-    void create(final Invoice invoice, final int billCycleDayUTC, final boolean isRealInvoice, final CallContext context);
+    void create(Invoice invoice, int billCycleDayUTC, boolean isRealInvoice, InternalCallContext context);
 
-    Invoice getById(final UUID id) throws InvoiceApiException;
+    Invoice getById(UUID id, InternalTenantContext context) throws InvoiceApiException;
 
-    Invoice getByNumber(final Integer number) throws InvoiceApiException;
+    Invoice getByNumber(Integer number, InternalTenantContext context) throws InvoiceApiException;
 
-    List<Invoice> get();
+    List<Invoice> get(InternalTenantContext context);
 
-    List<Invoice> getInvoicesByAccount(final UUID accountId);
+    List<Invoice> getInvoicesByAccount(UUID accountId, InternalTenantContext context);
 
-    List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate);
+    List<Invoice> getInvoicesByAccount(UUID accountId, LocalDate fromDate, InternalTenantContext context);
 
-    List<Invoice> getInvoicesBySubscription(final UUID subscriptionId);
+    List<Invoice> getInvoicesBySubscription(UUID subscriptionId, InternalTenantContext context);
 
-    UUID getInvoiceIdByPaymentId(final UUID paymentId);
+    UUID getInvoiceIdByPaymentId(UUID paymentId, InternalTenantContext context);
 
-    List<InvoicePayment> getInvoicePayments(final UUID paymentId);
+    List<InvoicePayment> getInvoicePayments(UUID paymentId, InternalTenantContext context);
 
-    void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context);
+    void notifyOfPayment(InvoicePayment invoicePayment, InternalCallContext context);
 
-    BigDecimal getAccountBalance(final UUID accountId);
+    BigDecimal getAccountBalance(UUID accountId, InternalTenantContext context);
 
-    public BigDecimal getAccountCBA(final UUID accountId);
+    public BigDecimal getAccountCBA(UUID accountId, InternalTenantContext context);
 
-    List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, @Nullable final LocalDate upToDate);
+    List<Invoice> getUnpaidInvoicesByAccountId(UUID accountId, @Nullable LocalDate upToDate, InternalTenantContext context);
 
-    void test();
+    void test(InternalTenantContext context);
 
-    List<Invoice> getAllInvoicesByAccount(final UUID accountId);
+    List<Invoice> getAllInvoicesByAccount(UUID accountId, InternalTenantContext context);
 
-    void setWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException;
+    void setWrittenOff(UUID invoiceId, InternalCallContext context) throws TagApiException;
 
-    void removeWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException;
+    void removeWrittenOff(UUID invoiceId, InternalCallContext context) throws TagApiException;
 
-    InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException;
+    InvoicePayment postChargeback(UUID invoicePaymentId, BigDecimal amount, InternalCallContext context) throws InvoiceApiException;
 
     /**
      * Create a refund.
@@ -83,18 +84,18 @@ public interface InvoiceDao {
      * @return the created invoice payment object associated with this refund
      * @throws InvoiceApiException
      */
-    InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts,
-                                final UUID paymentCookieId, final CallContext context) throws InvoiceApiException;
+    InvoicePayment createRefund(UUID paymentId, BigDecimal amount, boolean isInvoiceAdjusted, Map<UUID, BigDecimal> invoiceItemIdsWithAmounts,
+                                UUID paymentCookieId, InternalCallContext context) throws InvoiceApiException;
 
-    BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId);
+    BigDecimal getRemainingAmountPaid(UUID invoicePaymentId, InternalTenantContext context);
 
-    UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId) throws InvoiceApiException;
+    UUID getAccountIdFromInvoicePaymentId(UUID invoicePaymentId, InternalTenantContext context) throws InvoiceApiException;
 
-    List<InvoicePayment> getChargebacksByAccountId(final UUID accountId);
+    List<InvoicePayment> getChargebacksByAccountId(UUID accountId, InternalTenantContext context);
 
-    List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId);
+    List<InvoicePayment> getChargebacksByPaymentId(UUID paymentId, InternalTenantContext context);
 
-    InvoicePayment getChargebackById(final UUID chargebackId) throws InvoiceApiException;
+    InvoicePayment getChargebackById(UUID chargebackId, InternalTenantContext context) throws InvoiceApiException;
 
     /**
      * Retrieve am external charge by id.
@@ -103,7 +104,7 @@ public interface InvoiceDao {
      * @return the external charge invoice item
      * @throws InvoiceApiException
      */
-    InvoiceItem getExternalChargeById(final UUID externalChargeId) throws InvoiceApiException;
+    InvoiceItem getExternalChargeById(UUID externalChargeId, InternalTenantContext context) throws InvoiceApiException;
 
     /**
      * Add an external charge to a given account and invoice. If invoiceId is null, a new invoice will be created.
@@ -118,8 +119,8 @@ public interface InvoiceDao {
      * @param context       the call context
      * @return the newly created external charge invoice item
      */
-    InvoiceItem insertExternalCharge(final UUID accountId, @Nullable final UUID invoiceId, @Nullable final UUID bundleId, @Nullable final String description,
-                                     final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context) throws InvoiceApiException;
+    InvoiceItem insertExternalCharge(UUID accountId, @Nullable UUID invoiceId, @Nullable UUID bundleId, @Nullable String description,
+                                     BigDecimal amount, LocalDate effectiveDate, Currency currency, InternalCallContext context) throws InvoiceApiException;
 
     /**
      * Retrieve a credit by id.
@@ -128,7 +129,7 @@ public interface InvoiceDao {
      * @return the credit invoice item
      * @throws InvoiceApiException
      */
-    InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException;
+    InvoiceItem getCreditById(UUID creditId, InternalTenantContext context) throws InvoiceApiException;
 
     /**
      * Add a credit to a given account and invoice. If invoiceId is null, a new invoice will be created.
@@ -141,8 +142,8 @@ public interface InvoiceDao {
      * @param context       the call context
      * @return the newly created credit invoice item
      */
-    InvoiceItem insertCredit(final UUID accountId, @Nullable final UUID invoiceId, final BigDecimal amount,
-                             final LocalDate effectiveDate, final Currency currency, final CallContext context);
+    InvoiceItem insertCredit(UUID accountId, @Nullable UUID invoiceId, BigDecimal amount,
+                             LocalDate effectiveDate, Currency currency, InternalCallContext context);
 
     /**
      * Adjust an invoice item.
@@ -156,8 +157,8 @@ public interface InvoiceDao {
      * @param context       the call context
      * @return the newly created adjustment item
      */
-    InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final LocalDate effectiveDate,
-                                            @Nullable final BigDecimal amount, @Nullable final Currency currency, final CallContext context);
+    InvoiceItem insertInvoiceItemAdjustment(UUID accountId, UUID invoiceId, UUID invoiceItemId, LocalDate effectiveDate,
+                                            @Nullable BigDecimal amount, @Nullable Currency currency, InternalCallContext context);
 
     /**
      * Delete a CBA item.
@@ -166,5 +167,5 @@ public interface InvoiceDao {
      * @param invoiceId     the invoice id
      * @param invoiceItemId the invoice item id of the cba item to delete
      */
-    void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final CallContext context) throws InvoiceApiException;
+    void deleteCBA(UUID accountId, UUID invoiceId, UUID invoiceItemId, InternalCallContext context) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
index b990922..bb62a38 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
@@ -52,8 +52,9 @@ import com.ning.billing.invoice.model.ItemAdjInvoiceItem;
 import com.ning.billing.invoice.model.RecurringInvoiceItem;
 import com.ning.billing.invoice.model.RefundAdjInvoiceItem;
 import com.ning.billing.invoice.model.RepairAdjInvoiceItem;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.entity.dao.EntitySqlDao;
 
@@ -62,23 +63,29 @@ import com.ning.billing.util.entity.dao.EntitySqlDao;
 public interface InvoiceItemSqlDao extends EntitySqlDao<InvoiceItem> {
 
     @SqlQuery
-    List<Long> getRecordIds(@Bind("invoiceId") final String invoiceId);
+    List<Long> getRecordIds(@Bind("invoiceId") final String invoiceId,
+                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoiceItem> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId);
+    List<InvoiceItem> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId,
+                                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoiceItem> getInvoiceItemsByAccount(@Bind("accountId") final String accountId);
+    List<InvoiceItem> getInvoiceItemsByAccount(@Bind("accountId") final String accountId,
+                                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoiceItem> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId);
+    List<InvoiceItem> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId,
+                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
-    void create(@InvoiceItemBinder final InvoiceItem invoiceItem, @CallContextBinder final CallContext context);
+    void create(@InvoiceItemBinder final InvoiceItem invoiceItem,
+                @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch(transactional = false)
-    void batchCreateFromTransaction(@InvoiceItemBinder final List<InvoiceItem> items, @CallContextBinder final CallContext context);
+    void batchCreateFromTransaction(@InvoiceItemBinder final List<InvoiceItem> items,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @BindingAnnotation(InvoiceItemBinder.InvoiceItemBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
@@ -131,7 +138,7 @@ public interface InvoiceItemSqlDao extends EntitySqlDao<InvoiceItem> {
             final Currency currency = Currency.valueOf(result.getString("currency"));
             final UUID linkedItemId = getUUID(result, "linked_item_id");
 
-            InvoiceItem item = null;
+            final InvoiceItem item;
             switch (type) {
                 case EXTERNAL_CHARGE:
                     item = new ExternalChargeInvoiceItem(id, invoiceId, accountId, bundleId, planName, startDate, amount, currency);
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
index 1ea5cb3..f387ec8 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -47,8 +47,9 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
@@ -60,46 +61,58 @@ import com.ning.billing.util.entity.dao.EntitySqlDao;
 public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePayment>, Transactional<InvoicePaymentSqlDao>, AuditSqlDao, Transmogrifier {
 
     @SqlQuery
-    List<Long> getRecordIds(@Bind("invoiceId") final String invoiceId);
+    List<Long> getRecordIds(@Bind("invoiceId") final String invoiceId,
+                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public InvoicePayment getByPaymentId(@Bind("paymentId") final String paymentId);
+    public InvoicePayment getByPaymentId(@Bind("paymentId") final String paymentId,
+                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlQuery
-    public List<InvoicePayment> get();
+    public List<InvoicePayment> get(@InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
-    public void create(@InvoicePaymentBinder final InvoicePayment invoicePayment, @CallContextBinder final CallContext context);
+    public void create(@InvoicePaymentBinder final InvoicePayment invoicePayment,
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch(transactional = false)
-    void batchCreateFromTransaction(@InvoicePaymentBinder final List<InvoicePayment> items, @CallContextBinder final CallContext context);
+    void batchCreateFromTransaction(@InvoicePaymentBinder final List<InvoicePayment> items,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public List<InvoicePayment> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId);
+    public List<InvoicePayment> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId,
+                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoicePayment> getInvoicePayments(@Bind("paymentId") final String paymentId);
+    List<InvoicePayment> getInvoicePayments(@Bind("paymentId") final String paymentId,
+                                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    InvoicePayment getPaymentsForCookieId(@Bind("paymentCookieId") final String paymentCookieId);
+    InvoicePayment getPaymentsForCookieId(@Bind("paymentCookieId") final String paymentCookieId,
+                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void notifyOfPayment(@InvoicePaymentBinder final InvoicePayment invoicePayment, @CallContextBinder final CallContext context);
+    void notifyOfPayment(@InvoicePaymentBinder final InvoicePayment invoicePayment,
+                         @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    BigDecimal getRemainingAmountPaid(@Bind("invoicePaymentId") final String invoicePaymentId);
+    BigDecimal getRemainingAmountPaid(@Bind("invoicePaymentId") final String invoicePaymentId,
+                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @RegisterMapper(UuidMapper.class)
-    UUID getAccountIdFromInvoicePaymentId(@Bind("invoicePaymentId") final String invoicePaymentId);
+    UUID getAccountIdFromInvoicePaymentId(@Bind("invoicePaymentId") final String invoicePaymentId,
+                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoicePayment> getChargeBacksByAccountId(@Bind("accountId") final String accountId);
+    List<InvoicePayment> getChargeBacksByAccountId(@Bind("accountId") final String accountId,
+                                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoicePayment> getChargebacksByPaymentId(@Bind("paymentId") final String paymentId);
+    List<InvoicePayment> getChargebacksByPaymentId(@Bind("paymentId") final String paymentId,
+                                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     public static class InvoicePaymentMapper extends MapperBase implements ResultSetMapper<InvoicePayment> {
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
index 6581d3f..138608e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
@@ -27,7 +27,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -47,8 +46,9 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.model.DefaultInvoice;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.dao.UuidMapper;
@@ -60,24 +60,30 @@ public interface InvoiceSqlDao extends EntitySqlDao<Invoice>, AuditSqlDao, Trans
 
     @Override
     @SqlUpdate
-    void create(@InvoiceBinder Invoice invoice, @CallContextBinder final CallContext context);
+    void create(@InvoiceBinder Invoice invoice,
+                @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    List<Invoice> getInvoicesByAccount(@Bind("accountId") final String accountId);
+    List<Invoice> getInvoicesByAccount(@Bind("accountId") final String accountId,
+                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<Invoice> getAllInvoicesByAccount(@Bind("accountId") final String string);
+    List<Invoice> getAllInvoicesByAccount(@Bind("accountId") final String string,
+                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     List<Invoice> getInvoicesByAccountAfterDate(@Bind("accountId") final String accountId,
-                                                @Bind("fromDate") final Date fromDate);
+                                                @Bind("fromDate") final Date fromDate,
+                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<Invoice> getInvoicesBySubscription(@Bind("subscriptionId") final String subscriptionId);
+    List<Invoice> getInvoicesBySubscription(@Bind("subscriptionId") final String subscriptionId,
+                                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @RegisterMapper(UuidMapper.class)
-    UUID getInvoiceIdByPaymentId(@Bind("paymentId") final String paymentId);
+    UUID getInvoiceIdByPaymentId(@Bind("paymentId") final String paymentId,
+                                 @InternalTenantContextBinder final InternalTenantContext context);
 
     @BindingAnnotation(InvoiceBinder.InvoiceBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index 5bf88e5..59b0553 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -35,7 +35,6 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.entitlement.api.billing.BillingEvent;
 import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.invoice.api.Invoice;
@@ -56,6 +55,8 @@ import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.bus.BusEvent;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLock;
 import com.ning.billing.util.globallocker.GlobalLocker;
@@ -79,15 +80,17 @@ public class InvoiceDispatcher {
     private final GlobalLocker locker;
     private final Bus eventBus;
     private final Clock clock;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public InvoiceDispatcher(final InvoiceGenerator generator, final AccountUserApi accountUserApi,
-            final BillingApi billingApi,
-            final InvoiceDao invoiceDao,
-            final InvoiceNotifier invoiceNotifier,
-            final GlobalLocker locker,
-            final Bus eventBus,
-            final Clock clock) {
+                             final BillingApi billingApi,
+                             final InvoiceDao invoiceDao,
+                             final InvoiceNotifier invoiceNotifier,
+                             final GlobalLocker locker,
+                             final Bus eventBus,
+                             final Clock clock,
+                             final InternalCallContextFactory internalCallContextFactory) {
         this.generator = generator;
         this.billingApi = billingApi;
         this.accountUserApi = accountUserApi;
@@ -96,33 +99,33 @@ public class InvoiceDispatcher {
         this.locker = locker;
         this.eventBus = eventBus;
         this.clock = clock;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     public void processSubscription(final EffectiveSubscriptionEvent transition,
-            final CallContext context) throws InvoiceApiException {
+                                    final CallContext context) throws InvoiceApiException {
         final UUID subscriptionId = transition.getSubscriptionId();
         final DateTime targetDate = transition.getEffectiveTransitionTime();
         log.info("Got subscription transition: type: " + transition.getTransitionType().toString() + "; id: " + subscriptionId.toString() + "; targetDate: " + targetDate.toString());
         processSubscription(subscriptionId, targetDate, context);
     }
 
-    public void processSubscription(final UUID subscriptionId, final DateTime targetDate,
-            final CallContext context) throws InvoiceApiException {
+    public void processSubscription(final UUID subscriptionId, final DateTime targetDate, final CallContext context) throws InvoiceApiException {
         try {
             if (subscriptionId == null) {
                 log.error("Failed handling entitlement change.", new InvoiceApiException(ErrorCode.INVOICE_INVALID_TRANSITION));
                 return;
             }
-            final UUID accountId = billingApi.getAccountIdFromSubscriptionId(subscriptionId);
+            final UUID accountId = billingApi.getAccountIdFromSubscriptionId(subscriptionId, context);
             processAccount(accountId, targetDate, false, context);
         } catch (EntitlementBillingApiException e) {
             log.error("Failed handling entitlement change.",
-                    new InvoiceApiException(ErrorCode.INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID, subscriptionId.toString()));
+                      new InvoiceApiException(ErrorCode.INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID, subscriptionId.toString()));
         }
     }
 
     public Invoice processAccount(final UUID accountId, final DateTime targetDate,
-            final boolean dryRun, final CallContext context) throws InvoiceApiException {
+                                  final boolean dryRun, final CallContext context) throws InvoiceApiException {
         GlobalLock lock = null;
         try {
             lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT, accountId.toString(), NB_LOCK_TRY);
@@ -131,7 +134,7 @@ public class InvoiceDispatcher {
         } catch (LockFailedException e) {
             // Not good!
             log.error(String.format("Failed to process invoice for account %s, targetDate %s",
-                    accountId.toString(), targetDate), e);
+                                    accountId.toString(), targetDate), e);
         } finally {
             if (lock != null) {
                 lock.release();
@@ -141,15 +144,15 @@ public class InvoiceDispatcher {
     }
 
     private Invoice processAccountWithLock(final UUID accountId, final DateTime targetDateTime,
-            final boolean dryRun, final CallContext context) throws InvoiceApiException {
+                                           final boolean dryRun, final CallContext context) throws InvoiceApiException {
         try {
             // Make sure to first set the BCD if needed then get the account object (to have the BCD set)
-            final BillingEventSet billingEvents = billingApi.getBillingEventsForAccountAndUpdateAccountBCD(accountId);
-            final Account account = accountUserApi.getAccountById(accountId);
+            final BillingEventSet billingEvents = billingApi.getBillingEventsForAccountAndUpdateAccountBCD(accountId, context);
+            final Account account = accountUserApi.getAccountById(accountId, context);
 
             List<Invoice> invoices = new ArrayList<Invoice>();
             if (!billingEvents.isAccountAutoInvoiceOff()) {
-                invoices = invoiceDao.getInvoicesByAccount(accountId); //no need to fetch, invoicing is off on this account
+                invoices = invoiceDao.getInvoicesByAccount(accountId, internalCallContextFactory.createInternalTenantContext(account.getId(), context)); //no need to fetch, invoicing is off on this account
             }
 
             final Currency targetCurrency = account.getCurrency();
@@ -158,6 +161,7 @@ public class InvoiceDispatcher {
             final LocalDate targetDate = new LocalDate(targetDateTime, account.getTimeZone());
 
             final Invoice invoice = generator.generateInvoice(accountId, billingEvents, invoices, targetDate, account.getTimeZone(), targetCurrency);
+            final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), context);
 
             if (invoice == null) {
                 log.info("Generated null invoice.");
@@ -176,15 +180,15 @@ public class InvoiceDispatcher {
                         }
                     }).size() > 0;
 
-                    invoiceDao.create(invoice, account.getBillCycleDay().getDayOfMonthUTC(), isRealInvoiceWithItems, context);
+                    invoiceDao.create(invoice, account.getBillCycleDay().getDayOfMonthUTC(), isRealInvoiceWithItems, internalCallContext);
 
                     final List<InvoiceItem> fixedPriceInvoiceItems = invoice.getInvoiceItems(FixedPriceInvoiceItem.class);
                     final List<InvoiceItem> recurringInvoiceItems = invoice.getInvoiceItems(RecurringInvoiceItem.class);
                     setChargedThroughDates(account.getBillCycleDay(), account.getTimeZone(), fixedPriceInvoiceItems, recurringInvoiceItems, context);
 
                     final InvoiceCreationEvent event = new DefaultInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
-                            invoice.getBalance(), invoice.getCurrency(),
-                            context.getUserToken());
+                                                                                       invoice.getBalance(), invoice.getCurrency(),
+                                                                                       context.getUserToken());
 
                     if (isRealInvoiceWithItems) {
                         postEvent(event, accountId);
@@ -192,8 +196,9 @@ public class InvoiceDispatcher {
                 }
             }
 
-            if (account.isNotifiedForInvoices()) {
-                invoiceNotifier.notify(account, invoice);
+            if (account.isNotifiedForInvoices() && invoice != null && !dryRun) {
+                // Need to re-hydrate the invoice object to get the invoice number (record id)
+                invoiceNotifier.notify(account, invoiceDao.getById(invoice.getId(), internalCallContext), context);
             }
 
             return invoice;
@@ -204,10 +209,10 @@ public class InvoiceDispatcher {
     }
 
     private void setChargedThroughDates(final BillCycleDay billCycleDay,
-            final DateTimeZone accountTimeZone,
-            final Collection<InvoiceItem> fixedPriceItems,
-            final Collection<InvoiceItem> recurringItems,
-            final CallContext context) {
+                                        final DateTimeZone accountTimeZone,
+                                        final Collection<InvoiceItem> fixedPriceItems,
+                                        final Collection<InvoiceItem> recurringItems,
+                                        final CallContext context) {
         final Map<UUID, LocalDate> chargeThroughDates = new HashMap<UUID, LocalDate>();
         addInvoiceItemsToChargeThroughDates(billCycleDay, accountTimeZone, chargeThroughDates, fixedPriceItems);
         addInvoiceItemsToChargeThroughDates(billCycleDay, accountTimeZone, chargeThroughDates, recurringItems);
@@ -230,9 +235,9 @@ public class InvoiceDispatcher {
     }
 
     private void addInvoiceItemsToChargeThroughDates(final BillCycleDay billCycleDay,
-            final DateTimeZone accountTimeZone,
-            final Map<UUID, LocalDate> chargeThroughDates,
-            final Collection<InvoiceItem> items) {
+                                                     final DateTimeZone accountTimeZone,
+                                                     final Map<UUID, LocalDate> chargeThroughDates,
+                                                     final Collection<InvoiceItem> items) {
 
         for (final InvoiceItem item : items) {
             final UUID subscriptionId = item.getSubscriptionId();
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
index d6d2b93..ed30173 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -49,7 +49,8 @@ public class InvoiceListener {
     @Subscribe
     public void handleRepairEntitlementEvent(final RepairEntitlementEvent repairEvent) {
         try {
-            final CallContext context = factory.createCallContext("RepairBundle", CallOrigin.INTERNAL, UserType.SYSTEM, repairEvent.getUserToken());
+            // TODO retrieve tenantId?
+            final CallContext context = factory.createCallContext(null, "RepairBundle", CallOrigin.INTERNAL, UserType.SYSTEM, repairEvent.getUserToken());
             dispatcher.processAccount(repairEvent.getAccountId(), repairEvent.getEffectiveDate(), false, context);
         } catch (InvoiceApiException e) {
             log.error(e.getMessage());
@@ -67,7 +68,8 @@ public class InvoiceListener {
                 return;
             }
 
-            final CallContext context = factory.createCallContext("Transition", CallOrigin.INTERNAL, UserType.SYSTEM, transition.getUserToken());
+            // TODO retrieve tenantId?
+            final CallContext context = factory.createCallContext(null, "Transition", CallOrigin.INTERNAL, UserType.SYSTEM, transition.getUserToken());
             dispatcher.processSubscription(transition, context);
         } catch (InvoiceApiException e) {
             log.error(e.getMessage());
@@ -76,7 +78,8 @@ public class InvoiceListener {
 
     public void handleNextBillingDateEvent(final UUID subscriptionId, final DateTime eventDateTime) {
         try {
-            final CallContext context = factory.createCallContext("Next Billing Date", CallOrigin.INTERNAL, UserType.SYSTEM);
+            // TODO retrieve tenantId?
+            final CallContext context = factory.createCallContext(null, "Next Billing Date", CallOrigin.INTERNAL, UserType.SYSTEM);
             dispatcher.processSubscription(subscriptionId, eventDateTime, context);
         } catch (InvoiceApiException e) {
             log.error(e.getMessage());
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
index 99e4f28..8c5e122 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
@@ -22,7 +22,6 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.config.InvoiceConfig;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
@@ -30,6 +29,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.invoice.InvoiceListener;
 import com.ning.billing.invoice.api.DefaultInvoiceService;
+import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -37,7 +37,10 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 
+import com.google.inject.Inject;
+
 public class DefaultNextBillingDateNotifier implements NextBillingDateNotifier {
+
     private static final Logger log = LoggerFactory.getLogger(DefaultNextBillingDateNotifier.class);
 
     public static final String NEXT_BILLING_DATE_NOTIFIER_QUEUE = "next-billing-date-queue";
@@ -45,17 +48,22 @@ public class DefaultNextBillingDateNotifier implements NextBillingDateNotifier {
     private final NotificationQueueService notificationQueueService;
     private final InvoiceConfig config;
     private final EntitlementUserApi entitlementUserApi;
+    private final InvoiceListener listener;
+    private final CallContextFactory callContextFactory;
 
     private NotificationQueue nextBillingQueue;
-    private final InvoiceListener listener;
 
     @Inject
     public DefaultNextBillingDateNotifier(final NotificationQueueService notificationQueueService,
-                                          final InvoiceConfig config, final EntitlementUserApi entitlementUserApi, final InvoiceListener listener) {
+                                          final InvoiceConfig config,
+                                          final EntitlementUserApi entitlementUserApi,
+                                          final InvoiceListener listener,
+                                          final CallContextFactory callContextFactory) {
         this.notificationQueueService = notificationQueueService;
         this.config = config;
         this.entitlementUserApi = entitlementUserApi;
         this.listener = listener;
+        this.callContextFactory = callContextFactory;
     }
 
     @Override
@@ -83,7 +91,7 @@ public class DefaultNextBillingDateNotifier implements NextBillingDateNotifier {
 
                     final NextBillingDateNotificationKey key = (NextBillingDateNotificationKey) notificationKey;
                     try {
-                        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(key.getUuidKey());
+                        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(key.getUuidKey(), callContextFactory.createTenantContext(null));
                         if (subscription == null) {
                             log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")");
                         } else {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
index 5b87451..c1b2401 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
@@ -26,6 +26,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.ning.billing.invoice.api.DefaultInvoiceService;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.notificationq.Notification;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -38,33 +42,43 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
     private static final Logger log = LoggerFactory.getLogger(DefaultNextBillingDatePoster.class);
 
     private final NotificationQueueService notificationQueueService;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultNextBillingDatePoster(final NotificationQueueService notificationQueueService) {
+    public DefaultNextBillingDatePoster(final NotificationQueueService notificationQueueService,
+                                        final InternalCallContextFactory internalCallContextFactory) {
         this.notificationQueueService = notificationQueueService;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
     public void insertNextBillingNotification(final Transmogrifier transactionalDao, final UUID accountId,
                                               final UUID subscriptionId, final DateTime futureNotificationTime) {
+        final InternalCallContext context = createCallContext();
+
         final NotificationQueue nextBillingQueue;
         try {
             nextBillingQueue = notificationQueueService.getNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME,
                                                                              DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
             log.info("Queuing next billing date notification. id: {}, timestamp: {}", subscriptionId.toString(), futureNotificationTime.toString());
 
-            final List<Notification> existingNotifications = nextBillingQueue.getNotificationForAccountAndDate(accountId, futureNotificationTime);
+            final List<Notification> existingNotifications = nextBillingQueue.getNotificationForAccountAndDate(accountId, futureNotificationTime, context);
             if (existingNotifications.size() > 0) {
                 log.info(String.format("%s : notification for account %s and date %s already exist, skip...",
                                        DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE, accountId, futureNotificationTime));
                 return;
             }
 
-            nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, accountId, new NextBillingDateNotificationKey(subscriptionId));
+            nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, accountId,
+                                                                     new NextBillingDateNotificationKey(subscriptionId), context);
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to put items on a non-existent queue (NextBillingDateNotifier).", e);
         } catch (IOException e) {
             log.error("Failed to serialize notficationKey for subscriptionId {}", subscriptionId);
         }
     }
+
+    private InternalCallContext createCallContext() {
+        return internalCallContextFactory.createInternalCallContext("NextBillingDatePoster", CallOrigin.INTERNAL, UserType.SYSTEM, null);
+    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
index aa63fe3..e77eae7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
@@ -31,6 +31,8 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.template.HtmlInvoiceGenerator;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.email.DefaultEmailSender;
 import com.ning.billing.util.email.EmailApiException;
@@ -44,22 +46,29 @@ public class EmailInvoiceNotifier implements InvoiceNotifier {
     private final TagUserApi tagUserApi;
     private final HtmlInvoiceGenerator generator;
     private final EmailConfig config;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public EmailInvoiceNotifier(final AccountUserApi accountUserApi, final TagUserApi tagUserApi,
-                                final HtmlInvoiceGenerator generator, final EmailConfig config) {
+    public EmailInvoiceNotifier(final AccountUserApi accountUserApi,
+                                final TagUserApi tagUserApi,
+                                final HtmlInvoiceGenerator generator,
+                                final EmailConfig config,
+                                final InternalCallContextFactory internalCallContextFactory) {
         this.accountUserApi = accountUserApi;
         this.tagUserApi = tagUserApi;
         this.generator = generator;
         this.config = config;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public void notify(final Account account, final Invoice invoice) throws InvoiceApiException {
+    public void notify(final Account account, final Invoice invoice, final TenantContext context) throws InvoiceApiException {
+        final TenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(account.getId(), context).toTenantContext();
+
         final List<String> to = new ArrayList<String>();
         to.add(account.getEmail());
 
-        final List<AccountEmail> accountEmailList = accountUserApi.getEmails(account.getId());
+        final List<AccountEmail> accountEmailList = accountUserApi.getEmails(account.getId(), tenantContext);
         final List<String> cc = new ArrayList<String>();
         for (final AccountEmail email : accountEmailList) {
             cc.add(email.getEmail());
@@ -67,7 +76,7 @@ public class EmailInvoiceNotifier implements InvoiceNotifier {
 
         // Check if this account has the MANUAL_PAY system tag
         boolean manualPay = false;
-        final Map<String, Tag> accountTags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT);
+        final Map<String, Tag> accountTags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT, tenantContext);
         for (final Tag tag : accountTags.values()) {
             if (ControlTagType.MANUAL_PAY.getId().equals(tag.getTagDefinitionId())) {
                 manualPay = true;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/NullInvoiceNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/NullInvoiceNotifier.java
index 78cc394..7b49d5f 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/NullInvoiceNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/NullInvoiceNotifier.java
@@ -19,11 +19,12 @@ package com.ning.billing.invoice.notification;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceNotifier;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class NullInvoiceNotifier implements InvoiceNotifier {
 
     @Override
-    public void notify(final Account account, final Invoice invoice) {
+    public void notify(final Account account, final Invoice invoice, final TenantContext context) {
         // deliberate no-op
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/TagHandler.java b/invoice/src/main/java/com/ning/billing/invoice/TagHandler.java
index 01e82c1..fc8720f 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/TagHandler.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/TagHandler.java
@@ -20,8 +20,6 @@ import java.util.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Inject;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
@@ -32,6 +30,9 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.api.ControlTagDeletionEvent;
 
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+
 public class TagHandler {
 
     private static final Logger log = LoggerFactory.getLogger(TagHandler.class);
@@ -56,7 +57,8 @@ public class TagHandler {
 
     private void processUnpaid_AUTO_INVOICING_OFF_invoices(final UUID accountId, final UUID userToken) {
         try {
-            final CallContext context = new DefaultCallContext("InvoiceTagHandler", CallOrigin.INTERNAL, UserType.SYSTEM, userToken, clock);
+            // TODO retrieve tenantId?
+            final CallContext context = new DefaultCallContext(null, "InvoiceTagHandler", CallOrigin.INTERNAL, UserType.SYSTEM, userToken, clock);
             dispatcher.processAccount(accountId, clock.getUTCNow(), false, context);
         } catch (InvoiceApiException e) {
             log.warn(String.format("Failed to process process removal AUTO_INVOICING_OFF for account %s", accountId), e);
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index 0c14015..ec2bcd4 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group InvoiceItemSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
   <prefix>id,
   <prefix>type,  
@@ -16,59 +19,77 @@ fields(prefix) ::= <<
   <prefix>currency,
   <prefix>linked_item_id,
   <prefix>created_by,
-  <prefix>created_date
+  <prefix>created_date,
+  <prefix>account_record_id,
+  <prefix>tenant_record_id
 >>
 
 getById() ::= <<
   SELECT <fields()>
   FROM invoice_items
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getByRecordId() ::= <<
   SELECT <fields()>
   FROM invoice_items
-  WHERE record_id = :recordId;
+  WHERE record_id = :recordId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getRecordId() ::= <<
   SELECT record_id
   FROM invoice_items
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getInvoiceItemsByInvoice() ::= <<
   SELECT <fields()>
   FROM invoice_items
-  WHERE invoice_id = :invoiceId;
+  WHERE invoice_id = :invoiceId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getInvoiceItemsByAccount() ::= <<
   SELECT <fields()>
   FROM invoice_items
-  WHERE account_id = :accountId;
+  WHERE account_id = :accountId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getInvoiceItemsBySubscription() ::= <<
   SELECT <fields()>
   FROM invoice_items
-  WHERE subscription_id = :subscriptionId;
+  WHERE subscription_id = :subscriptionId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 create() ::= <<
   INSERT INTO invoice_items(<fields()>)
-  VALUES(:id, :type, :invoiceId, :accountId, :bundleId, :subscriptionId, :planName, :phaseName, :startDate, :endDate, :amount, :rate, :currency, :linkedItemId, :userName, :createdDate);
+  VALUES(:id, :type, :invoiceId, :accountId, :bundleId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
+         :amount, :rate, :currency, :linkedItemId, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 batchCreateFromTransaction() ::= <<
   INSERT INTO invoice_items(<fields()>)
-  VALUES(:id, :type,:invoiceId, :accountId, :bundleId, :subscriptionId, :planName, :phaseName, :startDate, :endDate, :amount, :rate, :currency, :linkedItemId, :userName, :createdDate);
+  VALUES(:id, :type,:invoiceId, :accountId, :bundleId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
+         :amount, :rate, :currency, :linkedItemId, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getRecordIds() ::= <<
     SELECT record_id, id
     FROM invoice_items
-    WHERE invoice_id = :invoiceId;
+    WHERE invoice_id = :invoiceId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -79,16 +100,20 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
   SELECT 1
-  FROM invoice_items;
+  FROM invoice_items
+  WHERE <CHECK_TENANT()>
+  ;
 >>
 ;
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 0ba9369..77139a9 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group InvoicePayment;
 
+CHECK_TENANT(prefix) ::= "<prefix>tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT(prefix) ::= "AND <CHECK_TENANT(prefix)>"
+
 invoicePaymentFields(prefix) ::= <<
   <prefix>id,
   <prefix>type,
@@ -11,72 +14,90 @@ invoicePaymentFields(prefix) ::= <<
   <prefix>payment_cookie_id,
   <prefix>linked_invoice_payment_id,
   <prefix>created_by,
-  <prefix>created_date
+  <prefix>created_date,
+  <prefix>account_record_id,
+  <prefix>tenant_record_id
 >>
 
 create() ::= <<
   INSERT INTO invoice_payments(<invoicePaymentFields()>)
   VALUES(:id, :type, :invoiceId, :paymentId, :paymentDate, :amount, :currency,
-         :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate);
+         :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 batchCreateFromTransaction() ::= <<
   INSERT INTO invoice_payments(<invoicePaymentFields()>)
   VALUES(:id, :type, :invoiceId, :paymentId, :paymentDate, :amount, :currency,
-        :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate);
+         :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getByPaymentId() ::= <<
   SELECT <invoicePaymentFields()>
   FROM invoice_payments
-  WHERE payment_id = :paymentId;
+  WHERE payment_id = :paymentId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 get() ::= <<
   SELECT <invoicePaymentFields()>
-  FROM invoice_payments;
+  FROM invoice_payments
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getById() ::= <<
   SELECT <invoicePaymentFields()>
   FROM invoice_payments
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getPaymentsForCookieId() ::= <<
   SELECT <invoicePaymentFields()>
   FROM invoice_payments
-  WHERE payment_cookie_id = :paymentCookieId;
+  WHERE payment_cookie_id = :paymentCookieId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getPaymentsForInvoice() ::= <<
   SELECT <invoicePaymentFields()>
   FROM invoice_payments
-  WHERE invoice_id = :invoiceId;
+  WHERE invoice_id = :invoiceId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 notifyOfPayment() ::= <<
   INSERT INTO invoice_payments(<invoicePaymentFields()>)
   VALUES(:id, :type, :invoiceId, :paymentId, :paymentDate, :amount, :currency,
-        :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate);
+         :paymentCookieId, :linkedInvoicePaymentId, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getInvoicePayments() ::= <<
     SELECT <invoicePaymentFields()>
     FROM invoice_payments
-    WHERE payment_id = :paymentId;
+    WHERE payment_id = :paymentId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM invoice_payments
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordIds() ::= <<
     SELECT record_id, id
     FROM invoice_payments
-    WHERE invoice_id = :invoiceId;
+    WHERE invoice_id = :invoiceId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -87,43 +108,54 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
-    SELECT 1 FROM invoice_payments;
+    SELECT 1 FROM invoice_payments where <CHECK_TENANT()>;
 >>
 
 getRemainingAmountPaid() ::= <<
     SELECT SUM(amount)
     FROM invoice_payments
-    WHERE id = :invoicePaymentId
-    OR linked_invoice_payment_id = :invoicePaymentId;
+    WHERE (id = :invoicePaymentId OR linked_invoice_payment_id = :invoicePaymentId)
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getAccountIdFromInvoicePaymentId() ::= <<
     SELECT account_id
     FROM invoice_payments ip
     INNER JOIN invoices i ON i.id = ip.invoice_id
-    WHERE ip.id = :invoicePaymentId;
+    WHERE ip.id = :invoicePaymentId
+    <AND_CHECK_TENANT("i.")>
+    <AND_CHECK_TENANT("ip.")>
+    ;
 >>
 
 getChargeBacksByAccountId() ::= <<
     SELECT <invoicePaymentFields("ip.")>
     FROM invoice_payments ip
     INNER JOIN invoices i ON i.id = ip.invoice_id
-    WHERE ip.type = 'CHARGED_BACK' AND i.account_id = :accountId;
+    WHERE ip.type = 'CHARGED_BACK' AND i.account_id = :accountId
+    <AND_CHECK_TENANT("i.")>
+    <AND_CHECK_TENANT("ip.")>
+    ;
 >>
 
 getChargebacksByPaymentId() ::= <<
     SELECT <invoicePaymentFields()>
     FROM invoice_payments
-    WHERE type = 'CHARGED_BACK' AND linked_invoice_payment_id IN
-        (SELECT id FROM invoice_payments WHERE payment_id = :paymentId);
+    WHERE type = 'CHARGED_BACK'
+    AND linked_invoice_payment_id IN (SELECT id FROM invoice_payments WHERE payment_id = :paymentId)
+    <AND_CHECK_TENANT()>
+    ;
 >>
 ;
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index ac5ca6e..1cba076 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group InvoiceDao;
 
+CHECK_TENANT(prefix) ::= "<prefix>tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT(prefix) ::= "AND <CHECK_TENANT(prefix)>"
+
 invoiceFields(prefix) ::= <<
     <prefix>id,
     <prefix>account_id,
@@ -8,12 +11,15 @@ invoiceFields(prefix) ::= <<
     <prefix>currency,
     <prefix>migrated,
     <prefix>created_by,
-    <prefix>created_date
+    <prefix>created_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 get() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
+  WHERE <CHECK_TENANT()>
   ORDER BY target_date ASC;
 >>
 
@@ -21,6 +27,7 @@ getInvoicesByAccount() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
   WHERE account_id = :accountId AND migrated = '0'
+  <AND_CHECK_TENANT()>
   ORDER BY target_date ASC;
 >>
 
@@ -28,6 +35,7 @@ getAllInvoicesByAccount() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
   WHERE account_id = :accountId
+  <AND_CHECK_TENANT()>
   ORDER BY target_date ASC;
 >>
 
@@ -35,6 +43,7 @@ getInvoicesByAccountAfterDate() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
   WHERE account_id = :accountId AND target_date >= :fromDate AND migrated = '0'
+  <AND_CHECK_TENANT()>
   ORDER BY target_date ASC;
 >>
 
@@ -42,24 +51,31 @@ getInvoicesBySubscription() ::= <<
   SELECT i.record_id as invoice_number, <invoiceFields("i.")>
   FROM invoices i
   JOIN invoice_items ii ON i.id = ii.invoice_id
-  WHERE ii.subscription_id = :subscriptionId AND i.migrated = '0';
+  WHERE ii.subscription_id = :subscriptionId AND i.migrated = '0'
+  <AND_CHECK_TENANT("i.")>
+  <AND_CHECK_TENANT("ii.")>
+  ;
 >>
 
 getById() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getByRecordId() ::= <<
   SELECT record_id as invoice_number, <invoiceFields()>
   FROM invoices
-  WHERE record_id = :recordId;
+  WHERE record_id = :recordId
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 create() ::= <<
   INSERT INTO invoices(<invoiceFields()>)
-  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated, :userName, :createdDate);
+  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getInvoiceIdByPaymentId() ::= <<
@@ -67,13 +83,17 @@ getInvoiceIdByPaymentId() ::= <<
     FROM invoices i, invoice_payments ip
    WHERE ip.invoice_id = i.id
      AND ip.payment_id = :paymentId
+   <AND_CHECK_TENANT("i.")>
+   <AND_CHECK_TENANT("ip.")>
 >>
 
 
 getRecordId() ::= <<
     SELECT record_id
     FROM invoices
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -84,16 +104,20 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
   SELECT 1
-  FROM invoices;
+  FROM invoices
+  WHERE <CHECK_TENANT()>
+  ;
 >>
 ;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
index 32f52e4..7731995 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
@@ -46,8 +46,7 @@ import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
 import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TestCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.tag.api.DefaultTagUserApi;
@@ -72,7 +71,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
     private InvoiceSqlDao invoiceSqlDao;
     private InvoiceItemSqlDao invoiceItemSqlDao;
     private InvoicePaymentApi invoicePaymentApi;
-    private CallContext context;
+    private InternalCallContextFactory internalCallContextFactory;
 
     @BeforeSuite(groups = "slow")
     public void setup() throws IOException {
@@ -80,19 +79,18 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
         final IDBI dbi = helper.getDBI();
 
         invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
-        invoiceSqlDao.test();
+        invoiceSqlDao.test(internalCallContext);
 
         invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
-        invoiceItemSqlDao.test();
+        invoiceItemSqlDao.test(internalCallContext);
 
         final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
         final TagDefinitionDao tagDefinitionDao = new MockTagDefinitionDao();
         final TagDao tagDao = new MockTagDao();
-        final TagUserApi tagUserApi = new DefaultTagUserApi(tagDefinitionDao, tagDao);
+        internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
+        final TagUserApi tagUserApi = new DefaultTagUserApi(internalCallContextFactory, tagDefinitionDao, tagDao);
         final InvoiceDao invoiceDao = new AuditedInvoiceDao(dbi, nextBillingDatePoster, tagUserApi, clock, Mockito.mock(Bus.class));
-        invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao);
-
-        context = new TestCallContext("Invoice payment tests");
+        invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
     }
 
     @Test(groups = "slow")
@@ -119,7 +117,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
     public void testFullRefundWithBothInvoiceItemAdjustments() throws Exception {
         // Create an invoice with two items (30 \u20ac and 10 \u20ac)
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock,
-                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, context);
+                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, callContext, internalCallContextFactory);
 
         // Fully adjust both items
         final Map<UUID, BigDecimal> adjustments = new HashMap<UUID, BigDecimal>();
@@ -133,7 +131,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
     public void testPartialRefundWithSingleInvoiceItemAdjustment() throws Exception {
         // Create an invoice with two items (30 \u20ac and 10 \u20ac)
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock,
-                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, context);
+                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, callContext, internalCallContextFactory);
 
         // Fully adjust both items
         final Map<UUID, BigDecimal> adjustments = new HashMap<UUID, BigDecimal>();
@@ -146,7 +144,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
     public void testPartialRefundWithTwoInvoiceItemAdjustment() throws Exception {
         // Create an invoice with two items (30 \u20ac and 10 \u20ac)
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock,
-                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, context);
+                                                        ImmutableList.<BigDecimal>of(THIRTY, BigDecimal.TEN), CURRENCY, callContext, internalCallContextFactory);
         // Adjust partially both items: the invoice posted was 40 \u20ac, but we should really just have charged you 2 \u20ac
         final ImmutableMap<UUID, BigDecimal> adjustments = ImmutableMap.<UUID, BigDecimal>of(invoice.getInvoiceItems().get(0).getId(), new BigDecimal("29"),
                                                                                              invoice.getInvoiceItems().get(1).getId(), new BigDecimal("9"));
@@ -155,21 +153,21 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
 
     private void verifyRefund(final BigDecimal invoiceAmount, final BigDecimal refundAmount, final BigDecimal finalInvoiceAmount,
                               final boolean adjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts) throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, invoiceAmount, CURRENCY, context);
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, invoiceAmount, CURRENCY, callContext, internalCallContextFactory);
         verifyRefund(invoice, invoiceAmount, refundAmount, finalInvoiceAmount, adjusted, invoiceItemIdsWithAmounts);
     }
 
     private void verifyRefund(final Invoice invoice, final BigDecimal invoiceAmount, final BigDecimal refundAmount, final BigDecimal finalInvoiceAmount,
                               final boolean adjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts) throws InvoiceApiException {
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), invoiceAmount, CURRENCY, context);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), invoiceAmount, CURRENCY, callContext);
 
         // Verify the initial invoice balance
-        final BigDecimal initialInvoiceBalance = invoicePaymentApi.getInvoice(invoice.getId()).getBalance();
+        final BigDecimal initialInvoiceBalance = invoicePaymentApi.getInvoice(invoice.getId(), callContext).getBalance();
         Assert.assertEquals(initialInvoiceBalance.compareTo(BigDecimal.ZERO), 0);
 
         // Create a full refund with no adjustment
         final InvoicePayment refund = invoicePaymentApi.createRefund(payment.getPaymentId(), refundAmount, adjusted, invoiceItemIdsWithAmounts,
-                                                                     UUID.randomUUID(), context);
+                                                                     UUID.randomUUID(), callContext);
         Assert.assertEquals(refund.getAmount().compareTo(refundAmount.negate()), 0);
         Assert.assertEquals(refund.getCurrency(), CURRENCY);
         Assert.assertEquals(refund.getInvoiceId(), invoice.getId());
@@ -177,7 +175,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
         Assert.assertEquals(refund.getType(), InvoicePaymentType.REFUND);
 
         // Verify the current invoice balance
-        final BigDecimal newInvoiceBalance = invoicePaymentApi.getInvoice(invoice.getId()).getBalance().setScale(2, RoundingMode.HALF_UP);
+        final BigDecimal newInvoiceBalance = invoicePaymentApi.getInvoice(invoice.getId(), callContext).getBalance().setScale(2, RoundingMode.HALF_UP);
         Assert.assertEquals(newInvoiceBalance.compareTo(finalInvoiceAmount.setScale(2, RoundingMode.HALF_UP)), 0);
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/InvoiceApiTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/InvoiceApiTestBase.java
index 4d243c1..e2c7fe4 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/InvoiceApiTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/InvoiceApiTestBase.java
@@ -55,10 +55,7 @@ import com.ning.billing.junction.api.BillingEventSet;
 import com.ning.billing.mock.api.MockBillCycleDay;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
@@ -99,6 +96,9 @@ public abstract class InvoiceApiTestBase extends InvoicingTestBase {
     @Inject
     protected Clock clock;
 
+    @Inject
+    protected InternalCallContextFactory internalCallContextFactory;
+
     @BeforeSuite(groups = "slow")
     public void setup() throws Exception {
         busService.getBus().start();
@@ -127,23 +127,23 @@ public abstract class InvoiceApiTestBase extends InvoicingTestBase {
                                           fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
                                           BillingModeType.IN_ADVANCE, "", 1L, SubscriptionTransitionType.CREATE));
 
-        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId())).thenReturn(events);
+        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext)).thenReturn(events);
 
         final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
         final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, billingApi,
-                                                                   invoiceDao, invoiceNotifier, locker, busService.getBus(), clock);
+                                                                   invoiceDao, invoiceNotifier, locker, busService.getBus(),
+                                                                   clock, internalCallContextFactory);
 
-        final CallContext context = new DefaultCallContextFactory(clock).createCallContext("Unit test", CallOrigin.TEST, UserType.TEST);
-        Invoice invoice = dispatcher.processAccount(account.getId(), targetDate, true, context);
+        Invoice invoice = dispatcher.processAccount(account.getId(), targetDate, true, callContext);
         Assert.assertNotNull(invoice);
 
-        List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId());
+        List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId(), internalCallContext);
         Assert.assertEquals(invoices.size(), 0);
 
-        invoice = dispatcher.processAccount(account.getId(), targetDate, false, context);
+        invoice = dispatcher.processAccount(account.getId(), targetDate, false, callContext);
         Assert.assertNotNull(invoice);
 
-        invoices = invoiceDao.getInvoicesByAccount(account.getId());
+        invoices = invoiceDao.getInvoicesByAccount(account.getId(), internalCallContext);
         Assert.assertEquals(invoices.size(), 1);
 
         return invoice.getId();
@@ -152,7 +152,7 @@ public abstract class InvoiceApiTestBase extends InvoicingTestBase {
     protected Account createAccount() throws AccountApiException {
         final UUID accountId = UUID.randomUUID();
         final Account account = Mockito.mock(Account.class);
-        Mockito.when(accountUserApi.getAccountById(accountId)).thenReturn(account);
+        Mockito.when(accountUserApi.getAccountById(accountId, callContext)).thenReturn(account);
         Mockito.when(account.getCurrency()).thenReturn(accountCurrency);
         Mockito.when(account.getId()).thenReturn(accountId);
         Mockito.when(account.isNotifiedForInvoices()).thenReturn(true);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index bb65134..ab8afe5 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -60,11 +60,12 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
     }
 
     private UUID createAndCheckMigrationInvoice(final UUID accountId) throws InvoiceApiException {
-        final UUID migrationInvoiceId = migrationApi.createMigrationInvoice(accountId, date_migrated, MIGRATION_INVOICE_AMOUNT, MIGRATION_INVOICE_CURRENCY);
+        final UUID migrationInvoiceId = migrationApi.createMigrationInvoice(accountId, date_migrated, MIGRATION_INVOICE_AMOUNT,
+                                                                            MIGRATION_INVOICE_CURRENCY, callContext);
         Assert.assertNotNull(migrationInvoiceId);
         //Double check it was created and values are correct
 
-        final Invoice invoice = invoiceDao.getById(migrationInvoiceId);
+        final Invoice invoice = invoiceDao.getById(migrationInvoiceId, internalCallContext);
         Assert.assertNotNull(invoice);
 
         Assert.assertEquals(invoice.getAccountId(), accountId);
@@ -81,22 +82,22 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
 
     @Test(groups = "slow")
     public void testUserApiAccess() {
-        final List<Invoice> byAccount = invoiceUserApi.getInvoicesByAccount(accountId);
+        final List<Invoice> byAccount = invoiceUserApi.getInvoicesByAccount(accountId, callContext);
         Assert.assertEquals(byAccount.size(), 1);
         Assert.assertEquals(byAccount.get(0).getId(), regularInvoiceId);
 
-        final List<Invoice> byAccountAndDate = invoiceUserApi.getInvoicesByAccount(accountId, date_migrated.minusDays(1));
+        final List<Invoice> byAccountAndDate = invoiceUserApi.getInvoicesByAccount(accountId, date_migrated.minusDays(1), callContext);
         Assert.assertEquals(byAccountAndDate.size(), 1);
         Assert.assertEquals(byAccountAndDate.get(0).getId(), regularInvoiceId);
 
-        final Collection<Invoice> unpaid = invoiceUserApi.getUnpaidInvoicesByAccountId(accountId, new LocalDate(date_regular.plusDays(1)));
+        final Collection<Invoice> unpaid = invoiceUserApi.getUnpaidInvoicesByAccountId(accountId, new LocalDate(date_regular.plusDays(1)), callContext);
         Assert.assertEquals(unpaid.size(), 2);
     }
 
     // Check migration invoice IS returned for payment api calls
     @Test(groups = "slow")
     public void testPaymentApi() {
-        final List<Invoice> allByAccount = invoicePaymentApi.getAllInvoicesByAccount(accountId);
+        final List<Invoice> allByAccount = invoicePaymentApi.getAllInvoicesByAccount(accountId, callContext);
         Assert.assertEquals(allByAccount.size(), 2);
         Assert.assertTrue(checkContains(allByAccount, regularInvoiceId));
         Assert.assertTrue(checkContains(allByAccount, migrationInvoiceId));
@@ -105,11 +106,11 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
     // ACCOUNT balance should reflect total of migration and non-migration invoices
     @Test(groups = "slow")
     public void testBalance() throws InvoiceApiException{
-        final Invoice migrationInvoice = invoiceDao.getById(migrationInvoiceId);
-        final Invoice regularInvoice = invoiceDao.getById(regularInvoiceId);
+        final Invoice migrationInvoice = invoiceDao.getById(migrationInvoiceId, internalCallContext);
+        final Invoice regularInvoice = invoiceDao.getById(regularInvoiceId, internalCallContext);
         final BigDecimal balanceOfAllInvoices = migrationInvoice.getBalance().add(regularInvoice.getBalance());
 
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
         log.info("ACCOUNT balance: " + accountBalance + " should equal the Balance Of All Invoices: " + balanceOfAllInvoices);
         Assert.assertEquals(accountBalance.compareTo(balanceOfAllInvoices), 0);
     }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index 18a4ce9..66ba437 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -31,6 +31,7 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class MockInvoicePaymentApi implements InvoicePaymentApi {
     private final CopyOnWriteArrayList<Invoice> invoices = new CopyOnWriteArrayList<Invoice>();
@@ -51,7 +52,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public List<Invoice> getAllInvoicesByAccount(final UUID accountId) {
+    public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final TenantContext context) {
         final ArrayList<Invoice> result = new ArrayList<Invoice>();
 
         for (final Invoice invoice : invoices) {
@@ -63,7 +64,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public Invoice getInvoice(final UUID invoiceId) {
+    public Invoice getInvoice(final UUID invoiceId, final TenantContext context) {
         for (final Invoice invoice : invoices) {
             if (invoiceId.equals(invoice.getId())) {
                 return invoice;
@@ -73,18 +74,18 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public Invoice getInvoiceForPaymentId(final UUID paymentId) {
+    public Invoice getInvoiceForPaymentId(final UUID paymentId, final TenantContext context) {
         for (final InvoicePayment invoicePayment : invoicePayments) {
             if (invoicePayment.getPaymentId().equals(paymentId)) {
-                return getInvoice(invoicePayment.getInvoiceId());
+                return getInvoice(invoicePayment.getInvoiceId(), context);
             }
         }
         return null;
     }
 
     @Override
-    public List<InvoicePayment> getInvoicePayments(final UUID paymentId) {
-        List<InvoicePayment> result = new LinkedList<InvoicePayment>();
+    public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
+        final List<InvoicePayment> result = new LinkedList<InvoicePayment>();
         for (final InvoicePayment invoicePayment : invoicePayments) {
             if (paymentId.equals(invoicePayment.getPaymentId())) {
                 result.add(invoicePayment);
@@ -94,7 +95,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId) {
+    public InvoicePayment getInvoicePaymentForAttempt(final UUID paymentId, final TenantContext context) {
         for (final InvoicePayment invoicePayment : invoicePayments) {
             if (paymentId.equals(invoicePayment.getPaymentId()) && invoicePayment.getType() == InvoicePaymentType.ATTEMPT) {
                 return invoicePayment;
@@ -145,7 +146,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId) {
+    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final TenantContext context) {
         BigDecimal amount = BigDecimal.ZERO;
         for (final InvoicePayment payment : invoicePayments) {
             if (payment.getId().equals(invoicePaymentId)) {
@@ -161,22 +162,22 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId) {
+    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public UUID getAccountIdFromInvoicePaymentId(final UUID uuid) throws InvoiceApiException {
+    public UUID getAccountIdFromInvoicePaymentId(final UUID uuid, final TenantContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId) {
+    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoicePayment getChargebackById(final UUID chargebackId) {
+    public InvoicePayment getChargebackById(final UUID chargebackId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index c245e29..7fa510f 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -21,6 +21,7 @@ import java.util.UUID;
 
 import javax.annotation.Nullable;
 
+import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -35,6 +36,7 @@ import com.ning.billing.invoice.model.InvoicingConfiguration;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.callcontext.UserType;
 
 public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
@@ -42,19 +44,21 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
     private UUID accountId;
     private UUID invoiceId;
     private CallContext context;
+    private TenantContext tenantContext;
 
     @BeforeMethod(groups = "slow")
     public void setupMethod() throws Exception {
         final Account account = createAccount();
         accountId = account.getId();
         invoiceId = generateRegularInvoice(account, clock.getUTCNow());
-        context = new DefaultCallContextFactory(clock).createCallContext("Unit test", CallOrigin.TEST, UserType.TEST);
+        context = new DefaultCallContextFactory(clock).createCallContext(callContext.getTenantId(), "Unit test", CallOrigin.TEST, UserType.TEST);
+        tenantContext = Mockito.mock(TenantContext.class);
     }
 
     @Test(groups = "slow")
     public void testPostExternalChargeOnNewInvoice() throws Exception {
         // Initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
 
         // Post an external charge
         final BigDecimal externalChargeAmount = BigDecimal.TEN;
@@ -66,7 +70,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
     @Test(groups = "slow")
     public void testPostExternalChargeForBundleOnNewInvoice() throws Exception {
         // Initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
 
         // Post an external charge
         final BigDecimal externalChargeAmount = BigDecimal.TEN;
@@ -89,22 +93,22 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertNull(externalChargeInvoiceItem.getLinkedItemId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(externalChargeInvoiceItem.getInvoiceId()).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(externalChargeInvoiceItem.getInvoiceId(), tenantContext).getBalance();
         Assert.assertEquals(adjustedInvoiceBalance.compareTo(externalChargeAmount), 0);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, initialAccountBalance.add(externalChargeAmount));
     }
 
     @Test(groups = "slow")
     public void testPostExternalChargeOnExistingInvoice() throws Exception {
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Post an external charge
@@ -118,11 +122,11 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
     @Test(groups = "slow")
     public void testPostExternalChargeForBundleOnExistingInvoice() throws Exception {
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Post an external charge
@@ -145,22 +149,22 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertNull(externalChargeInvoiceItem.getLinkedItemId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(adjustedInvoiceBalance.compareTo(initialInvoiceBalance.add(externalChargeAmount)), 0);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
     }
 
     @Test(groups = "slow")
     public void testAdjustFullInvoice() throws Exception {
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Adjust the invoice for the full amount
@@ -174,22 +178,22 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertNull(creditInvoiceItem.getLinkedItemId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(adjustedInvoiceBalance.compareTo(BigDecimal.ZERO), 0);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
     }
 
     @Test(groups = "slow")
     public void testAdjustPartialInvoice() throws Exception {
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Adjust the invoice for a fraction of the balance
@@ -204,12 +208,12 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertNull(creditInvoiceItem.getLinkedItemId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         // Note! The invoice code will round (see InvoiceItemList)
         verifyAdjustedInvoiceBalance(invoiceBalance, creditAmount, adjustedInvoiceBalance);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
     }
 
@@ -225,16 +229,16 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
 
     @Test(groups = "slow")
     public void testAdjustFullInvoiceItem() throws Exception {
-        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId).getInvoiceItems().get(0);
+        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId, tenantContext).getInvoiceItems().get(0);
         // Verify we picked a non zero item
         Assert.assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Adjust the invoice for the full amount
@@ -248,27 +252,27 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertEquals(adjInvoiceItem.getLinkedItemId(), invoiceItem.getId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         // Note! The invoice code will round (see InvoiceItemList)
         verifyAdjustedInvoiceBalance(invoiceBalance, invoiceItem.getAmount(), adjustedInvoiceBalance);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
     }
 
     @Test(groups = "slow")
     public void testAdjustPartialInvoiceItem() throws Exception {
-        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId).getInvoiceItems().get(0);
+        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId, tenantContext).getInvoiceItems().get(0);
         // Verify we picked a non zero item
         Assert.assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial invoice balance
-        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
 
         // Verify the initial account balance
-        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(accountBalance, invoiceBalance);
 
         // Adjust the invoice for a fraction of the balance
@@ -284,18 +288,18 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
         Assert.assertEquals(adjInvoiceItem.getLinkedItemId(), invoiceItem.getId());
 
         // Verify the adjusted invoice balance
-        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId).getBalance();
+        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, tenantContext).getBalance();
         // Note! The invoice code will round (see InvoiceItemList)
         verifyAdjustedInvoiceBalance(invoiceBalance, adjAmount, adjustedInvoiceBalance);
 
         // Verify the adjusted account balance
-        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId);
+        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, tenantContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
     }
 
     @Test(groups = "slow")
     public void testCantAdjustInvoiceItemWithNegativeAmount() throws Exception {
-        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId).getInvoiceItems().get(0);
+        final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId, tenantContext).getInvoiceItems().get(0);
 
         try {
             invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(),
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 902591b..60adf50 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -35,8 +35,7 @@ import com.ning.billing.invoice.tests.InvoicingTestBase;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.InMemoryBus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TestCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.tag.api.DefaultTagUserApi;
@@ -57,7 +56,6 @@ public class InvoiceDaoTestBase extends InvoicingTestBase {
     protected InvoiceItemSqlDao invoiceItemSqlDao;
     protected InvoicePaymentSqlDao invoicePaymentDao;
     protected Clock clock;
-    protected CallContext context;
     protected InvoiceGenerator generator;
     protected Bus bus;
 
@@ -109,14 +107,13 @@ public class InvoiceDaoTestBase extends InvoicingTestBase {
         final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
         final TagDefinitionDao tagDefinitionDao = new MockTagDefinitionDao();
         final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
-        final TagUserApi tagUserApi = new DefaultTagUserApi(tagDefinitionDao, tagDao);
+        final TagUserApi tagUserApi = new DefaultTagUserApi(new InternalCallContextFactory(dbi, clock), tagDefinitionDao, tagDao);
         invoiceDao = new AuditedInvoiceDao(dbi, nextBillingDatePoster, tagUserApi, clock, bus);
-        invoiceDao.test();
+        invoiceDao.test(internalCallContext);
 
         invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
         invoicePaymentDao = dbi.onDemand(InvoicePaymentSqlDao.class);
 
-        context = new TestCallContext("Invoice Dao Tests");
         generator = new DefaultInvoiceGenerator(clock, invoiceConfig);
 
         assertTrue(true);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index b45869d..4065ab6 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -35,7 +35,8 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.user.DefaultInvoiceCreationEvent;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.inject.Inject;
 
@@ -51,7 +52,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void create(final Invoice invoice, final int billCycleDay, final boolean isRealInvoice, final CallContext context) {
+    public void create(final Invoice invoice, final int billCycleDay, final boolean isRealInvoice, final InternalCallContext context) {
         synchronized (monitor) {
             invoices.put(invoice.getId(), invoice);
         }
@@ -65,14 +66,14 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public Invoice getById(final UUID id) {
+    public Invoice getById(final UUID id, final InternalTenantContext context) {
         synchronized (monitor) {
             return invoices.get(id);
         }
     }
 
     @Override
-    public Invoice getByNumber(final Integer number) {
+    public Invoice getByNumber(final Integer number, final InternalTenantContext context) {
         synchronized (monitor) {
             for (final Invoice invoice : invoices.values()) {
                 if (invoice.getInvoiceNumber().equals(number)) {
@@ -85,14 +86,14 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> get() {
+    public List<Invoice> get(final InternalTenantContext context) {
         synchronized (monitor) {
             return new ArrayList<Invoice>(invoices.values());
         }
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId) {
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final InternalTenantContext context) {
         final List<Invoice> result = new ArrayList<Invoice>();
 
         synchronized (monitor) {
@@ -106,11 +107,11 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate) {
+    public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate, final InternalTenantContext context) {
         final List<Invoice> invoicesForAccount = new ArrayList<Invoice>();
 
         synchronized (monitor) {
-            for (final Invoice invoice : get()) {
+            for (final Invoice invoice : get(context)) {
                 if (accountId.equals(invoice.getAccountId()) && !invoice.getTargetDate().isBefore(fromDate) && !invoice.isMigrationInvoice()) {
                     invoicesForAccount.add(invoice);
                 }
@@ -121,7 +122,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getInvoicesBySubscription(final UUID subscriptionId) {
+    public List<Invoice> getInvoicesBySubscription(final UUID subscriptionId, final InternalTenantContext context) {
         final List<Invoice> result = new ArrayList<Invoice>();
 
         synchronized (monitor) {
@@ -138,11 +139,11 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void test() {
+    public void test(final InternalTenantContext context) {
     }
 
     @Override
-    public UUID getInvoiceIdByPaymentId(final UUID paymentId) {
+    public UUID getInvoiceIdByPaymentId(final UUID paymentId, final InternalTenantContext context) {
         synchronized (monitor) {
             for (final Invoice invoice : invoices.values()) {
                 for (final InvoicePayment payment : invoice.getPayments()) {
@@ -156,8 +157,8 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<InvoicePayment> getInvoicePayments(final UUID paymentId) {
-        List<InvoicePayment> result = new LinkedList<InvoicePayment>();
+    public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final InternalTenantContext context) {
+        final List<InvoicePayment> result = new LinkedList<InvoicePayment>();
         synchronized (monitor) {
             for (final Invoice invoice : invoices.values()) {
                 for (final InvoicePayment payment : invoice.getPayments()) {
@@ -171,7 +172,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) {
+    public void notifyOfPayment(final InvoicePayment invoicePayment, final InternalCallContext context) {
         synchronized (monitor) {
             final Invoice invoice = invoices.get(invoicePayment.getInvoiceId());
             if (invoice != null) {
@@ -181,10 +182,10 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public BigDecimal getAccountBalance(final UUID accountId) {
+    public BigDecimal getAccountBalance(final UUID accountId, final InternalTenantContext context) {
         BigDecimal balance = BigDecimal.ZERO;
 
-        for (final Invoice invoice : get()) {
+        for (final Invoice invoice : get(context)) {
             if (accountId.equals(invoice.getAccountId())) {
                 balance = balance.add(invoice.getBalance());
             }
@@ -194,10 +195,10 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate) {
+    public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate, final InternalTenantContext context) {
         final List<Invoice> unpaidInvoices = new ArrayList<Invoice>();
 
-        for (final Invoice invoice : get()) {
+        for (final Invoice invoice : get(context)) {
             if (accountId.equals(invoice.getAccountId()) && (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) && !invoice.isMigrationInvoice()) {
                 unpaidInvoices.add(invoice);
             }
@@ -207,7 +208,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<Invoice> getAllInvoicesByAccount(final UUID accountId) {
+    public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final InternalTenantContext context) {
         final List<Invoice> result = new ArrayList<Invoice>();
 
         synchronized (monitor) {
@@ -221,88 +222,90 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void setWrittenOff(final UUID objectId, final CallContext context) {
+    public void setWrittenOff(final UUID objectId, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void removeWrittenOff(final UUID objectId, final CallContext context) {
+    public void removeWrittenOff(final UUID objectId, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final InternalCallContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId) {
+    public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId) throws InvoiceApiException {
+    public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId, final InternalTenantContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId) {
+    public List<InvoicePayment> getChargebacksByAccountId(final UUID accountId, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId) {
+    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoicePayment getChargebackById(final UUID chargebackId) throws InvoiceApiException {
+    public InvoicePayment getChargebackById(final UUID chargebackId, final InternalTenantContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoiceItem getExternalChargeById(final UUID externalChargeId) throws InvoiceApiException {
+    public InvoiceItem getExternalChargeById(final UUID externalChargeId, final InternalTenantContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
     public InvoiceItem insertExternalCharge(final UUID accountId, @Nullable final UUID invoiceId, @Nullable final UUID bundleId,
                                             @Nullable final String description, final BigDecimal amount, final LocalDate effectiveDate,
-                                            final Currency currency, final CallContext context) {
+                                            final Currency currency, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException {
+    public InvoiceItem getCreditById(final UUID creditId, final InternalTenantContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public InvoiceItem insertCredit(final UUID accountId, final UUID invoiceId, final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context) {
+    public InvoiceItem insertCredit(final UUID accountId, final UUID invoiceId, final BigDecimal amount, final LocalDate effectiveDate,
+                                    final Currency currency, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
     public InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId,
-                                                   final LocalDate effectiveDate, @Nullable final BigDecimal amount, @Nullable final Currency currency, final CallContext context) {
+                                                   final LocalDate effectiveDate, @Nullable final BigDecimal amount,
+                                                   @Nullable final Currency currency, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public BigDecimal getAccountCBA(UUID accountId) {
+    public BigDecimal getAccountCBA(final UUID accountId, final InternalTenantContext context) {
         return null;
     }
 
     @Override
     public InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted,
                                        final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final UUID paymentCookieId,
-                                       final CallContext context)
+                                       final InternalCallContext context)
             throws InvoiceApiException {
         return null;
     }
 
     @Override
-    public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final CallContext context) throws InvoiceApiException {
+    public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final InternalCallContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
index 0427972..36e1168 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
@@ -29,7 +29,6 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.invoice.InvoiceTestSuite;
 import com.ning.billing.invoice.api.Invoice;
@@ -38,8 +37,10 @@ import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
@@ -49,6 +50,8 @@ import com.ning.billing.util.tag.dao.MockTagDefinitionDao;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
+import com.google.common.collect.ImmutableMap;
+
 public class TestDefaultInvoiceDao extends InvoiceTestSuite {
 
     private InvoiceSqlDao invoiceSqlDao;
@@ -60,7 +63,7 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
         final IDBI idbi = Mockito.mock(IDBI.class);
         invoiceSqlDao = Mockito.mock(InvoiceSqlDao.class);
         Mockito.when(idbi.onDemand(InvoiceSqlDao.class)).thenReturn(invoiceSqlDao);
-        Mockito.when(invoiceSqlDao.getById(Mockito.anyString())).thenReturn(Mockito.mock(Invoice.class));
+        Mockito.when(invoiceSqlDao.getById(Mockito.anyString(), Mockito.<InternalTenantContext>any())).thenReturn(Mockito.mock(Invoice.class));
         Mockito.when(invoiceSqlDao.inTransaction(Mockito.<Transaction<Void, InvoiceSqlDao>>any())).thenAnswer(new Answer() {
             @Override
             public Object answer(final InvocationOnMock invocation) {
@@ -77,7 +80,7 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
         final NextBillingDatePoster poster = Mockito.mock(NextBillingDatePoster.class);
         final TagDefinitionDao tagDefinitionDao = new MockTagDefinitionDao();
         final TagDao tagDao = new MockTagDao();
-        tagUserApi = new DefaultTagUserApi(tagDefinitionDao, tagDao);
+        tagUserApi = new DefaultTagUserApi(new InternalCallContextFactory(Mockito.mock(IDBI.class), new ClockMock()), tagDefinitionDao, tagDao);
         dao = new AuditedInvoiceDao(idbi, poster, tagUserApi, Mockito.mock(Clock.class), Mockito.mock(Bus.class));
     }
 
@@ -122,11 +125,11 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
     public void testFindByNumber() throws Exception {
         final Integer number = Integer.MAX_VALUE;
         final Invoice invoice = Mockito.mock(Invoice.class);
-        Mockito.when(invoiceSqlDao.getByRecordId(number.longValue())).thenReturn(invoice);
+        Mockito.when(invoiceSqlDao.getByRecordId(number.longValue(), internalCallContext)).thenReturn(invoice);
 
-        Assert.assertEquals(dao.getByNumber(number), invoice);
+        Assert.assertEquals(dao.getByNumber(number, internalCallContext), invoice);
         try {
-            dao.getByNumber(Integer.MIN_VALUE);
+            dao.getByNumber(Integer.MIN_VALUE, internalCallContext);
             Assert.fail();
         } catch (InvoiceApiException e) {
         }
@@ -136,12 +139,12 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
     public void testSetWrittenOff() throws Exception {
         final UUID invoiceId = UUID.randomUUID();
 
-        final Map<String, Tag> beforeTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE);
+        final Map<String, Tag> beforeTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
         Assert.assertEquals(beforeTags.keySet().size(), 0);
 
-        dao.setWrittenOff(invoiceId, Mockito.mock(CallContext.class));
+        dao.setWrittenOff(invoiceId, internalCallContext);
 
-        final Map<String, Tag> afterTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE);
+        final Map<String, Tag> afterTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
         Assert.assertEquals(afterTags.keySet().size(), 1);
         final UUID tagDefinitionId = ControlTagType.WRITTEN_OFF.getId();
         Assert.assertEquals(afterTags.values().iterator().next().getTagDefinitionId(), tagDefinitionId);
@@ -151,13 +154,13 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
     public void testRemoveWrittenOff() throws Exception {
         final UUID invoiceId = UUID.randomUUID();
 
-        dao.setWrittenOff(invoiceId, Mockito.mock(CallContext.class));
+        dao.setWrittenOff(invoiceId, internalCallContext);
 
-        final Map<String, Tag> beforeTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE);
+        final Map<String, Tag> beforeTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
         Assert.assertEquals(beforeTags.keySet().size(), 1);
-        dao.removeWrittenOff(invoiceId, Mockito.mock(CallContext.class));
+        dao.removeWrittenOff(invoiceId, internalCallContext);
 
-        final Map<String, Tag> afterTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE);
+        final Map<String, Tag> afterTags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
         Assert.assertEquals(afterTags.keySet().size(), 0);
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index 1374148..552c8dc 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.invoice.dao;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,7 +32,6 @@ import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.DefaultPrice;
 import com.ning.billing.catalog.MockInternationalPrice;
@@ -71,11 +65,19 @@ import com.ning.billing.junction.api.BillingEventSet;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 import com.ning.billing.util.tag.dao.TagDao;
 
+import com.google.common.collect.ImmutableMap;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestInvoiceDao extends InvoiceDaoTestBase {
 
     @Test(groups = "slow")
@@ -84,9 +86,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
         final LocalDate invoiceDate = invoice.getInvoiceDate();
 
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
-        final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+        final List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId, internalCallContext);
         assertNotNull(invoices);
         assertEquals(invoices.size(), 1);
         final Invoice thisInvoice = invoices.get(0);
@@ -107,12 +109,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final LocalDate startDate = new LocalDate(2010, 1, 1);
         final LocalDate endDate = new LocalDate(2010, 4, 1);
         final InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test plan", "test phase", startDate, endDate,
-                new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD);
+                                                                 new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD);
 
         invoice.addInvoiceItem(invoiceItem);
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
-        final Invoice savedInvoice = invoiceDao.getById(invoiceId);
+        final Invoice savedInvoice = invoiceDao.getById(invoiceId, internalCallContext);
         assertNotNull(savedInvoice);
         assertEquals(savedInvoice.getBalance().compareTo(new BigDecimal("21.00")), 0);
         assertEquals(savedInvoice.getPaidAmount(), BigDecimal.ZERO);
@@ -121,9 +123,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal paymentAmount = new BigDecimal("11.00");
         final UUID paymentId = UUID.randomUUID();
 
-        invoiceDao.notifyOfPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD), context);
+        invoiceDao.notifyOfPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD), internalCallContext);
 
-        final Invoice retrievedInvoice = invoiceDao.getById(invoiceId);
+        final Invoice retrievedInvoice = invoiceDao.getById(invoiceId, internalCallContext);
         assertNotNull(retrievedInvoice);
         assertEquals(retrievedInvoice.getInvoiceItems().size(), 1);
         assertEquals(retrievedInvoice.getChargedAmount().compareTo(new BigDecimal("21.00")), 0);
@@ -132,9 +134,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testRetrievalForNonExistentInvoiceId()  throws InvoiceApiException {
+    public void testRetrievalForNonExistentInvoiceId() throws InvoiceApiException {
         try {
-            invoiceDao.getById(UUID.randomUUID());
+            invoiceDao.getById(UUID.randomUUID(), internalCallContext);
             Assert.fail();
         } catch (InvoiceApiException e) {
             if (e.getCode() != ErrorCode.INVOICE_NOT_FOUND.getCode()) {
@@ -144,7 +146,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testGetInvoicesBySubscriptionForRecurringItems() {
+    public void testGetInvoicesBySubscriptionForRecurringItems() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
@@ -161,7 +163,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Create invoice 1 (subscriptions 1-4)
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId1 = invoice1.getId();
 
@@ -169,24 +171,24 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         LocalDate endDate = startDate.plusMonths(1);
 
         final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                    rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
+                                                                    rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
 
         final RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate, endDate,
-                rate3, rate3, Currency.USD);
-        invoiceItemSqlDao.create(item3, context);
+                                                                    rate3, rate3, Currency.USD);
+        invoiceItemSqlDao.create(item3, internalCallContext);
 
         final RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate, endDate,
-                rate4, rate4, Currency.USD);
-        invoiceItemSqlDao.create(item4, context);
+                                                                    rate4, rate4, Currency.USD);
+        invoiceItemSqlDao.create(item4, internalCallContext);
 
         // Create invoice 2 (subscriptions 1-3)
         final DefaultInvoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId2 = invoice2.getId();
 
@@ -194,33 +196,33 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         endDate = startDate.plusMonths(1);
 
         final RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item5, context);
+                                                                    rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item5, internalCallContext);
 
         final RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item6, context);
+                                                                    rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item6, internalCallContext);
 
         final RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate, endDate,
-                rate3, rate3, Currency.USD);
-        invoiceItemSqlDao.create(item7, context);
+                                                                    rate3, rate3, Currency.USD);
+        invoiceItemSqlDao.create(item7, internalCallContext);
 
         // Check that each subscription returns the correct number of invoices
-        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1);
+        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1, internalCallContext);
         assertEquals(items1.size(), 2);
 
-        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2);
+        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2, internalCallContext);
         assertEquals(items2.size(), 2);
 
-        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3);
+        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3, internalCallContext);
         assertEquals(items3.size(), 2);
 
-        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4);
+        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4, internalCallContext);
         assertEquals(items4.size(), 1);
     }
 
     @Test(groups = "slow")
-    public void testGetInvoicesBySubscriptionForFixedItems() {
+    public void testGetInvoicesBySubscriptionForFixedItems() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
@@ -237,7 +239,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Create invoice 1 (subscriptions 1-4)
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId1 = invoice1.getId();
 
@@ -245,24 +247,24 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         LocalDate endDate = startDate.plusMonths(1);
 
         final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate,
-                rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                      rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final FixedPriceInvoiceItem item2 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate,
-                rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
+                                                                      rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
 
         final FixedPriceInvoiceItem item3 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate,
-                rate3, Currency.USD);
-        invoiceItemSqlDao.create(item3, context);
+                                                                      rate3, Currency.USD);
+        invoiceItemSqlDao.create(item3, internalCallContext);
 
         final FixedPriceInvoiceItem item4 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate,
-                rate4, Currency.USD);
-        invoiceItemSqlDao.create(item4, context);
+                                                                      rate4, Currency.USD);
+        invoiceItemSqlDao.create(item4, internalCallContext);
 
         // create invoice 2 (subscriptions 1-3)
         final DefaultInvoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId2 = invoice2.getId();
 
@@ -270,33 +272,33 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         endDate = startDate.plusMonths(1);
 
         final FixedPriceInvoiceItem item5 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate,
-                rate1, Currency.USD);
-        invoiceItemSqlDao.create(item5, context);
+                                                                      rate1, Currency.USD);
+        invoiceItemSqlDao.create(item5, internalCallContext);
 
         final FixedPriceInvoiceItem item6 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate,
-                rate2, Currency.USD);
-        invoiceItemSqlDao.create(item6, context);
+                                                                      rate2, Currency.USD);
+        invoiceItemSqlDao.create(item6, internalCallContext);
 
         final FixedPriceInvoiceItem item7 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate,
-                rate3, Currency.USD);
-        invoiceItemSqlDao.create(item7, context);
+                                                                      rate3, Currency.USD);
+        invoiceItemSqlDao.create(item7, internalCallContext);
 
         // check that each subscription returns the correct number of invoices
-        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1);
+        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1, internalCallContext);
         assertEquals(items1.size(), 2);
 
-        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2);
+        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2, internalCallContext);
         assertEquals(items2.size(), 2);
 
-        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3);
+        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3, internalCallContext);
         assertEquals(items3.size(), 2);
 
-        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4);
+        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4, internalCallContext);
         assertEquals(items4.size(), 1);
     }
 
     @Test(groups = "slow")
-    public void testGetInvoicesBySubscriptionForRecurringAndFixedItems() {
+    public void testGetInvoicesBySubscriptionForRecurringAndFixedItems() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
@@ -313,7 +315,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Create invoice 1 (subscriptions 1-4)
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId1 = invoice1.getId();
 
@@ -321,40 +323,40 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         LocalDate endDate = startDate.plusMonths(1);
 
         final RecurringInvoiceItem recurringItem1 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem1, context);
+                                                                             rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem1, internalCallContext);
 
         final RecurringInvoiceItem recurringItem2 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem2, context);
+                                                                             rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem2, internalCallContext);
 
         final RecurringInvoiceItem recurringItem3 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate, endDate,
-                rate3, rate3, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem3, context);
+                                                                             rate3, rate3, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem3, internalCallContext);
 
         final RecurringInvoiceItem recurringItem4 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate, endDate,
-                rate4, rate4, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem4, context);
+                                                                             rate4, rate4, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem4, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem1 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate,
-                rate1, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem1, context);
+                                                                           rate1, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem1, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem2 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate,
-                rate2, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem2, context);
+                                                                           rate2, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem2, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem3 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate,
-                rate3, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem3, context);
+                                                                           rate3, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem3, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem4 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate,
-                rate4, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem4, context);
+                                                                           rate4, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem4, internalCallContext);
 
         // create invoice 2 (subscriptions 1-3)
         final DefaultInvoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId2 = invoice2.getId();
 
@@ -362,39 +364,39 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         endDate = startDate.plusMonths(1);
 
         final RecurringInvoiceItem recurringItem5 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem5, context);
+                                                                             rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem5, internalCallContext);
 
         final RecurringInvoiceItem recurringItem6 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem6, context);
+                                                                             rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem6, internalCallContext);
 
         final RecurringInvoiceItem recurringItem7 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate, endDate,
-                rate3, rate3, Currency.USD);
-        invoiceItemSqlDao.create(recurringItem7, context);
+                                                                             rate3, rate3, Currency.USD);
+        invoiceItemSqlDao.create(recurringItem7, internalCallContext);
         final FixedPriceInvoiceItem fixedItem5 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate,
-                rate1, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem5, context);
+                                                                           rate1, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem5, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem6 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate,
-                rate2, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem6, context);
+                                                                           rate2, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem6, internalCallContext);
 
         final FixedPriceInvoiceItem fixedItem7 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate,
-                rate3, Currency.USD);
-        invoiceItemSqlDao.create(fixedItem7, context);
+                                                                           rate3, Currency.USD);
+        invoiceItemSqlDao.create(fixedItem7, internalCallContext);
 
         // check that each subscription returns the correct number of invoices
-        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1);
+        final List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1, internalCallContext);
         assertEquals(items1.size(), 4);
 
-        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2);
+        final List<Invoice> items2 = invoiceDao.getInvoicesBySubscription(subscriptionId2, internalCallContext);
         assertEquals(items2.size(), 4);
 
-        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3);
+        final List<Invoice> items3 = invoiceDao.getInvoicesBySubscription(subscriptionId3, internalCallContext);
         assertEquals(items3.size(), 4);
 
-        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4);
+        final List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4, internalCallContext);
         assertEquals(items4.size(), 2);
     }
 
@@ -403,36 +405,36 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final UUID accountId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true,  context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate targetDate2 = new LocalDate(2011, 12, 6);
         final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate2, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         List<Invoice> invoices;
-        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 1, 1));
+        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 1, 1), internalCallContext);
         assertEquals(invoices.size(), 2);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 10, 6));
+        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 10, 6), internalCallContext);
         assertEquals(invoices.size(), 2);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 10, 11));
+        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 10, 11), internalCallContext);
         assertEquals(invoices.size(), 1);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 12, 6));
+        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2011, 12, 6), internalCallContext);
         assertEquals(invoices.size(), 1);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2012, 1, 1));
+        invoices = invoiceDao.getInvoicesByAccount(accountId, new LocalDate(2012, 1, 1), internalCallContext);
         assertEquals(invoices.size(), 0);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalance() {
+    public void testAccountBalance() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -441,28 +443,28 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal rate2 = new BigDecimal("42.0");
 
         final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
-                endDate, rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                    endDate, rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
+                                                                    endDate, rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
 
         final BigDecimal payment1 = new BigDecimal("48.0");
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
+        invoicePaymentDao.create(payment, internalCallContext);
 
-        final BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        final BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(rate1.add(rate2).subtract(payment1)), 0);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithCredit() {
+    public void testAccountBalanceWithCredit() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -470,23 +472,23 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal rate1 = new BigDecimal("17.0");
 
         final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
-                endDate, rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                    endDate, rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), rate1.negate(), Currency.USD);
-        invoiceItemSqlDao.create(creditItem, context);
+        invoiceItemSqlDao.create(creditItem, internalCallContext);
 
-        final BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        final BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithNoPayments() {
+    public void testAccountBalanceWithNoPayments() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -495,49 +497,49 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal rate2 = new BigDecimal("42.0");
 
         final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                    rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
+                                                                    rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
 
-        final BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        final BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(rate1.add(rate2)), 0);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithNoInvoiceItems() {
+    public void testAccountBalanceWithNoInvoiceItems() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final BigDecimal payment1 = new BigDecimal("48.0");
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
+        invoicePaymentDao.create(payment, internalCallContext);
 
-        final BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        final BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(BigDecimal.ZERO.subtract(payment1)), 0);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithRefundNoAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithRefundNoAdj() throws InvoiceApiException, EntityPersistenceException {
         testAccountBalanceWithRefundInternal(false);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithRefundAndAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithRefundAndAdj() throws InvoiceApiException, EntityPersistenceException {
         testAccountBalanceWithRefundInternal(true);
     }
 
-    private void testAccountBalanceWithRefundInternal(boolean withAdjustment) throws InvoiceApiException {
+    private void testAccountBalanceWithRefundInternal(final boolean withAdjustment) throws InvoiceApiException, EntityPersistenceException {
 
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -548,21 +550,21 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Recurring item
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
-        BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+                                                                    endDate, rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
+        BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("20.00")), 0);
 
         // Pay the whole thing
         final UUID paymentId = UUID.randomUUID();
         final BigDecimal payment1 = rate1;
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoicePaymentDao.create(payment, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
 
-        invoiceDao.createRefund(paymentId, refund1, withAdjustment, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoiceDao.createRefund(paymentId, refund1, withAdjustment, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         if (withAdjustment) {
             assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
         } else {
@@ -583,52 +585,49 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     private void testRefundWithRepairAndInvoiceItemAdjustmentInternal(final BigDecimal refundAmount) throws InvoiceApiException {
-
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
 
         final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
 
         final BigDecimal amount = new BigDecimal("20.0");
-        ;
 
         // Recurring item
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, amount, amount, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
-        BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+                                                                    endDate, amount, amount, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
+        BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("20.00")), 0);
 
         // Pay the whole thing
         final UUID paymentId = UUID.randomUUID();
         final BigDecimal payment1 = amount;
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoicePaymentDao.create(payment, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
 
-
         // Repair the item (And add CBA item that should be generated)
         final InvoiceItem repairItem = new RepairAdjInvoiceItem(invoice.getId(), accountId, startDate, endDate, amount.negate(), Currency.USD, item2.getId());
-        invoiceItemSqlDao.create(repairItem, context);
+        invoiceItemSqlDao.create(repairItem, internalCallContext);
 
         final InvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), accountId, startDate, amount, Currency.USD);
-        invoiceItemSqlDao.create(cbaItem, context);
+        invoiceItemSqlDao.create(cbaItem, internalCallContext);
 
         Map<UUID, BigDecimal> itemAdjustment = new HashMap<UUID, BigDecimal>();
         itemAdjustment.put(item2.getId(), refundAmount);
 
-        invoiceDao.createRefund(paymentId, refundAmount, true, itemAdjustment, UUID.randomUUID(), context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoiceDao.createRefund(paymentId, refundAmount, true, itemAdjustment, UUID.randomUUID(), internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
 
         final boolean partialRefund = refundAmount.compareTo(amount) < 0;
-        final BigDecimal cba = invoiceDao.getAccountCBA(accountId);
-        final Invoice savedInvoice = invoiceDao.getById(invoice.getId());
+        final BigDecimal cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
+        final Invoice savedInvoice = invoiceDao.getById(invoice.getId(), internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("20.0")), 0);
         if (partialRefund) {
             // IB = 20 (rec) - 20 (repair) + 20 (cba) - (20 -7) = 7;  AB = IB - CBA = 7 - 20 = -13
@@ -640,41 +639,40 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         }
     }
 
-
     @Test(groups = "slow")
-    public void testAccountBalanceWithSmallRefundAndCBANoAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithSmallRefundAndCBANoAdj() throws InvoiceApiException, EntityPersistenceException {
         BigDecimal refundAmount = new BigDecimal("7.00");
         BigDecimal expectedBalance = new BigDecimal("-3.00");
         testAccountBalanceWithRefundAndCBAInternal(false, refundAmount, expectedBalance);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithSmallRefundAndCBAWithAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithSmallRefundAndCBAWithAdj() throws InvoiceApiException, EntityPersistenceException {
         BigDecimal refundAmount = new BigDecimal("7.00");
         BigDecimal expectedBalance = new BigDecimal("-10.00");
         testAccountBalanceWithRefundAndCBAInternal(true, refundAmount, expectedBalance);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithLargeRefundAndCBANoAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithLargeRefundAndCBANoAdj() throws InvoiceApiException, EntityPersistenceException {
         BigDecimal refundAmount = new BigDecimal("20.00");
         BigDecimal expectedBalance = new BigDecimal("10.00");
         testAccountBalanceWithRefundAndCBAInternal(false, refundAmount, expectedBalance);
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithLargeRefundAndCBAWithAdj() throws InvoiceApiException {
+    public void testAccountBalanceWithLargeRefundAndCBAWithAdj() throws InvoiceApiException, EntityPersistenceException {
         BigDecimal refundAmount = new BigDecimal("20.00");
         BigDecimal expectedBalance = new BigDecimal("-10.00");
         testAccountBalanceWithRefundAndCBAInternal(true, refundAmount, expectedBalance);
     }
 
-    private void testAccountBalanceWithRefundAndCBAInternal(boolean withAdjustment, final BigDecimal refundAmount, final BigDecimal expectedFinalBalance) throws InvoiceApiException {
+    private void testAccountBalanceWithRefundAndCBAInternal(final boolean withAdjustment, final BigDecimal refundAmount, final BigDecimal expectedFinalBalance) throws InvoiceApiException, EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -685,69 +683,69 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Fixed Item
         final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
-                amount1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                      amount1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
-        BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("5.00")), 0);
 
         // Recurring item
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+                                                                    endDate, rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
 
         // Pay the whole thing
         final UUID paymentId = UUID.randomUUID();
         final BigDecimal payment1 = amount1.add(rate1);
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoicePaymentDao.create(payment, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
 
         // Repair previous item with rate 2
         final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
         final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2Repair, context);
-        invoiceItemSqlDao.create(item2Replace, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+                                                                           endDate, rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2Repair, internalCallContext);
+        invoiceItemSqlDao.create(item2Replace, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
 
         // CBA
         final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), balance.negate(), Currency.USD);
-        invoiceItemSqlDao.create(cbaItem, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoiceItemSqlDao.create(cbaItem, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
-        BigDecimal cba = invoiceDao.getAccountCBA(accountId);
+        BigDecimal cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
 
         // PARTIAL REFUND on the payment
-        invoiceDao.createRefund(paymentId, refundAmount, withAdjustment, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), context);
+        invoiceDao.createRefund(paymentId, refundAmount, withAdjustment, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), internalCallContext);
 
-        balance = invoiceDao.getAccountBalance(accountId);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(expectedFinalBalance), 0);
-        cba = invoiceDao.getAccountCBA(accountId);
+        cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
     }
 
     @Test(groups = "slow")
-    public void testExternalChargeWithCBA() throws InvoiceApiException {
+    public void testExternalChargeWithCBA() throws InvoiceApiException, EntityPersistenceException {
 
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         // CREATE INVOICE WITH A (just) CBA. Should not happen, but that does not matter for that test
         final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), new BigDecimal("20.0"), Currency.USD);
-        invoiceItemSqlDao.create(cbaItem, context);
+        invoiceItemSqlDao.create(cbaItem, internalCallContext);
 
-        final InvoiceItem charge =  invoiceDao.insertExternalCharge(accountId, null, bundleId, "bla", new BigDecimal("15.0"), clock.getUTCNow().toLocalDate(), Currency.USD, context);
+        final InvoiceItem charge = invoiceDao.insertExternalCharge(accountId, null, bundleId, "bla", new BigDecimal("15.0"), clock.getUTCNow().toLocalDate(), Currency.USD, internalCallContext);
 
-        final Invoice newInvoice = invoiceDao.getById(charge.getInvoiceId());
+        final Invoice newInvoice = invoiceDao.getById(charge.getInvoiceId(), internalCallContext);
         List<InvoiceItem> items = newInvoice.getInvoiceItems();
         assertEquals(items.size(), 2);
         for (InvoiceItem cur : items) {
@@ -760,12 +758,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testAccountBalanceWithAllSortsOfThings() {
+    public void testAccountBalanceWithAllSortsOfThings() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -776,78 +774,77 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Fixed Item
         final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
-                amount1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                      amount1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
-        BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+        BigDecimal balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("5.00")), 0);
 
         // Recurring item
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+                                                                    endDate, rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
 
         // Pay the whole thing
         final BigDecimal payment1 = amount1.add(rate1);
         final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), new DateTime(), payment1, Currency.USD);
-        invoicePaymentDao.create(payment, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoicePaymentDao.create(payment, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
 
         // Repair previous item with rate 2
         final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
         final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
-                endDate, rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2Repair, context);
-        invoiceItemSqlDao.create(item2Replace, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+                                                                           endDate, rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2Repair, internalCallContext);
+        invoiceItemSqlDao.create(item2Replace, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
 
         // CBA
         final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), balance.negate(), Currency.USD);
-        invoiceItemSqlDao.create(cbaItem, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoiceItemSqlDao.create(cbaItem, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
-        BigDecimal cba = invoiceDao.getAccountCBA(accountId);
+        BigDecimal cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
 
         // partial REFUND on the payment (along with CBA generated by the system)
         final InvoicePayment refund = new DefaultInvoicePayment(UUID.randomUUID(), InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), new DateTime(), rate2.negate(), Currency.USD, null, payment.getId());
-        invoicePaymentDao.create(refund, context);
+        invoicePaymentDao.create(refund, internalCallContext);
         final CreditBalanceAdjInvoiceItem cbaItem2 = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), rate2.negate(), Currency.USD);
-        invoiceItemSqlDao.create(cbaItem2, context);
+        invoiceItemSqlDao.create(cbaItem2, internalCallContext);
 
-        balance = invoiceDao.getAccountBalance(accountId);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
-        cba = invoiceDao.getAccountCBA(accountId);
+        cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(BigDecimal.ZERO), 0);
 
         // NEXT RECURRING on invoice 2
 
         final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1.plusMonths(1), Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final RecurringInvoiceItem nextItem = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test bla", startDate.plusMonths(1),
-                endDate.plusMonths(1), rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(nextItem, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+                                                                       endDate.plusMonths(1), rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(nextItem, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("10.00")), 0);
-        cba = invoiceDao.getAccountCBA(accountId);
+        cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("0.00")), 0);
 
         // FINALLY ISSUE A CREDIT ADJ
         final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice2.getId(), accountId, new LocalDate(), rate2.negate(), Currency.USD);
-        invoiceItemSqlDao.create(creditItem, context);
-        balance = invoiceDao.getAccountBalance(accountId);
+        invoiceItemSqlDao.create(creditItem, internalCallContext);
+        balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
-        cba = invoiceDao.getAccountCBA(accountId);
+        cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
         assertEquals(cba.compareTo(new BigDecimal("0.00")), 0);
 
     }
 
-
     @Test(groups = "slow")
     public void testAccountCredit() {
 
@@ -857,18 +854,18 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         final BigDecimal creditAmount = new BigDecimal("5.0");
 
-        invoiceDao.insertCredit(accountId, null, creditAmount, effectiveDate, Currency.USD, context);
+        invoiceDao.insertCredit(accountId, null, creditAmount, effectiveDate, Currency.USD, internalCallContext);
 
-        final List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId);
+        final List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId, internalCallContext);
         assertEquals(invoices.size(), 1);
 
-        Invoice invoice = invoices.get(0);
+        final Invoice invoice = invoices.get(0);
         assertTrue(invoice.getBalance().compareTo(BigDecimal.ZERO) == 0);
-        List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
+        final List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
         assertEquals(invoiceItems.size(), 2);
         boolean foundCredit = false;
         boolean foundCBA = false;
-        for (InvoiceItem cur : invoiceItems) {
+        for (final InvoiceItem cur : invoiceItems) {
             if (cur.getInvoiceItemType() == InvoiceItemType.CREDIT_ADJ) {
                 foundCredit = true;
                 assertTrue(cur.getAmount().compareTo(creditAmount.negate()) == 0);
@@ -881,9 +878,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         assertTrue(foundCBA);
     }
 
-
     @Test(groups = "slow")
-    public void testInvoiceCreditWithBalancePositive() {
+    public void testInvoiceCreditWithBalancePositive() throws EntityPersistenceException {
         final BigDecimal creditAmount = new BigDecimal("2.0");
         final BigDecimal expectedBalance = new BigDecimal("3.0");
         final boolean expectCBA = false;
@@ -891,7 +887,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testInvoiceCreditWithBalanceNegative() {
+    public void testInvoiceCreditWithBalanceNegative() throws EntityPersistenceException {
         final BigDecimal creditAmount = new BigDecimal("7.0");
         final BigDecimal expectedBalance = new BigDecimal("0.0");
         final boolean expectCBA = true;
@@ -899,23 +895,22 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testInvoiceCreditWithBalanceZero() {
+    public void testInvoiceCreditWithBalanceZero() throws EntityPersistenceException {
         final BigDecimal creditAmount = new BigDecimal("5.0");
         final BigDecimal expectedBalance = new BigDecimal("0.0");
         final boolean expectCBA = false;
         testInvoiceCreditInternal(creditAmount, expectedBalance, expectCBA);
     }
 
-    private void testInvoiceCreditInternal(BigDecimal creditAmount, BigDecimal expectedBalance, boolean expectCBA) {
+    private void testInvoiceCreditInternal(final BigDecimal creditAmount, final BigDecimal expectedBalance, final boolean expectCBA) throws EntityPersistenceException {
 
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
-
-        // Crete one invoice with a fixed invoice item
+        // Create one invoice with a fixed invoice item
         final LocalDate targetDate = new LocalDate(2011, 2, 15);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
 
@@ -923,24 +918,24 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // Fixed Item
         final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
-                amount1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                      amount1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         // Create the credit item
         final LocalDate effectiveDate = new LocalDate(2011, 3, 1);
 
-        invoiceDao.insertCredit(accountId, invoice1.getId(), creditAmount, effectiveDate, Currency.USD, context);
+        invoiceDao.insertCredit(accountId, invoice1.getId(), creditAmount, effectiveDate, Currency.USD, internalCallContext);
 
-        final List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId);
+        final List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId, internalCallContext);
         assertEquals(invoices.size(), 1);
 
-        Invoice invoice = invoices.get(0);
+        final Invoice invoice = invoices.get(0);
         assertTrue(invoice.getBalance().compareTo(expectedBalance) == 0);
-        List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
+        final List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
         assertEquals(invoiceItems.size(), expectCBA ? 3 : 2);
         boolean foundCredit = false;
         boolean foundCBA = false;
-        for (InvoiceItem cur : invoiceItems) {
+        for (final InvoiceItem cur : invoiceItems) {
             if (cur.getInvoiceItemType() == InvoiceItemType.CREDIT_ADJ) {
                 foundCredit = true;
                 assertTrue(cur.getAmount().compareTo(creditAmount.negate()) == 0);
@@ -953,12 +948,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testGetUnpaidInvoicesByAccountId() {
+    public void testGetUnpaidInvoicesByAccountId() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
         final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate = new LocalDate(2011, 3, 1);
         final LocalDate endDate = startDate.plusMonths(1);
@@ -967,27 +962,27 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal rate2 = new BigDecimal("42.0");
 
         final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
-                rate1, rate1, Currency.USD);
-        invoiceItemSqlDao.create(item1, context);
+                                                                    rate1, rate1, Currency.USD);
+        invoiceItemSqlDao.create(item1, internalCallContext);
 
         final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
-                rate2, rate2, Currency.USD);
-        invoiceItemSqlDao.create(item2, context);
+                                                                    rate2, rate2, Currency.USD);
+        invoiceItemSqlDao.create(item2, internalCallContext);
 
         LocalDate upToDate;
         Collection<Invoice> invoices;
 
         upToDate = new LocalDate(2011, 1, 1);
-        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
+        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContext);
         assertEquals(invoices.size(), 0);
 
         upToDate = new LocalDate(2012, 1, 1);
-        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
+        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContext);
         assertEquals(invoices.size(), 1);
 
         final LocalDate targetDate2 = new LocalDate(2011, 7, 1);
         final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate2, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         final LocalDate startDate2 = new LocalDate(2011, 6, 1);
         final LocalDate endDate2 = startDate2.plusMonths(3);
@@ -995,15 +990,15 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BigDecimal rate3 = new BigDecimal("21.0");
 
         final RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2,
-                rate3, rate3, Currency.USD);
-        invoiceItemSqlDao.create(item3, context);
+                                                                    rate3, rate3, Currency.USD);
+        invoiceItemSqlDao.create(item3, internalCallContext);
 
         upToDate = new LocalDate(2011, 1, 1);
-        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
+        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContext);
         assertEquals(invoices.size(), 0);
 
         upToDate = new LocalDate(2012, 1, 1);
-        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
+        invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContext);
         assertEquals(invoices.size(), 2);
     }
 
@@ -1029,8 +1024,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         final DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0);
         final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan1, phase1, null,
-                recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
 
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
@@ -1047,8 +1042,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         final DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0);
         final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan2, phase2, null,
-                recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                "testEvent2", 2L, SubscriptionTransitionType.CREATE);
+                                                           recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                           "testEvent2", 2L, SubscriptionTransitionType.CREATE);
         events.add(event2);
 
         // second invoice should be for one half (14/28 days) the difference between the rate plans
@@ -1057,13 +1052,13 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         assertEquals(invoice2.getBalance(), FIVE);
         invoiceList.add(invoice2);
 
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
-        final Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId());
+        final Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId(), internalCallContext);
         assertEquals(savedInvoice1.getBalance(), ZERO);
 
-        final Invoice savedInvoice2 = invoiceDao.getById(invoice2.getId());
+        final Invoice savedInvoice2 = invoiceDao.getById(invoice2.getId(), internalCallContext);
         assertEquals(savedInvoice2.getBalance(), FIFTEEN);
     }
 
@@ -1079,8 +1074,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final DateTime effectiveDate = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event = createMockBillingEvent(null, subscription, effectiveDate, plan, phase, null,
-                recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
-                "testEvent", 1L, SubscriptionTransitionType.CREATE);
+                                                          recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+                                                          "testEvent", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event);
 
@@ -1118,8 +1113,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final DateTime effectiveDate1 = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1, fixedPrice.getPrice(currency),
-                null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                           null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
@@ -1132,12 +1127,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final List<Invoice> invoiceList = new ArrayList<Invoice>();
         invoiceList.add(invoice1);
 
-        //invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), context);
+        //invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), internalCallContext);
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent2", 2L, SubscriptionTransitionType.PHASE);
+                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent2", 2L, SubscriptionTransitionType.PHASE);
         events.add(event2);
 
         final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
@@ -1147,7 +1142,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         invoiceList.add(invoice2);
 
-        //invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), context);
+        //invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), internalCallContext);
 
         final DateTime effectiveDate3 = effectiveDate2.plusMonths(1);
         final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate3), DateTimeZone.UTC, Currency.USD);
@@ -1155,7 +1150,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         assertEquals(invoice3.getNumberOfItems(), 1);
         assertEquals(invoice3.getBalance().compareTo(cheapAmount), 0);
 
-        //invoiceDao.create(invoice3, invoice3.getTargetDate().getDayOfMonth(), context);
+        //invoiceDao.create(invoice3, invoice3.getTargetDate().getDayOfMonth(), internalCallContext);
     }
 
     @Test(groups = "slow")
@@ -1183,16 +1178,16 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final DateTime effectiveDate1 = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1,
-                fixedPrice.getPrice(currency), null, currency,
-                BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                           fixedPrice.getPrice(currency), null, currency,
+                                                           BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
@@ -1200,17 +1195,16 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         assertEquals(invoice.getNumberOfItems(), 2);
         assertEquals(invoice.getBalance().compareTo(cheapAmount), 0);
 
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
-        final Invoice savedInvoice = invoiceDao.getById(invoice.getId());
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        final Invoice savedInvoice = invoiceDao.getById(invoice.getId(), internalCallContext);
 
         assertNotNull(savedInvoice);
         assertEquals(savedInvoice.getNumberOfItems(), 2);
         assertEquals(savedInvoice.getBalance().compareTo(cheapAmount), 0);
     }
 
-
     @Test(groups = "slow")
-    public void testRefundedInvoiceWithInvoiceItemAdjustmentWithRepair() throws InvoiceApiException  {
+    public void testRefundedInvoiceWithInvoiceItemAdjustmentWithRepair() throws InvoiceApiException {
 
         final UUID accountId = UUID.randomUUID();
         final UUID subscriptionId = UUID.randomUUID();
@@ -1223,39 +1217,35 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final LocalDate recuringEndDate = clock.getUTCNow().plusDays(30).toLocalDate();
         final LocalDate targetDate = recuringStartDate.plusDays(1);
 
-
         // FIRST CREATE INITIAL INVOICE WITH ONE RECURRING ITEM
         final Invoice invoice = new DefaultInvoice(accountId, targetDate, targetDate, Currency.USD);
         final UUID invoiceId = invoice.getId();
 
         final InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test-plan", "test-phase-rec",
-                recuringStartDate, recuringEndDate, new BigDecimal("239.00"), new BigDecimal("239.00"), Currency.USD);
-
+                                                                 recuringStartDate, recuringEndDate, new BigDecimal("239.00"), new BigDecimal("239.00"), Currency.USD);
 
         invoice.addInvoiceItem(invoiceItem);
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
-
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         ((ClockMock) clock).addDays(1);
 
         // SECOND CREATE THE PAYMENT
         final BigDecimal paymentAmount = new BigDecimal("239.00");
         final UUID paymentId = UUID.randomUUID();
-        invoiceDao.notifyOfPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, clock.getUTCNow(), paymentAmount, Currency.USD), context);
+        invoiceDao.notifyOfPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, clock.getUTCNow(), paymentAmount, Currency.USD), internalCallContext);
 
         // AND THEN THIRD THE REFUND
-        Map<UUID, BigDecimal> invoiceItemMap = new HashMap<UUID, BigDecimal>();
+        final Map<UUID, BigDecimal> invoiceItemMap = new HashMap<UUID, BigDecimal>();
         invoiceItemMap.put(invoiceItem.getId(), new BigDecimal("239.00"));
-        invoiceDao.createRefund(paymentId, paymentAmount, true, invoiceItemMap, UUID.randomUUID(), context);
+        invoiceDao.createRefund(paymentId, paymentAmount, true, invoiceItemMap, UUID.randomUUID(), internalCallContext);
 
-        final Invoice savedInvoice = invoiceDao.getById(invoiceId);
+        final Invoice savedInvoice = invoiceDao.getById(invoiceId, internalCallContext);
         assertNotNull(savedInvoice);
         assertEquals(savedInvoice.getInvoiceItems().size(), 2);
 
         final List<Invoice> invoices = new ArrayList<Invoice>();
         invoices.add(savedInvoice);
 
-
         // NOW COMPUTE A DIFFERENT ITEM TO TRIGGER REPAIR
         final BillingEventSet events = new MockBillingEventSet();
         final Subscription subscription = getZombieSubscription();
@@ -1270,15 +1260,15 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         Mockito.when(phase2.getName()).thenReturn("plan-phase2");
 
         final BillingEvent event1 = createMockBillingEvent(null, subscription, recuringStartDate.toDateTimeAtStartOfDay(), plan, phase1, null,
-                TEN, Currency.USD,
-                BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                "new-event", 1L, SubscriptionTransitionType.CREATE);
+                                                           TEN, Currency.USD,
+                                                           BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                           "new-event", 1L, SubscriptionTransitionType.CREATE);
         events.add(event1);
-        Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, DateTimeZone.UTC, Currency.USD);
-        invoiceDao.create(newInvoice, newInvoice.getTargetDate().getDayOfMonth(), true, context);
+        final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, DateTimeZone.UTC, Currency.USD);
+        invoiceDao.create(newInvoice, newInvoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
 
         // VERIFY THAT WE STILL HAVE ONLY 2 ITEMS, MENAING THERE WERE NO REPAIR AND NO CBA GENERATED
-        final Invoice firstInvoice = invoiceDao.getById(invoiceId);
+        final Invoice firstInvoice = invoiceDao.getById(invoiceId, internalCallContext);
         assertNotNull(firstInvoice);
         assertEquals(firstInvoice.getInvoiceItems().size(), 2);
     }
@@ -1304,25 +1294,25 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final List<Invoice> invoices = new ArrayList<Invoice>();
 
         final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
-                TEN, currency,
-                BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+                                                           TEN, currency,
+                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
         events.add(event1);
 
         Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), DateTimeZone.UTC, Currency.USD);
         invoices.add(invoice1);
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoice1 = invoiceDao.getById(invoice1.getId());
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoice1 = invoiceDao.getById(invoice1.getId(), internalCallContext);
         assertNotNull(invoice1.getInvoiceNumber());
 
         final BillingEvent event2 = createMockBillingEvent(null, subscription, targetDate1, plan, phase2, null,
-                TWENTY, currency,
-                BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+                                                           TWENTY, currency,
+                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
         Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), DateTimeZone.UTC, Currency.USD);
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
-        invoice2 = invoiceDao.getById(invoice2.getId());
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoice2 = invoiceDao.getById(invoice2.getId(), internalCallContext);
         assertNotNull(invoice2.getInvoiceNumber());
     }
 
@@ -1341,18 +1331,18 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // create pseudo-random invoice
         final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
-                TEN, currency,
-                BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+                                                           TEN, currency,
+                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(targetDate1), DateTimeZone.UTC, Currency.USD);
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
-        invoiceDao.setWrittenOff(invoice.getId(), context);
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceDao.setWrittenOff(invoice.getId(), internalCallContext);
 
         final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
-        final Map<String, Tag> tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE);
+        final Map<String, Tag> tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE, internalCallContext);
         assertEquals(tags.size(), 1);
         assertEquals(tags.values().iterator().next().getTagDefinitionId(), ControlTagType.WRITTEN_OFF.getId());
     }
@@ -1372,23 +1362,23 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // create pseudo-random invoice
         final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
-                TEN, currency,
-                BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+                                                           TEN, currency,
+                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                           "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(targetDate1), DateTimeZone.UTC, Currency.USD);
-        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
-        invoiceDao.setWrittenOff(invoice.getId(), context);
+        invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceDao.setWrittenOff(invoice.getId(), internalCallContext);
 
         final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
-        Map<String, Tag> tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE);
+        Map<String, Tag> tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE, internalCallContext);
         assertEquals(tags.size(), 1);
         assertEquals(tags.values().iterator().next().getTagDefinitionId(), ControlTagType.WRITTEN_OFF.getId());
 
-        invoiceDao.removeWrittenOff(invoice.getId(), context);
-        tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE);
+        invoiceDao.removeWrittenOff(invoice.getId(), internalCallContext);
+        tags = tagDao.loadEntities(invoice.getId(), ObjectType.INVOICE, internalCallContext);
         assertEquals(tags.size(), 0);
     }
 
@@ -1412,20 +1402,20 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(),
                                                                                                          fixedItem1.getStartDate(), fixedItem1.getAmount(),
                                                                                                          fixedItem1.getCurrency());
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem1, context);
-        invoiceItemSqlDao.create(repairAdjInvoiceItem, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem1, internalCallContext);
+        invoiceItemSqlDao.create(repairAdjInvoiceItem, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, internalCallContext);
 
         // Verify scenario - no CBA should have been used
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 10.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 10.00);
         verifyInvoice(invoice1.getId(), 10.00, 10.00);
 
         // Delete the CBA on invoice 1
-        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context);
+        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
 
         // Verify the result
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 0.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
         verifyInvoice(invoice1.getId(), 0.00, 0.00);
     }
 
@@ -1449,10 +1439,10 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(),
                                                                                                          fixedItem1.getStartDate(), fixedItem1.getAmount(),
                                                                                                          fixedItem1.getCurrency());
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem1, context);
-        invoiceItemSqlDao.create(repairAdjInvoiceItem, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem1, internalCallContext);
+        invoiceItemSqlDao.create(repairAdjInvoiceItem, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, internalCallContext);
 
         // Create invoice 2
         // Scenario: single item
@@ -1464,20 +1454,20 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem2.getInvoiceId(), fixedItem2.getAccountId(),
                                                                                                          fixedItem2.getStartDate(), fixedItem2.getAmount().negate(),
                                                                                                          fixedItem2.getCurrency());
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem2, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem2, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem2, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem2, internalCallContext);
 
         // Verify scenario - half of the CBA should have been used
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 5.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 5.00);
         verifyInvoice(invoice1.getId(), 10.00, 10.00);
         verifyInvoice(invoice2.getId(), 0.00, -5.00);
 
         // Delete the CBA on invoice 1
-        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context);
+        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
 
         // Verify all three invoices were affected
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 0.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
         verifyInvoice(invoice1.getId(), 0.00, 0.00);
         verifyInvoice(invoice2.getId(), 5.00, 0.00);
     }
@@ -1502,10 +1492,10 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(),
                                                                                                          fixedItem1.getStartDate(), fixedItem1.getAmount(),
                                                                                                          fixedItem1.getCurrency());
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem1, context);
-        invoiceItemSqlDao.create(repairAdjInvoiceItem, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem1, internalCallContext);
+        invoiceItemSqlDao.create(repairAdjInvoiceItem, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, internalCallContext);
 
         // Create invoice 2
         // Scenario: single item
@@ -1517,9 +1507,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem2.getInvoiceId(), fixedItem2.getAccountId(),
                                                                                                          fixedItem2.getStartDate(), fixedItem2.getAmount().negate(),
                                                                                                          fixedItem2.getCurrency());
-        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem2, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem2, context);
+        invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem2, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem2, internalCallContext);
 
         // Create invoice 3
         // Scenario: single item
@@ -1531,21 +1521,21 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem3 = new CreditBalanceAdjInvoiceItem(fixedItem3.getInvoiceId(), fixedItem3.getAccountId(),
                                                                                                          fixedItem3.getStartDate(), fixedItem3.getAmount().negate(),
                                                                                                          fixedItem3.getCurrency());
-        invoiceDao.create(invoice3, invoice3.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(fixedItem3, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem3, context);
+        invoiceDao.create(invoice3, invoice3.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(fixedItem3, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem3, internalCallContext);
 
         // Verify scenario - all CBA should have been used
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 0.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
         verifyInvoice(invoice1.getId(), 10.00, 10.00);
         verifyInvoice(invoice2.getId(), 0.00, -5.00);
         verifyInvoice(invoice3.getId(), 0.00, -5.00);
 
         // Delete the CBA on invoice 1
-        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context);
+        invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
 
         // Verify all three invoices were affected
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 0.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
         verifyInvoice(invoice1.getId(), 0.00, 0.00);
         verifyInvoice(invoice2.getId(), 5.00, 0.00);
         verifyInvoice(invoice3.getId(), 5.00, 0.00);
@@ -1567,17 +1557,17 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(invoice1.getId(), invoice1.getAccountId(),
                                                                                                          invoice1.getInvoiceDate(), repairAdjInvoiceItem.getAmount().negate(),
                                                                                                          invoice1.getCurrency());
-        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
-        invoiceItemSqlDao.create(repairAdjInvoiceItem, context);
-        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, context);
+        invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, internalCallContext);
+        invoiceItemSqlDao.create(repairAdjInvoiceItem, internalCallContext);
+        invoiceItemSqlDao.create(creditBalanceAdjInvoiceItem1, internalCallContext);
 
         // Verify scenario
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 10.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 10.00);
         verifyInvoice(invoice1.getId(), 0.00, 10.00);
 
         // Delete the CBA on invoice 1
         try {
-            invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context);
+            invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
             Assert.fail();
         } catch (TransactionFailedException e) {
             Assert.assertTrue(e.getCause() instanceof InvoiceApiException);
@@ -1585,12 +1575,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         }
 
         // Verify the result
-        Assert.assertEquals(invoiceDao.getAccountCBA(accountId).doubleValue(), 10.00);
+        Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 10.00);
         verifyInvoice(invoice1.getId(), 0.00, 10.00);
     }
 
     private void verifyInvoice(final UUID invoiceId, final double balance, final double cbaAmount) throws InvoiceApiException {
-        final Invoice invoice = invoiceDao.getById(invoiceId);
+        final Invoice invoice = invoiceDao.getById(invoiceId, internalCallContext);
         Assert.assertEquals(invoice.getBalance().doubleValue(), balance);
         Assert.assertEquals(invoice.getCBAAmount().doubleValue(), cbaAmount);
     }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
index 5fc759d..8182355 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
@@ -33,7 +33,7 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.RecurringInvoiceItem;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 
 public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
 
@@ -45,10 +45,10 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
         final UUID invoiceId = UUID.randomUUID();
         final UUID invoiceItemId = UUID.randomUUID();
         final LocalDate effectiveDate = new LocalDate();
-        final CallContext context = Mockito.mock(CallContext.class);
+        final InternalCallContext context = Mockito.mock(InternalCallContext.class);
 
         try {
-            invoiceDao.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, null, null, context);
+            invoiceDao.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, null, null, internalCallContext);
             Assert.fail("Should not have been able to adjust a non existing invoice item");
         } catch (Exception e) {
             Assert.assertEquals(((InvoiceApiException) e.getCause()).getCode(), ErrorCode.INVOICE_ITEM_NOT_FOUND.getCode());
@@ -63,10 +63,10 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
                                                                  new LocalDate(2010, 1, 1), new LocalDate(2010, 4, 1),
                                                                  INVOICE_ITEM_AMOUNT, new BigDecimal("7.00"), Currency.USD);
         invoice.addInvoiceItem(invoiceItem);
-        invoiceDao.create(invoice, 1, true, context);
+        invoiceDao.create(invoice, 1, true, internalCallContext);
 
         try {
-            invoiceDao.insertInvoiceItemAdjustment(invoice.getAccountId(), UUID.randomUUID(), invoiceItem.getId(), new LocalDate(2010, 1, 1), null, null, context);
+            invoiceDao.insertInvoiceItemAdjustment(invoice.getAccountId(), UUID.randomUUID(), invoiceItem.getId(), new LocalDate(2010, 1, 1), null, null, internalCallContext);
             Assert.fail("Should not have been able to adjust an item on a non existing invoice");
         } catch (Exception e) {
             Assert.assertEquals(((InvoiceApiException) e.getCause()).getCode(), ErrorCode.INVOICE_INVALID_FOR_INVOICE_ITEM_ADJUSTMENT.getCode());
@@ -81,7 +81,7 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
                                                                  new LocalDate(2010, 1, 1), new LocalDate(2010, 4, 1),
                                                                  INVOICE_ITEM_AMOUNT, new BigDecimal("7.00"), Currency.USD);
         invoice.addInvoiceItem(invoiceItem);
-        invoiceDao.create(invoice, 1, true, context);
+        invoiceDao.create(invoice, 1, true, internalCallContext);
 
         final InvoiceItem adjustedInvoiceItem = createAndCheckAdjustment(invoice, invoiceItem, null);
         Assert.assertEquals(adjustedInvoiceItem.getAmount().compareTo(invoiceItem.getAmount().negate()), 0);
@@ -95,7 +95,7 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
                                                                  new LocalDate(2010, 1, 1), new LocalDate(2010, 4, 1),
                                                                  INVOICE_ITEM_AMOUNT, new BigDecimal("7.00"), Currency.USD);
         invoice.addInvoiceItem(invoiceItem);
-        invoiceDao.create(invoice, 1, true, context);
+        invoiceDao.create(invoice, 1, true, internalCallContext);
 
         final InvoiceItem adjustedInvoiceItem = createAndCheckAdjustment(invoice, invoiceItem, BigDecimal.TEN);
         Assert.assertEquals(adjustedInvoiceItem.getAmount().compareTo(BigDecimal.TEN.negate()), 0);
@@ -104,7 +104,7 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
     private InvoiceItem createAndCheckAdjustment(final Invoice invoice, final InvoiceItem invoiceItem, final BigDecimal amount) throws InvoiceApiException {
         final LocalDate effectiveDate = new LocalDate(2010, 1, 1);
         final InvoiceItem adjustedInvoiceItem = invoiceDao.insertInvoiceItemAdjustment(invoice.getAccountId(), invoice.getId(), invoiceItem.getId(),
-                                                                                       effectiveDate, amount, null, context);
+                                                                                       effectiveDate, amount, null, internalCallContext);
         Assert.assertEquals(adjustedInvoiceItem.getAccountId(), invoiceItem.getAccountId());
         Assert.assertNull(adjustedInvoiceItem.getBundleId());
         Assert.assertEquals(adjustedInvoiceItem.getCurrency(), invoiceItem.getCurrency());
@@ -120,11 +120,11 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
         Assert.assertNull(adjustedInvoiceItem.getSubscriptionId());
 
         // Retrieve the item by id
-        final InvoiceItem retrievedInvoiceItem = invoiceItemSqlDao.getById(adjustedInvoiceItem.getId().toString());
+        final InvoiceItem retrievedInvoiceItem = invoiceItemSqlDao.getById(adjustedInvoiceItem.getId().toString(), internalCallContext);
         Assert.assertEquals(retrievedInvoiceItem, adjustedInvoiceItem);
 
         // Retrieve the item by invoice id
-        final Invoice retrievedInvoice = invoiceDao.getById(adjustedInvoiceItem.getInvoiceId());
+        final Invoice retrievedInvoice = invoiceDao.getById(adjustedInvoiceItem.getInvoiceId(), internalCallContext);
         final List<InvoiceItem> invoiceItems = retrievedInvoice.getInvoiceItems();
         Assert.assertEquals(invoiceItems.size(), 2);
         final InvoiceItem retrievedByInvoiceInvoiceItem;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceItemDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceItemDao.java
index acf4a79..59ae006 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceItemDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceItemDao.java
@@ -30,6 +30,7 @@ import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.ExternalChargeInvoiceItem;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
 import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.util.entity.EntityPersistenceException;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -38,7 +39,7 @@ import static org.testng.Assert.assertTrue;
 public class TestInvoiceItemDao extends InvoiceDaoTestBase {
 
     @Test(groups = "slow")
-    public void testInvoiceItemCreation() {
+    public void testInvoiceItemCreation() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID invoiceId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
@@ -49,9 +50,9 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
 
         final RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test plan", "test phase", startDate, endDate,
                                                                    rate, rate, Currency.USD);
-        invoiceItemSqlDao.create(item, context);
+        invoiceItemSqlDao.create(item, internalCallContext);
 
-        final RecurringInvoiceItem thisItem = (RecurringInvoiceItem) invoiceItemSqlDao.getById(item.getId().toString());
+        final RecurringInvoiceItem thisItem = (RecurringInvoiceItem) invoiceItemSqlDao.getById(item.getId().toString(), internalCallContext);
         assertNotNull(thisItem);
         assertEquals(thisItem.getId(), item.getId());
         assertEquals(thisItem.getInvoiceId(), item.getInvoiceId());
@@ -66,7 +67,7 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
     }
 
     @Test(groups = "slow")
-    public void testGetInvoiceItemsBySubscriptionId() {
+    public void testGetInvoiceItemsBySubscriptionId() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID subscriptionId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
@@ -79,15 +80,15 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
             final RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
                                                                        "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1),
                                                                        rate, rate, Currency.USD);
-            invoiceItemSqlDao.create(item, context);
+            invoiceItemSqlDao.create(item, internalCallContext);
         }
 
-        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsBySubscription(subscriptionId.toString());
+        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsBySubscription(subscriptionId.toString(), internalCallContext);
         assertEquals(items.size(), 3);
     }
 
     @Test(groups = "slow")
-    public void testGetInvoiceItemsByInvoiceId() {
+    public void testGetInvoiceItemsByInvoiceId() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID invoiceId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
@@ -101,21 +102,21 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
             final RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
                                                                        "test plan", "test phase", startDate, startDate.plusMonths(1),
                                                                        amount, amount, Currency.USD);
-            invoiceItemSqlDao.create(item, context);
+            invoiceItemSqlDao.create(item, internalCallContext);
         }
 
-        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsByInvoice(invoiceId.toString());
+        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsByInvoice(invoiceId.toString(), internalCallContext);
         assertEquals(items.size(), 5);
     }
 
     @Test(groups = "slow")
-    public void testGetInvoiceItemsByAccountId() {
+    public void testGetInvoiceItemsByAccountId() throws EntityPersistenceException {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final LocalDate targetDate = new LocalDate(2011, 5, 23);
         final DefaultInvoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate, Currency.USD);
 
-        invoiceDao.create(invoice, targetDate.getDayOfMonth(), true, context);
+        invoiceDao.create(invoice, targetDate.getDayOfMonth(), true, internalCallContext);
 
         final UUID invoiceId = invoice.getId();
         final LocalDate startDate = new LocalDate(2011, 3, 1);
@@ -126,36 +127,36 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
         final RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
                                                                    "test plan", "test phase", startDate, startDate.plusMonths(1),
                                                                    rate, rate, Currency.USD);
-        invoiceItemSqlDao.create(item, context);
+        invoiceItemSqlDao.create(item, internalCallContext);
 
-        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsByAccount(accountId.toString());
+        final List<InvoiceItem> items = invoiceItemSqlDao.getInvoiceItemsByAccount(accountId.toString(), internalCallContext);
         assertEquals(items.size(), 1);
     }
 
     @Test(groups = "slow")
-    public void testCreditBalanceInvoiceSqlDao() {
+    public void testCreditBalanceInvoiceSqlDao() throws EntityPersistenceException {
         final UUID invoiceId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
         final LocalDate creditDate = new LocalDate(2012, 4, 1);
 
         final InvoiceItem creditInvoiceItem = new CreditBalanceAdjInvoiceItem(invoiceId, accountId, creditDate, TEN, Currency.USD);
-        invoiceItemSqlDao.create(creditInvoiceItem, context);
+        invoiceItemSqlDao.create(creditInvoiceItem, internalCallContext);
 
-        final InvoiceItem savedItem = invoiceItemSqlDao.getById(creditInvoiceItem.getId().toString());
+        final InvoiceItem savedItem = invoiceItemSqlDao.getById(creditInvoiceItem.getId().toString(), internalCallContext);
         assertEquals(savedItem, creditInvoiceItem);
     }
 
     @Test(groups = "slow")
-    public void testFixedPriceInvoiceSqlDao() {
+    public void testFixedPriceInvoiceSqlDao() throws EntityPersistenceException {
         final UUID invoiceId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
         final LocalDate startDate = new LocalDate(2012, 4, 1);
 
         final InvoiceItem fixedPriceInvoiceItem = new FixedPriceInvoiceItem(invoiceId, accountId, UUID.randomUUID(),
                                                                             UUID.randomUUID(), "test plan", "test phase", startDate, TEN, Currency.USD);
-        invoiceItemSqlDao.create(fixedPriceInvoiceItem, context);
+        invoiceItemSqlDao.create(fixedPriceInvoiceItem, internalCallContext);
 
-        final InvoiceItem savedItem = invoiceItemSqlDao.getById(fixedPriceInvoiceItem.getId().toString());
+        final InvoiceItem savedItem = invoiceItemSqlDao.getById(fixedPriceInvoiceItem.getId().toString(), internalCallContext);
         assertEquals(savedItem, fixedPriceInvoiceItem);
     }
 
@@ -168,9 +169,9 @@ public class TestInvoiceItemDao extends InvoiceDaoTestBase {
         final LocalDate startDate = new LocalDate(2012, 4, 1);
         final InvoiceItem externalChargeInvoiceItem = new ExternalChargeInvoiceItem(invoiceId, accountId, bundleId, description,
                                                                                     startDate, TEN, Currency.USD);
-        invoiceItemSqlDao.create(externalChargeInvoiceItem, context);
+        invoiceItemSqlDao.create(externalChargeInvoiceItem, internalCallContext);
 
-        final InvoiceItem savedItem = invoiceItemSqlDao.getById(externalChargeInvoiceItem.getId().toString());
+        final InvoiceItem savedItem = invoiceItemSqlDao.getById(externalChargeInvoiceItem.getId().toString(), internalCallContext);
         assertEquals(savedItem, externalChargeInvoiceItem);
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index 5fb9e88..4aba9db 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -32,10 +32,6 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.catalog.MockCatalogModule;
 import com.ning.billing.config.InvoiceConfig;
@@ -55,6 +51,8 @@ import com.ning.billing.mock.glue.MockJunctionModule;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.email.templates.TemplateModule;
@@ -65,6 +63,11 @@ import com.ning.billing.util.glue.TagStoreModule;
 import com.ning.billing.util.notificationq.DummySqlTest;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.MINUTES;
 
@@ -138,11 +141,12 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB 
 
         final Subscription subscription = Mockito.mock(Subscription.class);
         final EntitlementUserApi entitlementUserApi = Mockito.mock(EntitlementUserApi.class);
-        Mockito.when(entitlementUserApi.getSubscriptionFromId(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementUserApi.getSubscriptionFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         final CallContextFactory factory = new DefaultCallContextFactory(clock);
         listener = new InvoiceListenerMock(factory, dispatcher);
-        notifier = new DefaultNextBillingDateNotifier(notificationQueueService, g.getInstance(InvoiceConfig.class), entitlementUserApi, listener);
+        notifier = new DefaultNextBillingDateNotifier(notificationQueueService, g.getInstance(InvoiceConfig.class), entitlementUserApi,
+                                                      listener, new DefaultCallContextFactory(clock));
     }
 
     @Test(groups = "slow")
@@ -152,7 +156,7 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB 
         final UUID subscriptionId = new UUID(0L, 1L);
         final DateTime now = new DateTime();
         final DateTime readyTime = now.plusMillis(2000);
-        final NextBillingDatePoster poster = new DefaultNextBillingDatePoster(notificationQueueService);
+        final NextBillingDatePoster poster = new DefaultNextBillingDatePoster(notificationQueueService, new InternalCallContextFactory(getMysqlTestingHelper().getDBI(), clock));
 
         eventBus.start();
         notifier.initialize();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index 140fc67..0b8b6e5 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -60,10 +60,8 @@ import com.ning.billing.junction.api.BillingEventSet;
 import com.ning.billing.mock.api.MockBillCycleDay;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
@@ -98,7 +96,8 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
     @Inject
     private Clock clock;
 
-    private CallContext context;
+    private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(getMysqlTestingHelper().getDBI(), clock);
+
     private AccountUserApi accountUserApi;
     private Account account;
     private Subscription subscription;
@@ -108,15 +107,13 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
         notifier.initialize();
         notifier.start();
 
-        context = new DefaultCallContextFactory(clock).createCallContext("Miracle Max", CallOrigin.TEST, UserType.TEST);
-
         busService.getBus().start();
 
         accountUserApi = Mockito.mock(AccountUserApi.class);
         account = Mockito.mock(Account.class);
 
         final UUID accountId = UUID.randomUUID();
-        Mockito.when(accountUserApi.getAccountById(accountId)).thenReturn(account);
+        Mockito.when(accountUserApi.getAccountById(accountId, callContext)).thenReturn(account);
         Mockito.when(account.getCurrency()).thenReturn(Currency.USD);
         Mockito.when(account.getId()).thenReturn(accountId);
         Mockito.when(account.isNotifiedForInvoices()).thenReturn(true);
@@ -152,32 +149,34 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
                                           fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
                                           BillingModeType.IN_ADVANCE, "", 1L, SubscriptionTransitionType.CREATE));
 
-        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(accountId)).thenReturn(events);
+        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(accountId, callContext)).thenReturn(events);
 
         final DateTime target = new DateTime();
 
         final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
         final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, billingApi, invoiceDao,
-                                                                   invoiceNotifier, locker, busService.getBus(), clock);
+                                                                   invoiceNotifier, locker, busService.getBus(),
+                                                                   clock, new InternalCallContextFactory(getMysqlTestingHelper().getDBI(), clock));
 
-        Invoice invoice = dispatcher.processAccount(accountId, target, true, context);
+        Invoice invoice = dispatcher.processAccount(accountId, target, true, callContext);
         Assert.assertNotNull(invoice);
 
-        List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, callContext);
+        List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId, internalTenantContext);
         Assert.assertEquals(invoices.size(), 0);
 
         // Try it again to double check
-        invoice = dispatcher.processAccount(accountId, target, true, context);
+        invoice = dispatcher.processAccount(accountId, target, true, callContext);
         Assert.assertNotNull(invoice);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId);
+        invoices = invoiceDao.getInvoicesByAccount(accountId, internalTenantContext);
         Assert.assertEquals(invoices.size(), 0);
 
         // This time no dry run
-        invoice = dispatcher.processAccount(accountId, target, false, context);
+        invoice = dispatcher.processAccount(accountId, target, false, callContext);
         Assert.assertNotNull(invoice);
 
-        invoices = invoiceDao.getInvoicesByAccount(accountId);
+        invoices = invoiceDao.getInvoicesByAccount(accountId, internalTenantContext);
         Assert.assertEquals(invoices.size(), 1);
     }
 
@@ -207,12 +206,13 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
                                           new MockPlanPhase(jetTrialEvergreen1000USD, PhaseType.EVERGREEN), null, new BigDecimal("1000"), account.getCurrency(), BillingPeriod.MONTHLY,
                                           31, 31, BillingModeType.IN_ADVANCE, "CHANGE", 3L, SubscriptionTransitionType.CHANGE));
 
-        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId())).thenReturn(events);
+        Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext)).thenReturn(events);
         final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
         final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, billingApi, invoiceDao,
-                                                                   invoiceNotifier, locker, busService.getBus(), clock);
+                                                                   invoiceNotifier, locker, busService.getBus(),
+                                                                   clock, internalCallContextFactory);
 
-        final Invoice invoice = dispatcher.processAccount(account.getId(), new DateTime("2012-07-30T00:00:00.000Z"), false, context);
+        final Invoice invoice = dispatcher.processAccount(account.getId(), new DateTime("2012-07-30T00:00:00.000Z"), false, callContext);
         Assert.assertNotNull(invoice);
 
         final List<InvoiceItem> invoiceItems = invoice.getInvoiceItems();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
index 8826134..0bace86 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
@@ -25,6 +25,7 @@ import org.mockito.Mockito;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
@@ -33,6 +34,7 @@ import com.ning.billing.invoice.dao.InvoiceItemSqlDao;
 import com.ning.billing.invoice.dao.InvoiceSqlDao;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.common.collect.ImmutableList;
@@ -46,9 +48,10 @@ public class InvoiceTestUtils {
                                                   final Clock clock,
                                                   final BigDecimal amount,
                                                   final Currency currency,
-                                                  final CallContext callContext) {
+                                                  final CallContext callContext,
+                                                  final InternalCallContextFactory internalCallContextFactory) {
         return createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, ImmutableList.<BigDecimal>of(amount),
-                                       currency, callContext);
+                                       currency, callContext, internalCallContextFactory);
     }
 
     public static Invoice createAndPersistInvoice(final InvoiceSqlDao invoiceSqlDao,
@@ -56,7 +59,8 @@ public class InvoiceTestUtils {
                                                   final Clock clock,
                                                   final List<BigDecimal> amounts,
                                                   final Currency currency,
-                                                  final CallContext callContext) {
+                                                  final CallContext callContext,
+                                                  final InternalCallContextFactory internalCallContextFactory) {
         final Invoice invoice = Mockito.mock(Invoice.class);
         final UUID invoiceId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
@@ -71,12 +75,12 @@ public class InvoiceTestUtils {
         final List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
         for (final BigDecimal amount : amounts) {
             final InvoiceItem invoiceItem = createInvoiceItem(clock, invoiceId, accountId, amount, currency);
-            invoiceItemSqlDao.create(invoiceItem, callContext);
+            invoiceItemSqlDao.create(invoiceItem, internalCallContextFactory.createInternalCallContext(callContext));
             invoiceItems.add(invoiceItem);
         }
         Mockito.when(invoice.getInvoiceItems()).thenReturn(invoiceItems);
 
-        invoiceSqlDao.create(invoice, callContext);
+        invoiceSqlDao.create(invoice, internalCallContextFactory.createInternalCallContext(callContext));
 
         return invoice;
     }
@@ -91,7 +95,7 @@ public class InvoiceTestUtils {
                                                          final UUID invoiceId,
                                                          final BigDecimal amount,
                                                          final Currency currency,
-                                                         final CallContext callContext) {
+                                                         final CallContext callContext) throws InvoiceApiException {
         final InvoicePayment payment = Mockito.mock(InvoicePayment.class);
         Mockito.when(payment.getId()).thenReturn(UUID.randomUUID());
         Mockito.when(payment.getType()).thenReturn(InvoicePaymentType.ATTEMPT);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
index 928b727..4ac6dbf 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
@@ -46,8 +46,7 @@ import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
 import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TestCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.tag.api.DefaultTagUserApi;
@@ -71,7 +70,8 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     private InvoiceSqlDao invoiceSqlDao;
     private InvoiceItemSqlDao invoiceItemSqlDao;
     private InvoicePaymentApi invoicePaymentApi;
-    private CallContext context;
+    private InternalCallContextFactory internalCallContextFactory;
+
     private final Clock clock = new ClockMock();
     private static final Currency CURRENCY = Currency.EUR;
 
@@ -83,18 +83,17 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
         final IDBI dbi = helper.getDBI();
 
         invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
-        invoiceSqlDao.test();
+        invoiceSqlDao.test(internalCallContext);
 
         invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
-        invoiceItemSqlDao.test();
+        invoiceItemSqlDao.test(internalCallContext);
         final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
         final TagDefinitionDao tagDefinitionDao = new MockTagDefinitionDao();
         final TagDao tagDao = new MockTagDao();
-        final TagUserApi tagUserApi = new DefaultTagUserApi(tagDefinitionDao, tagDao);
+        internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
+        final TagUserApi tagUserApi = new DefaultTagUserApi(internalCallContextFactory, tagDefinitionDao, tagDao);
         final InvoiceDao invoiceDao = new AuditedInvoiceDao(dbi, nextBillingDatePoster, tagUserApi, clock, Mockito.mock(Bus.class));
-        invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao);
-
-        context = new TestCallContext("Charge back tests");
+        invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
     }
 
     private static void loadSystemPropertiesFromClasspath(final String resource) {
@@ -109,38 +108,38 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testCompleteChargeBack() throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
         // create a full charge back
-        invoicePaymentApi.createChargeback(payment.getId(), THIRTY, context);
+        invoicePaymentApi.createChargeback(payment.getId(), THIRTY, callContext);
 
         // check amount owed
-        final BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId());
+        final BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId(), callContext);
         assertTrue(amount.compareTo(BigDecimal.ZERO) == 0);
     }
 
     @Test(groups = "slow")
     public void testPartialChargeBack() throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
         // create a partial charge back
-        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, context);
+        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
 
         // check amount owed
-        final BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId());
+        final BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId(), callContext);
         assertTrue(amount.compareTo(FIFTEEN) == 0);
     }
 
     @Test(groups = "slow", expectedExceptions = InvoiceApiException.class)
     public void testChargeBackLargerThanPaymentAmount() throws InvoiceApiException {
         try {
-            final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+            final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
             // create a large charge back
-            invoicePaymentApi.createChargeback(payment.getId(), ONE_MILLION, context);
+            invoicePaymentApi.createChargeback(payment.getId(), ONE_MILLION, callContext);
             fail("Expected a failure...");
         } catch (TransactionFailedException expected) {
             throw (InvoiceApiException) expected.getCause();
@@ -150,11 +149,11 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow", expectedExceptions = InvoiceApiException.class)
     public void testNegativeChargeBackAmount() throws InvoiceApiException {
         try {
-            final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+            final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
             // create a partial charge back
-            invoicePaymentApi.createChargeback(payment.getId(), BigDecimal.ONE.negate(), context);
+            invoicePaymentApi.createChargeback(payment.getId(), BigDecimal.ONE.negate(), callContext);
         } catch (TransactionFailedException expected) {
             throw (InvoiceApiException) expected.getCause();
         }
@@ -162,33 +161,33 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testGetAccountIdFromPaymentIdHappyPath() throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
-        final UUID accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(payment.getId());
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final UUID accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(payment.getId(), callContext);
         assertEquals(accountId, invoice.getAccountId());
     }
 
     @Test(groups = "slow", expectedExceptions = InvoiceApiException.class)
     public void testGetAccountIdFromPaymentIdBadPaymentId() throws InvoiceApiException {
-        invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.randomUUID());
+        invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.randomUUID(), callContext);
     }
 
     @Test(groups = "slow")
     public void testGetChargeBacksByAccountIdWithEmptyReturnSet() throws InvoiceApiException {
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.randomUUID());
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.randomUUID(), callContext);
         assertNotNull(chargebacks);
         assertEquals(chargebacks.size(), 0);
     }
 
     @Test(groups = "slow")
     public void testGetChargeBacksByAccountIdHappyPath() throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
         // create a partial charge back
-        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, context);
+        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
 
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(invoice.getAccountId());
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(invoice.getAccountId(), callContext);
         assertNotNull(chargebacks);
         assertEquals(chargebacks.size(), 1);
         assertEquals(chargebacks.get(0).getLinkedInvoicePaymentId(), payment.getId());
@@ -196,20 +195,20 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testGetChargeBacksByPaymentIdWithEmptyReturnSet() throws InvoiceApiException {
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.randomUUID());
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.randomUUID(), callContext);
         assertNotNull(chargebacks);
         assertEquals(chargebacks.size(), 0);
     }
 
     @Test(groups = "slow")
     public void testGetChargeBacksByInvoicePaymentIdHappyPath() throws InvoiceApiException {
-        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, context);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, context);
+        final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
+        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
 
         // create a partial charge back
-        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, context);
+        invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
 
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(payment.getPaymentId());
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(payment.getPaymentId(), callContext);
         assertNotNull(chargebacks);
         assertEquals(chargebacks.size(), 1);
         assertEquals(chargebacks.get(0).getLinkedInvoicePaymentId(), payment.getId());

jaxrs/pom.xml 6(+5 -1)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 3dad564..22d13e0 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -26,9 +26,13 @@
             <artifactId>killbill-util</artifactId>
         </dependency>
         <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.ws.rs</groupId>
             <artifactId>jsr311-api</artifactId>
-            <version>1.1.1</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TenantJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TenantJson.java
new file mode 100644
index 0000000..7502838
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TenantJson.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.json;
+
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.tenant.api.TenantData;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class TenantJson {
+
+    protected final String tenantId;
+    protected final String externalKey;
+    protected final String apiKey;
+    protected final String apiSecret;
+
+    @JsonCreator
+    public TenantJson(@JsonProperty("tenantId") final String tenantId,
+                      @JsonProperty("externalKey") final String externalKey,
+                      @JsonProperty("apiKey") final String apiKey,
+                      @JsonProperty("apiSecret") final String apiSecret) {
+        this.tenantId = tenantId;
+        this.externalKey = externalKey;
+        this.apiKey = apiKey;
+        this.apiSecret = apiSecret;
+    }
+
+    public TenantJson(final Tenant tenant) {
+        this(tenant.getId().toString(), tenant.getExternalKey(), tenant.getApiKey(), tenant.getApiSecret());
+    }
+
+    public TenantData toTenantData() {
+        return new TenantData() {
+            @Override
+            public String getExternalKey() {
+                return externalKey;
+            }
+
+            @Override
+            public String getApiKey() {
+                return apiKey;
+            }
+
+            @Override
+            public String getApiSecret() {
+                return apiSecret;
+            }
+        };
+    }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    public String getApiSecret() {
+        return apiSecret;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("TenantJson");
+        sb.append("{tenantId='").append(tenantId).append('\'');
+        sb.append(", externalKey='").append(externalKey).append('\'');
+        sb.append(", apiKey='").append(apiKey).append('\'');
+        sb.append(", apiSecret='").append(apiSecret).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final TenantJson that = (TenantJson) o;
+
+        if (apiKey != null ? !apiKey.equals(that.apiKey) : that.apiKey != null) {
+            return false;
+        }
+        if (apiSecret != null ? !apiSecret.equals(that.apiSecret) : that.apiSecret != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = tenantId != null ? tenantId.hashCode() : 0;
+        result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+        result = 31 * result + (apiKey != null ? apiKey.hashCode() : 0);
+        result = 31 * result + (apiSecret != null ? apiSecret.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 6d186d3..1039683 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -23,6 +23,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -38,8 +39,6 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
-import org.skife.config.Default;
-
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -85,6 +84,8 @@ import com.ning.billing.util.audit.AuditLogsForInvoicePayments;
 import com.ning.billing.util.audit.AuditLogsForInvoices;
 import com.ning.billing.util.audit.AuditLogsForPayments;
 import com.ning.billing.util.audit.AuditLogsForRefunds;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 
@@ -109,7 +110,6 @@ public class AccountResource extends JaxRsResourceBase {
     private final InvoiceUserApi invoiceApi;
     private final InvoicePaymentApi invoicePaymentApi;
     private final PaymentApi paymentApi;
-    private final Context context;
 
     @Inject
     public AccountResource(final JaxrsUriBuilder uriBuilder,
@@ -123,14 +123,13 @@ public class AccountResource extends JaxRsResourceBase {
                            final AuditUserApi auditUserApi,
                            final CustomFieldUserApi customFieldUserApi,
                            final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi);
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.accountApi = accountApi;
         this.entitlementApi = entitlementApi;
         this.invoiceApi = invoiceApi;
         this.invoicePaymentApi = invoicePaymentApi;
         this.paymentApi = paymentApi;
         this.timelineApi = timelineApi;
-        this.context = context;
     }
 
     @GET
@@ -138,26 +137,30 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getAccount(@PathParam("accountId") final String accountId,
                                @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
-                               @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA) throws AccountApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-        return getAccount(account, accountWithBalance, accountWithBalanceAndCBA);
+                               @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final TenantContext tenantContext = context.createContext(request);
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), tenantContext);
+        return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
     }
 
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + BUNDLES)
     @Produces(APPLICATION_JSON)
-    public Response getAccountBundles(@PathParam("accountId") final String accountId, @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey)
-            throws AccountApiException, EntitlementUserApiException {
+    public Response getAccountBundles(@PathParam("accountId") final String accountId,
+                                      @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, EntitlementUserApiException {
+        final TenantContext tenantContext = context.createContext(request);
 
         final UUID uuid = UUID.fromString(accountId);
-        accountApi.getAccountById(uuid);
+        accountApi.getAccountById(uuid, tenantContext);
 
         if (externalKey != null) {
-            final SubscriptionBundle bundle = entitlementApi.getBundleForAccountAndKey(uuid, externalKey);
+            final SubscriptionBundle bundle = entitlementApi.getBundleForAccountAndKey(uuid, externalKey, tenantContext);
             final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
             return Response.status(Status.OK).entity(json).build();
         } else {
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid);
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid, tenantContext);
             final Collection<BundleJsonNoSubscriptions> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJsonNoSubscriptions>() {
                 @Override
                 public BundleJsonNoSubscriptions apply(final SubscriptionBundle input) {
@@ -172,19 +175,21 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
                                     @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
-                                    @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA) throws AccountApiException {
-        final Account account = accountApi.getAccountByKey(externalKey);
-        return getAccount(account, accountWithBalance, accountWithBalanceAndCBA);
+                                    @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final TenantContext tenantContext = context.createContext(request);
+        final Account account = accountApi.getAccountByKey(externalKey, tenantContext);
+        return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
     }
 
-    private Response getAccount(final Account account, final Boolean accountWithBalance, final Boolean accountWithBalanceAndCBA) {
+    private Response getAccount(final Account account, final Boolean accountWithBalance, final Boolean accountWithBalanceAndCBA, final TenantContext tenantContext) {
         final AccountJson json;
         if (accountWithBalanceAndCBA) {
-            final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId());
-            final BigDecimal accountCBA = invoiceApi.getAccountCBA(account.getId());
+            final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId(), tenantContext);
+            final BigDecimal accountCBA = invoiceApi.getAccountCBA(account.getId(), tenantContext);
             json = new AccountJsonWithBalanceAndCBA(account, accountBalance, accountCBA);
         } else if (accountWithBalance) {
-            final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId());
+            final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId(), tenantContext);
             json = new AccountJsonWithBalance(account, accountBalance);
         } else {
             json = new AccountJson(account);
@@ -198,9 +203,10 @@ public class AccountResource extends JaxRsResourceBase {
     public Response createAccount(final AccountJson json,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
-                                  @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+                                  @HeaderParam(HDR_COMMENT) final String comment,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         final AccountData data = json.toAccountData();
-        final Account account = accountApi.createAccount(data, context.createContext(createdBy, reason, comment));
+        final Account account = accountApi.createAccount(data, context.createContext(createdBy, reason, comment, request));
         return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
     }
 
@@ -212,18 +218,20 @@ public class AccountResource extends JaxRsResourceBase {
                                   @PathParam("accountId") final String accountId,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
-                                  @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+                                  @HeaderParam(HDR_COMMENT) final String comment,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         final AccountData data = json.toAccountData();
         final UUID uuid = UUID.fromString(accountId);
-        accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment));
-        return getAccount(accountId, false, false);
+        accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment, request));
+        return getAccount(accountId, false, false, request);
     }
 
     // Not supported
     @DELETE
     @Path("/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response cancelAccount(@PathParam("accountId") final String accountId) {
+    public Response cancelAccount(@PathParam("accountId") final String accountId,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) {
         /*
         try {
             accountApi.cancelAccount(accountId);
@@ -240,41 +248,44 @@ public class AccountResource extends JaxRsResourceBase {
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TIMELINE)
     @Produces(APPLICATION_JSON)
     public Response getAccountTimeline(@PathParam("accountId") final String accountIdString,
-                                       @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode) throws AccountApiException, PaymentApiException, EntitlementRepairException {
+                                       @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException, EntitlementRepairException {
+        final TenantContext tenantContext = context.createContext(request);
+
         final UUID accountId = UUID.fromString(accountIdString);
-        final Account account = accountApi.getAccountById(accountId);
+        final Account account = accountApi.getAccountById(accountId, tenantContext);
 
         // Get the invoices
-        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
-        final AuditLogsForInvoices invoicesAuditLogs = auditUserApi.getAuditLogsForInvoices(invoices, auditMode.getLevel());
+        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), tenantContext);
+        final AuditLogsForInvoices invoicesAuditLogs = auditUserApi.getAuditLogsForInvoices(invoices, auditMode.getLevel(), tenantContext);
 
         // Get the payments
-        final List<Payment> payments = paymentApi.getAccountPayments(accountId);
-        final AuditLogsForPayments paymentsAuditLogs = auditUserApi.getAuditLogsForPayments(payments, auditMode.getLevel());
+        final List<Payment> payments = paymentApi.getAccountPayments(accountId, tenantContext);
+        final AuditLogsForPayments paymentsAuditLogs = auditUserApi.getAuditLogsForPayments(payments, auditMode.getLevel(), tenantContext);
 
         // Get the refunds
-        final List<Refund> refunds = paymentApi.getAccountRefunds(account);
-        final AuditLogsForRefunds refundsAuditLogs = auditUserApi.getAuditLogsForRefunds(refunds, auditMode.getLevel());
+        final List<Refund> refunds = paymentApi.getAccountRefunds(account, tenantContext);
+        final AuditLogsForRefunds refundsAuditLogs = auditUserApi.getAuditLogsForRefunds(refunds, auditMode.getLevel(), tenantContext);
         final Multimap<UUID, Refund> refundsByPayment = ArrayListMultimap.<UUID, Refund>create();
         for (final Refund refund : refunds) {
             refundsByPayment.put(refund.getPaymentId(), refund);
         }
 
         // Get the chargebacks
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(accountId);
-        final AuditLogsForInvoicePayments chargebacksAuditLogs = auditUserApi.getAuditLogsForInvoicePayments(chargebacks, auditMode.getLevel());
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(accountId, tenantContext);
+        final AuditLogsForInvoicePayments chargebacksAuditLogs = auditUserApi.getAuditLogsForInvoicePayments(chargebacks, auditMode.getLevel(), tenantContext);
         final Multimap<UUID, InvoicePayment> chargebacksByPayment = ArrayListMultimap.<UUID, InvoicePayment>create();
         for (final InvoicePayment chargeback : chargebacks) {
             chargebacksByPayment.put(chargeback.getPaymentId(), chargeback);
         }
 
         // Get the bundles
-        final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
+        final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId(), tenantContext);
         final List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
         for (final SubscriptionBundle bundle : bundles) {
-            bundlesTimeline.add(timelineApi.getBundleTimeline(bundle.getId()));
+            bundlesTimeline.add(timelineApi.getBundleTimeline(bundle.getId(), tenantContext));
         }
-        final AuditLogsForBundles bundlesAuditLogs = auditUserApi.getAuditLogsForBundles(bundlesTimeline, auditMode.getLevel());
+        final AuditLogsForBundles bundlesAuditLogs = auditUserApi.getAuditLogsForBundles(bundlesTimeline, auditMode.getLevel(), tenantContext);
 
         final AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline,
                                                                  refundsByPayment, chargebacksByPayment,
@@ -290,8 +301,9 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
     @Produces(APPLICATION_JSON)
-    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountId) throws AccountApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountId,
+                                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), context.createContext(request));
         final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, account.isNotifiedForInvoices());
 
         return Response.status(Status.OK).entity(invoiceEmailJson).build();
@@ -305,13 +317,16 @@ public class AccountResource extends JaxRsResourceBase {
                                                     @PathParam("accountId") final String accountIdString,
                                                     @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                     @HeaderParam(HDR_REASON) final String reason,
-                                                    @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+                                                    @HeaderParam(HDR_COMMENT) final String comment,
+                                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final UUID accountId = UUID.fromString(accountIdString);
-        final Account account = accountApi.getAccountById(accountId);
+        final Account account = accountApi.getAccountById(accountId, callContext);
 
         final MutableAccountData mutableAccountData = account.toMutableAccountData();
         mutableAccountData.setIsNotifiedForInvoices(json.isNotifiedForInvoices());
-        accountApi.updateAccount(accountId, mutableAccountData, context.createContext(createdBy, reason, comment));
+        accountApi.updateAccount(accountId, mutableAccountData, callContext);
 
         return Response.status(Status.OK).build();
     }
@@ -325,8 +340,9 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getPayments(@PathParam("accountId") final String accountId,
                                 @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-                                @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) throws PaymentApiException {
-        final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
+                                @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC,
+                                @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+        final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId), context.createContext(request));
         final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
         for (final Payment payment : payments) {
             result.add(new PaymentJsonSimple(payment));
@@ -343,11 +359,14 @@ public class AccountResource extends JaxRsResourceBase {
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
-                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, PaymentApiException {
+                                        @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final PaymentMethod data = json.toPaymentMethod();
-        final Account account = accountApi.getAccountById(data.getAccountId());
+        final Account account = accountApi.getAccountById(data.getAccountId(), callContext);
 
-        final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
+        final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), callContext);
         return uriBuilder.buildResponse(PaymentMethodResource.class, "getPaymentMethod", paymentMethodId, uriInfo.getBaseUri().toString());
     }
 
@@ -357,9 +376,12 @@ public class AccountResource extends JaxRsResourceBase {
     public Response getPaymentMethods(@PathParam("accountId") final String accountId,
                                       @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                       @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-                                      @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) throws AccountApiException, PaymentApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-        final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
+                                      @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC,
+                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), tenantContext);
+        final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo, tenantContext);
         final List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
             @Override
             public PaymentMethodJson apply(final PaymentMethod input) {
@@ -378,9 +400,12 @@ public class AccountResource extends JaxRsResourceBase {
                                             @PathParam("paymentMethodId") final String paymentMethodId,
                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                             @HeaderParam(HDR_REASON) final String reason,
-                                            @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, PaymentApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-        paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
+                                            @HeaderParam(HDR_COMMENT) final String comment,
+                                            @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), callContext);
+        paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), callContext);
         return Response.status(Status.OK).build();
     }
 
@@ -390,9 +415,12 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + REFUNDS)
     @Produces(APPLICATION_JSON)
-    public Response getRefunds(@PathParam("accountId") final String accountId) throws AccountApiException, PaymentApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-        final List<Refund> refunds = paymentApi.getAccountRefunds(account);
+    public Response getRefunds(@PathParam("accountId") final String accountId,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), tenantContext);
+        final List<Refund> refunds = paymentApi.getAccountRefunds(account, tenantContext);
         final List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
             @Override
             public RefundJson apply(Refund input) {
@@ -411,8 +439,9 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
     @Produces(APPLICATION_JSON)
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id) {
-        return super.getCustomFields(UUID.fromString(id));
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        return super.getCustomFields(UUID.fromString(id), context.createContext(request));
     }
 
     @POST
@@ -423,9 +452,10 @@ public class AccountResource extends JaxRsResourceBase {
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -436,9 +466,10 @@ public class AccountResource extends JaxRsResourceBase {
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     /*
@@ -448,8 +479,10 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TAGS)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id, @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit) throws TagDefinitionApiException {
-        return super.getTags(UUID.fromString(id), withAudit);
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+                            @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit,
+                            @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        return super.getTags(UUID.fromString(id), withAudit, context.createContext(request));
     }
 
     @POST
@@ -460,9 +493,10 @@ public class AccountResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -473,13 +507,15 @@ public class AccountResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException, AccountApiException {
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException, AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         // Look if there is an AUTO_PAY_OFF for that account and check if the account has a default paymentMethod
         // If not we can't remove the AUTO_PAY_OFF tag
         final Collection<UUID> tagDefinitionUUIDs = getTagDefinitionUUIDs(tagList);
         boolean isTagAutoPayOff = false;
-        for (UUID cur : tagDefinitionUUIDs) {
+        for (final UUID cur : tagDefinitionUUIDs) {
             if (cur.equals(ControlTagType.AUTO_PAY_OFF.getId())) {
                 isTagAutoPayOff = true;
                 break;
@@ -487,14 +523,13 @@ public class AccountResource extends JaxRsResourceBase {
         }
         final UUID accountId = UUID.fromString(id);
         if (isTagAutoPayOff) {
-            final Account account = accountApi.getAccountById(accountId);
+            final Account account = accountApi.getAccountById(accountId, callContext);
             if (account.getPaymentMethodId() == null) {
                 throw new TagApiException(ErrorCode.TAG_CANNOT_BE_REMOVED, ControlTagType.AUTO_PAY_OFF, " the account does not have a default payment method");
             }
         }
 
-        return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+        return super.deleteTags(UUID.fromString(id), tagList, callContext);
     }
 
     /*
@@ -504,9 +539,10 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAILS)
     @Produces(APPLICATION_JSON)
-    public Response getEmails(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getEmails(@PathParam(ID_PARAM_NAME) final String id,
+                              @javax.ws.rs.core.Context final HttpServletRequest request) {
         final UUID accountId = UUID.fromString(id);
-        final List<AccountEmail> emails = accountApi.getEmails(accountId);
+        final List<AccountEmail> emails = accountApi.getEmails(accountId, context.createContext(request));
 
         final List<AccountEmailJson> emailsJson = new ArrayList<AccountEmailJson>();
         for (final AccountEmail email : emails) {
@@ -523,13 +559,16 @@ public class AccountResource extends JaxRsResourceBase {
                              @PathParam(ID_PARAM_NAME) final String id,
                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                              @HeaderParam(HDR_REASON) final String reason,
-                             @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+                             @HeaderParam(HDR_COMMENT) final String comment,
+                             @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final UUID accountId = UUID.fromString(id);
 
         // Make sure the account exist or we will confuse the history and auditing code
-        accountApi.getAccountById(accountId);
+        accountApi.getAccountById(accountId, callContext);
 
-        accountApi.addEmail(accountId, json.toAccountEmail(), context.createContext(createdBy, reason, comment));
+        accountApi.addEmail(accountId, json.toAccountEmail(), callContext);
 
         return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
     }
@@ -541,11 +580,12 @@ public class AccountResource extends JaxRsResourceBase {
                                 @PathParam("email") final String email,
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                 @HeaderParam(HDR_REASON) final String reason,
-                                @HeaderParam(HDR_COMMENT) final String comment) {
+                                @HeaderParam(HDR_COMMENT) final String comment,
+                                @javax.ws.rs.core.Context final HttpServletRequest request) {
         final UUID accountId = UUID.fromString(id);
         final AccountEmailJson accountEmailJson = new AccountEmailJson(id, email);
         final AccountEmail accountEmail = accountEmailJson.toAccountEmail();
-        accountApi.removeEmail(accountId, accountEmail, context.createContext(createdBy, reason, comment));
+        accountApi.removeEmail(accountId, accountEmail, context.createContext(createdBy, reason, comment, request));
 
         return Response.status(Status.OK).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
index f0df8ac..e8c871e 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
@@ -17,6 +17,7 @@
 package com.ning.billing.jaxrs.resources;
 
 import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -27,6 +28,11 @@ import javax.ws.rs.core.Response.Status;
 import com.ning.billing.analytics.api.TimeSeriesData;
 import com.ning.billing.analytics.api.user.AnalyticsUserApi;
 import com.ning.billing.jaxrs.json.TimeSeriesDataJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
 
 import com.google.inject.Singleton;
 
@@ -34,20 +40,26 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.ANALYTICS_PATH)
-public class AnalyticsResource {
+public class AnalyticsResource extends JaxRsResourceBase {
 
     private final AnalyticsUserApi analyticsUserApi;
 
     @Inject
-    public AnalyticsResource(final AnalyticsUserApi analyticsUserApi) {
+    public AnalyticsResource(final AnalyticsUserApi analyticsUserApi,
+                             final JaxrsUriBuilder uriBuilder,
+                             final TagUserApi tagUserApi,
+                             final CustomFieldUserApi customFieldUserApi,
+                             final AuditUserApi auditUserApi,
+                             final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.analyticsUserApi = analyticsUserApi;
     }
 
     @GET
     @Path("/accountsCreatedOverTime")
     @Produces(APPLICATION_JSON)
-    public Response getAccountsCreatedOverTime() {
-        final TimeSeriesData data = analyticsUserApi.getAccountsCreatedOverTime();
+    public Response getAccountsCreatedOverTime(@javax.ws.rs.core.Context final HttpServletRequest request) {
+        final TimeSeriesData data = analyticsUserApi.getAccountsCreatedOverTime(context.createContext(request));
         final TimeSeriesDataJson json = new TimeSeriesDataJson(data);
         return Response.status(Status.OK).entity(json).build();
     }
@@ -56,8 +68,9 @@ public class AnalyticsResource {
     @Path("/subscriptionsCreatedOverTime")
     @Produces(APPLICATION_JSON)
     public Response getSubscriptionsCreatedOverTime(@QueryParam("productType") final String productType,
-                                                    @QueryParam("slug") final String slug) {
-        final TimeSeriesData data = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, slug);
+                                                    @QueryParam("slug") final String slug,
+                                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        final TimeSeriesData data = analyticsUserApi.getSubscriptionsCreatedOverTime(productType, slug, context.createContext(request));
         final TimeSeriesDataJson json = new TimeSeriesDataJson(data);
         return Response.status(Status.OK).entity(json).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
index 6ab3239..13880d3 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -20,6 +20,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -48,10 +49,13 @@ import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.common.base.Function;
@@ -69,28 +73,26 @@ public class BundleResource extends JaxRsResourceBase {
 
     private final EntitlementUserApi entitlementApi;
     private final EntitlementTransferApi transferApi;
-    private final Context context;
-    private final JaxrsUriBuilder uriBuilder;
 
     @Inject
-    public BundleResource(final JaxrsUriBuilder uriBuilder,
-                          final EntitlementUserApi entitlementApi,
+    public BundleResource(final EntitlementUserApi entitlementApi,
                           final EntitlementTransferApi transferApi,
+                          final JaxrsUriBuilder uriBuilder,
                           final TagUserApi tagUserApi,
                           final CustomFieldUserApi customFieldUserApi,
+                          final AuditUserApi auditUserApi,
                           final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
-        this.uriBuilder = uriBuilder;
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.entitlementApi = entitlementApi;
         this.transferApi = transferApi;
-        this.context = context;
     }
 
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getBundle(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
+    public Response getBundle(@PathParam("bundleId") final String bundleId,
+                              @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId), context.createContext(request));
         final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
         return Response.status(Status.OK).entity(json).build();
     }
@@ -101,23 +103,26 @@ public class BundleResource extends JaxRsResourceBase {
     public Response createBundle(final BundleJsonNoSubscriptions json,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
-                                 @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+                                 @HeaderParam(HDR_COMMENT) final String comment,
+                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
         final UUID accountId = UUID.fromString(json.getAccountId());
         final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(),
-                                                                                context.createContext(createdBy, reason, comment));
+                                                                                context.createContext(createdBy, reason, comment, request));
         return uriBuilder.buildResponse(BundleResource.class, "getBundle", bundle.getId());
     }
 
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + SUBSCRIPTIONS)
     @Produces(APPLICATION_JSON)
-    public Response getBundleSubscriptions(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
+    public Response getBundleSubscriptions(@PathParam("bundleId") final String bundleId,
+                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
+        final TenantContext tenantContext = context.createContext(request);
         final UUID uuid = UUID.fromString(bundleId);
-        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid);
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid, tenantContext);
         if (bundle == null) {
             return Response.status(Status.NO_CONTENT).build();
         }
-        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(uuid);
+        final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(uuid, tenantContext);
         final Collection<SubscriptionJsonNoEvents> result = Collections2.transform(subscriptions, new Function<Subscription, SubscriptionJsonNoEvents>() {
             @Override
             public SubscriptionJsonNoEvents apply(final Subscription input) {
@@ -130,8 +135,9 @@ public class BundleResource extends JaxRsResourceBase {
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id) {
-        return super.getCustomFields(UUID.fromString(id));
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        return super.getCustomFields(UUID.fromString(id), context.createContext(request));
     }
 
     @POST
@@ -142,9 +148,10 @@ public class BundleResource extends JaxRsResourceBase {
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -155,16 +162,19 @@ public class BundleResource extends JaxRsResourceBase {
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id, @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit) throws TagDefinitionApiException {
-        return super.getTags(UUID.fromString(id), withAudit);
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+                            @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit,
+                            @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        return super.getTags(UUID.fromString(id), withAudit, context.createContext(request));
     }
 
     @PUT
@@ -179,12 +189,13 @@ public class BundleResource extends JaxRsResourceBase {
                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                    @HeaderParam(HDR_REASON) final String reason,
                                    @HeaderParam(HDR_COMMENT) final String comment,
-                                   @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementUserApiException, EntitlementTransferApiException {
-
-        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(id));
+                                   @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException, EntitlementTransferApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(id), callContext);
         final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
         final SubscriptionBundle newBundle = transferApi.transferBundle(bundle.getAccountId(), UUID.fromString(json.getAccountId()), bundle.getKey(), inputDate, transferAddOn,
-                                                                        cancelImmediatley, context.createContext(createdBy, reason, comment));
+                                                                        cancelImmediatley, callContext);
 
         return uriBuilder.buildResponse(BundleResource.class, "getBundle", newBundle.getId(), uriInfo.getBaseUri().toString());
     }
@@ -198,9 +209,10 @@ public class BundleResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -211,9 +223,10 @@ public class BundleResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
index dbd8ff4..e709110 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
@@ -16,12 +16,10 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.APPLICATION_XML;
-
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -29,37 +27,52 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Listing;
 import com.ning.billing.catalog.api.StaticCatalog;
 import com.ning.billing.jaxrs.json.CatalogJsonSimple;
 import com.ning.billing.jaxrs.json.PlanDetailJason;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.config.XMLWriter;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+
 @Singleton
 @Path(JaxrsResource.CATALOG_PATH)
-public class CatalogResource implements JaxrsResource {
+public class CatalogResource extends JaxRsResourceBase {
 
     private final CatalogService catalogService;
 
     @Inject
-    public CatalogResource(final CatalogService catalogService) {
+    public CatalogResource(final CatalogService catalogService,
+                           final JaxrsUriBuilder uriBuilder,
+                           final TagUserApi tagUserApi,
+                           final CustomFieldUserApi customFieldUserApi,
+                           final AuditUserApi auditUserApi,
+                           final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.catalogService = catalogService;
     }
 
     @GET
     @Produces(APPLICATION_XML)
-    public Response getCatalogXml() throws Exception {
+    public Response getCatalogXml(@javax.ws.rs.core.Context final HttpServletRequest request) throws Exception {
         return Response.status(Status.OK).entity(XMLWriter.writeXML(catalogService.getCurrentCatalog(), StaticCatalog.class)).build();
     }
 
     @GET
     @Produces(APPLICATION_JSON)
-    public Response getCatalogJson() throws Exception {
-        StaticCatalog catalog = catalogService.getCurrentCatalog();
+    public Response getCatalogJson(@javax.ws.rs.core.Context final HttpServletRequest request) throws Exception {
+        final StaticCatalog catalog = catalogService.getCurrentCatalog();
 
         return Response.status(Status.OK).entity(catalog).build();
     }
@@ -78,11 +91,11 @@ public class CatalogResource implements JaxrsResource {
     //        return result;
     //    }
 
-
     @GET
     @Path("/availableAddons")
     @Produces(APPLICATION_JSON)
-    public Response getAvailableAddons(@QueryParam("baseProductName") final String baseProductName) throws CatalogApiException {
+    public Response getAvailableAddons(@QueryParam("baseProductName") final String baseProductName,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CatalogApiException {
         final StaticCatalog catalog = catalogService.getCurrentCatalog();
         final List<Listing> listings = catalog.getAvailableAddonListings(baseProductName);
         final List<PlanDetailJason> details = new ArrayList<PlanDetailJason>();
@@ -95,7 +108,7 @@ public class CatalogResource implements JaxrsResource {
     @GET
     @Path("/availableBasePlans")
     @Produces(APPLICATION_JSON)
-    public Response getAvailableBasePlans() throws CatalogApiException {
+    public Response getAvailableBasePlans(@javax.ws.rs.core.Context final HttpServletRequest request) throws CatalogApiException {
         final StaticCatalog catalog = catalogService.getCurrentCatalog();
         final List<Listing> listings = catalog.getAvailableBasePlanListings();
         final List<PlanDetailJason> details = new ArrayList<PlanDetailJason>();
@@ -108,11 +121,10 @@ public class CatalogResource implements JaxrsResource {
     @GET
     @Path("/simpleCatalog")
     @Produces(APPLICATION_JSON)
-    public Response getSimpleCatalog() throws CatalogApiException {
-
-        StaticCatalog catalog  = catalogService.getCurrentCatalog();
+    public Response getSimpleCatalog(@javax.ws.rs.core.Context final HttpServletRequest request) throws CatalogApiException {
+        final StaticCatalog catalog = catalogService.getCurrentCatalog();
 
-        CatalogJsonSimple json = new CatalogJsonSimple(catalog);
+        final CatalogJsonSimple json = new CatalogJsonSimple(catalog);
         return Response.status(Status.OK).entity(json).build();
     }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
index 9deb48d..b302360 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
@@ -37,8 +38,11 @@ import com.ning.billing.jaxrs.json.ChargebackCollectionJson;
 import com.ning.billing.jaxrs.json.ChargebackJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.inject.Inject;
@@ -51,24 +55,24 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 public class ChargebackResource extends JaxRsResourceBase {
 
     private final InvoicePaymentApi invoicePaymentApi;
-    private final Context context;
 
     @Inject
-    public ChargebackResource(final JaxrsUriBuilder uriBuilder,
-                              final InvoicePaymentApi invoicePaymentApi,
+    public ChargebackResource(final InvoicePaymentApi invoicePaymentApi,
+                              final JaxrsUriBuilder uriBuilder,
                               final TagUserApi tagUserApi,
                               final CustomFieldUserApi customFieldUserApi,
+                              final AuditUserApi auditUserApi,
                               final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.invoicePaymentApi = invoicePaymentApi;
-        this.context = context;
     }
 
     @GET
     @Path("/{chargebackId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getChargeback(@PathParam("chargebackId") final String chargebackId) throws InvoiceApiException {
-        final InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId));
+    public Response getChargeback(@PathParam("chargebackId") final String chargebackId,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+        final InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId), context.createContext(request));
         final ChargebackJson chargebackJson = new ChargebackJson(chargeback);
 
         return Response.status(Response.Status.OK).entity(chargebackJson).build();
@@ -77,8 +81,9 @@ public class ChargebackResource extends JaxRsResourceBase {
     @GET
     @Path("/accounts/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForAccount(@PathParam("accountId") final String accountId) {
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.fromString(accountId));
+    public Response getForAccount(@PathParam("accountId") final String accountId,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) {
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.fromString(accountId), context.createContext(request));
         final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
 
         final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
@@ -88,14 +93,17 @@ public class ChargebackResource extends JaxRsResourceBase {
     @GET
     @Path("/payments/{paymentId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForPayment(@PathParam("paymentId") final String paymentId) throws InvoiceApiException {
-        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.fromString(paymentId));
+    public Response getForPayment(@PathParam("paymentId") final String paymentId,
+                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.fromString(paymentId), tenantContext);
         if (chargebacks.size() == 0) {
             return Response.status(Response.Status.NO_CONTENT).build();
         }
 
         final UUID invoicePaymentId = chargebacks.get(0).getId();
-        final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(invoicePaymentId).toString();
+        final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(invoicePaymentId, tenantContext).toString();
         final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
         final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
 
@@ -108,14 +116,16 @@ public class ChargebackResource extends JaxRsResourceBase {
     public Response createChargeback(final ChargebackJson json,
                                      @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                      @HeaderParam(HDR_REASON) final String reason,
-                                     @HeaderParam(HDR_COMMENT) final String comment) throws InvoiceApiException {
-        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(UUID.fromString(json.getPaymentId()));
+                                     @HeaderParam(HDR_COMMENT) final String comment,
+                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(UUID.fromString(json.getPaymentId()), callContext);
         if (invoicePayment == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, json.getPaymentId());
         }
-
         final InvoicePayment chargeBack = invoicePaymentApi.createChargeback(invoicePayment.getId(), json.getChargebackAmount(),
-                                                                             context.createContext(createdBy, reason, comment));
+                                                                             callContext);
         return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", chargeBack.getId());
     }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
index 6ce38af..08286d9 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -18,6 +18,7 @@ package com.ning.billing.jaxrs.resources;
 
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
@@ -38,8 +39,11 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.jaxrs.json.CreditJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.inject.Inject;
@@ -53,27 +57,28 @@ public class CreditResource extends JaxRsResourceBase {
 
     private final InvoiceUserApi invoiceUserApi;
     private final AccountUserApi accountUserApi;
-    private final Context context;
 
     @Inject
-    public CreditResource(final JaxrsUriBuilder uriBuilder,
-                          final InvoiceUserApi invoiceUserApi,
+    public CreditResource(final InvoiceUserApi invoiceUserApi,
                           final AccountUserApi accountUserApi,
+                          final JaxrsUriBuilder uriBuilder,
                           final TagUserApi tagUserApi,
                           final CustomFieldUserApi customFieldUserApi,
+                          final AuditUserApi auditUserApi,
                           final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.invoiceUserApi = invoiceUserApi;
         this.accountUserApi = accountUserApi;
-        this.context = context;
     }
 
     @GET
     @Path("/{creditId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getCredit(@PathParam("creditId") final String creditId) throws InvoiceApiException, AccountApiException {
-        final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
-        final Account account = accountUserApi.getAccountById(credit.getAccountId());
+    public Response getCredit(@PathParam("creditId") final String creditId,
+                              @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException, AccountApiException {
+        final TenantContext tenantContext = context.createContext(request);
+        final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId), tenantContext);
+        final Account account = accountUserApi.getAccountById(credit.getAccountId(), tenantContext);
         final CreditJson creditJson = new CreditJson(credit, account.getTimeZone());
         return Response.status(Response.Status.OK).entity(creditJson).build();
     }
@@ -84,19 +89,22 @@ public class CreditResource extends JaxRsResourceBase {
     public Response createCredit(final CreditJson json,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
-                                 @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
-        final Account account = accountUserApi.getAccountById(UUID.fromString(json.getAccountId()));
+                                 @HeaderParam(HDR_COMMENT) final String comment,
+                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountUserApi.getAccountById(UUID.fromString(json.getAccountId()), callContext);
         final LocalDate effectiveDate = json.getEffectiveDate().toDateTime(account.getTimeZone()).toLocalDate();
 
         final InvoiceItem credit;
         if (json.getInvoiceId() != null) {
             // Apply an invoice level credit
             credit = invoiceUserApi.insertCreditForInvoice(account.getId(), UUID.fromString(json.getInvoiceId()), json.getCreditAmount(),
-                                                           effectiveDate, account.getCurrency(), context.createContext(createdBy, reason, comment));
+                                                           effectiveDate, account.getCurrency(), callContext);
         } else {
             // Apply a account level credit
             credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), effectiveDate,
-                                                 account.getCurrency(), context.createContext(createdBy, reason, comment));
+                                                 account.getCurrency(), callContext);
         }
 
         return uriBuilder.buildResponse(CreditResource.class, "getCredit", credit.getId());
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 0f3531b..5b3b0dc 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -23,6 +23,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -62,11 +63,13 @@ import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
 
@@ -87,8 +90,6 @@ public class InvoiceResource extends JaxRsResourceBase {
     private final AccountUserApi accountApi;
     private final InvoiceUserApi invoiceApi;
     private final PaymentApi paymentApi;
-    private final Context context;
-    private final JaxrsUriBuilder uriBuilder;
     private final InvoiceNotifier invoiceNotifier;
     private final Clock clock;
 
@@ -96,18 +97,17 @@ public class InvoiceResource extends JaxRsResourceBase {
     public InvoiceResource(final AccountUserApi accountApi,
                            final InvoiceUserApi invoiceApi,
                            final PaymentApi paymentApi,
-                           final Context context,
+                           final InvoiceNotifier invoiceNotifier,
+                           final Clock clock,
                            final JaxrsUriBuilder uriBuilder,
                            final TagUserApi tagUserApi,
                            final CustomFieldUserApi customFieldUserApi,
-                           final InvoiceNotifier invoiceNotifier,
-                           final Clock clock) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+                           final AuditUserApi auditUserApi,
+                           final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.accountApi = accountApi;
         this.invoiceApi = invoiceApi;
         this.paymentApi = paymentApi;
-        this.context = context;
-        this.uriBuilder = uriBuilder;
         this.invoiceNotifier = invoiceNotifier;
         this.clock = clock;
     }
@@ -115,11 +115,14 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Produces(APPLICATION_JSON)
     public Response getInvoices(@QueryParam(QUERY_ACCOUNT_ID) final String accountId,
-                                @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems) throws AccountApiException {
+                                @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems,
+                                @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
         // Verify the account exists
-        accountApi.getAccountById(UUID.fromString(accountId));
+        accountApi.getAccountById(UUID.fromString(accountId), tenantContext);
 
-        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
+        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId), tenantContext);
         if (withItems) {
             final List<InvoiceJsonWithItems> result = new LinkedList<InvoiceJsonWithItems>();
             for (final Invoice invoice : invoices) {
@@ -141,8 +144,9 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Path("/{invoiceId:" + UUID_PATTERN + "}/")
     @Produces(APPLICATION_JSON)
     public Response getInvoice(@PathParam("invoiceId") final String invoiceId,
-                               @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems) throws InvoiceApiException {
-        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
+                               @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId), context.createContext(request));
         if (invoice == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
         } else {
@@ -154,8 +158,9 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Path("/{invoiceId:" + UUID_PATTERN + "}/html")
     @Produces(TEXT_HTML)
-    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId) throws InvoiceApiException, IOException, AccountApiException {
-        return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId))).build();
+    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId,
+                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException, IOException, AccountApiException {
+        return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId), context.createContext(request))).build();
     }
 
     @POST
@@ -166,14 +171,17 @@ public class InvoiceResource extends JaxRsResourceBase {
                                         @QueryParam(QUERY_DRY_RUN) @DefaultValue("false") final Boolean dryRun,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), callContext);
 
         final DateTime inputDateTime = DATE_TIME_FORMATTER.parseDateTime(targetDateTime);
         final LocalDate inputDate = inputDateTime.toDateTime(account.getTimeZone()).toLocalDate();
 
         final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun,
-                                                                             context.createContext(createdBy, reason, comment));
+                                                                             callContext);
         if (dryRun) {
             return Response.status(Status.OK).entity(new InvoiceJsonSimple(generatedInvoice)).build();
         } else {
@@ -190,11 +198,13 @@ public class InvoiceResource extends JaxRsResourceBase {
                               @QueryParam(QUERY_ACCOUNT_ID) final String accountId,
                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
                               @HeaderParam(HDR_REASON) final String reason,
-                              @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+                              @HeaderParam(HDR_COMMENT) final String comment,
+                              @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
-        invoiceApi.deleteCBA(account.getId(), UUID.fromString(invoiceId), UUID.fromString(invoiceItemId),
-                             context.createContext(createdBy, reason, comment));
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), callContext);
+
+        invoiceApi.deleteCBA(account.getId(), UUID.fromString(invoiceId), UUID.fromString(invoiceItemId), callContext);
 
         return Response.status(Status.OK).build();
     }
@@ -208,8 +218,11 @@ public class InvoiceResource extends JaxRsResourceBase {
                                       @QueryParam(QUERY_REQUESTED_DT) final String requestedDateTimeString,
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                       @HeaderParam(HDR_REASON) final String reason,
-                                      @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(json.getAccountId()));
+                                      @HeaderParam(HDR_COMMENT) final String comment,
+                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(json.getAccountId()), callContext);
 
         // Get the effective date of the adjustment, in the account timezone
         final LocalDate requestedDate;
@@ -226,7 +239,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     UUID.fromString(invoiceId),
                                                                     UUID.fromString(json.getInvoiceItemId()),
                                                                     requestedDate,
-                                                                    context.createContext(createdBy, reason, comment));
+                                                                    callContext);
         } else {
             adjustmentItem = invoiceApi.insertInvoiceItemAdjustment(account.getId(),
                                                                     UUID.fromString(invoiceId),
@@ -234,7 +247,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     requestedDate,
                                                                     json.getAmount(),
                                                                     json.getCurrency(),
-                                                                    context.createContext(createdBy, reason, comment));
+                                                                    callContext);
         }
 
         return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId());
@@ -249,9 +262,11 @@ public class InvoiceResource extends JaxRsResourceBase {
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                          @HeaderParam(HDR_REASON) final String reason,
                                          @HeaderParam(HDR_COMMENT) final String comment,
-                                         @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(externalChargeJson.getAccountId()));
-        final CallContext callContext = context.createContext(createdBy, reason, comment);
+                                         @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(externalChargeJson.getAccountId()), callContext);
 
         // Get the effective date of the external charge, in the account timezone
         final LocalDate requestedDate;
@@ -287,9 +302,11 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                    @HeaderParam(HDR_REASON) final String reason,
                                                    @HeaderParam(HDR_COMMENT) final String comment,
-                                                   @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(externalChargeJson.getAccountId()));
-        final CallContext callContext = context.createContext(createdBy, reason, comment);
+                                                   @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(externalChargeJson.getAccountId()), callContext);
 
         // Get the effective date of the external charge, in the account timezone
         final LocalDate requestedDate;
@@ -319,8 +336,9 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Path("/{invoiceId:" + UUID_PATTERN + "}/" + PAYMENTS)
     @Produces(APPLICATION_JSON)
-    public Response getPayments(@PathParam("invoiceId") final String invoiceId) throws PaymentApiException {
-        final List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId));
+    public Response getPayments(@PathParam("invoiceId") final String invoiceId,
+                                @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+        final List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId), context.createContext(request));
 
         final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
         for (final Payment cur : payments) {
@@ -338,11 +356,13 @@ public class InvoiceResource extends JaxRsResourceBase {
                                    @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                    @HeaderParam(HDR_REASON) final String reason,
-                                   @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, PaymentApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
+                                   @HeaderParam(HDR_COMMENT) final String comment,
+                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()), callContext);
 
-        final CallContext callContext = context.createContext(createdBy, reason, comment);
-        final Collection<Invoice> unpaidInvoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday());
+        final Collection<Invoice> unpaidInvoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
         for (final Invoice invoice : unpaidInvoices) {
             if (externalPayment) {
                 paymentApi.createExternalPayment(account, invoice.getId(), invoice.getBalance(), callContext);
@@ -362,11 +382,13 @@ public class InvoiceResource extends JaxRsResourceBase {
                                          @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                          @HeaderParam(HDR_REASON) final String reason,
-                                         @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, PaymentApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
+                                         @HeaderParam(HDR_COMMENT) final String comment,
+                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()), callContext);
 
         final UUID invoiceId = UUID.fromString(payment.getInvoiceId());
-        final CallContext callContext = context.createContext(createdBy, reason, comment);
         if (externalPayment) {
             paymentApi.createExternalPayment(account, invoiceId, payment.getAmount(), callContext);
         } else {
@@ -383,16 +405,19 @@ public class InvoiceResource extends JaxRsResourceBase {
     public Response triggerEmailNotificationForInvoice(@PathParam("invoiceId") final String invoiceId,
                                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                        @HeaderParam(HDR_REASON) final String reason,
-                                                       @HeaderParam(HDR_COMMENT) final String comment) throws InvoiceApiException, AccountApiException {
-        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
+                                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException, AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId), callContext);
         if (invoice == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
         }
 
-        final Account account = accountApi.getAccountById(invoice.getAccountId());
+        final Account account = accountApi.getAccountById(invoice.getAccountId(), callContext);
 
         // Send the email (synchronous send)
-        invoiceNotifier.notify(account, invoice);
+        invoiceNotifier.notify(account, invoice, callContext);
 
         return Response.status(Status.OK).build();
     }
@@ -400,8 +425,9 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Path(CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id) {
-        return super.getCustomFields(UUID.fromString(id));
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        return super.getCustomFields(UUID.fromString(id), context.createContext(request));
     }
 
     @POST
@@ -412,9 +438,10 @@ public class InvoiceResource extends JaxRsResourceBase {
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -425,16 +452,19 @@ public class InvoiceResource extends JaxRsResourceBase {
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id, @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit) throws TagDefinitionApiException {
-        return super.getTags(UUID.fromString(id), withAudit);
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+                            @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit,
+                            @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        return super.getTags(UUID.fromString(id), withAudit, context.createContext(request));
     }
 
     @POST
@@ -446,9 +476,10 @@ public class InvoiceResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -459,9 +490,10 @@ public class InvoiceResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index 9c8af32..e89acbe 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -43,6 +43,7 @@ public interface JaxrsResource {
      * Query parameters
      */
     public static final String QUERY_EXTERNAL_KEY = "externalKey";
+    public static final String QUERY_API_KEY = "apiKey";
     public static final String QUERY_REQUESTED_DT = "requestedDate";
     public static final String QUERY_CALL_COMPLETION = "callCompletion";
     public static final String QUERY_CALL_TIMEOUT = "callTimeoutSec";
@@ -122,4 +123,7 @@ public interface JaxrsResource {
 
     public static final String OVERDUE = "overdue";
     public static final String OVERDUE_PATH = PREFIX + "/" + OVERDUE;
+
+    public static final String TENANTS = "tenants";
+    public static final String TENANTS_PATH = PREFIX + "/" + TENANTS;
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
index 1f08c34..071c300 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.TagJson;
+import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
@@ -42,6 +43,7 @@ import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.customfield.StringCustomField;
 import com.ning.billing.util.dao.ObjectType;
@@ -60,29 +62,28 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     protected final TagUserApi tagUserApi;
     protected final CustomFieldUserApi customFieldUserApi;
     protected final AuditUserApi auditUserApi;
+    protected final Context context;
 
     protected final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTimeParser();
 
     public JaxRsResourceBase(final JaxrsUriBuilder uriBuilder,
                              final TagUserApi tagUserApi,
                              final CustomFieldUserApi customFieldUserApi,
-                             final AuditUserApi auditUserApi) {
+                             final AuditUserApi auditUserApi,
+                             final Context context) {
         this.uriBuilder = uriBuilder;
         this.tagUserApi = tagUserApi;
         this.customFieldUserApi = customFieldUserApi;
         this.auditUserApi = auditUserApi;
+        this.context = context;
     }
 
-    protected abstract ObjectType getObjectType();
-
-    public JaxRsResourceBase(final JaxrsUriBuilder uriBuilder,
-                             final TagUserApi tagUserApi,
-                             final CustomFieldUserApi customFieldUserApi) {
-        this(uriBuilder, tagUserApi, customFieldUserApi, null);
+    protected ObjectType getObjectType() {
+        return null;
     }
 
-    protected Response getTags(final UUID id, final boolean withAudit) throws TagDefinitionApiException {
-        final Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType());
+    protected Response getTags(final UUID id, final boolean withAudit, final TenantContext context) throws TagDefinitionApiException {
+        final Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType(), context);
         final Collection<UUID> tagIdList = (tags.size() == 0) ?
                                            Collections.<UUID>emptyList() :
                                            Collections2.transform(tags.values(), new Function<Tag, UUID>() {
@@ -93,12 +94,12 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
                                            });
 
         final AtomicReference<TagDefinitionApiException> theException = new AtomicReference<TagDefinitionApiException>();
-        final List<TagDefinition> tagDefinitionList = tagUserApi.getTagDefinitions(tagIdList);
+        final List<TagDefinition> tagDefinitionList = tagUserApi.getTagDefinitions(tagIdList, context);
         final List<TagJson> result = ImmutableList.<TagJson>copyOf(Collections2.transform(tagIdList, new Function<UUID, TagJson>() {
             @Override
-            public TagJson apply(UUID input) {
+            public TagJson apply(final UUID input) {
                 try {
-                final TagDefinition tagDefinition = findTagDefinitionFromId(tagDefinitionList, input);
+                    final TagDefinition tagDefinition = findTagDefinitionFromId(tagDefinitionList, input);
                     return new TagJson(input.toString(), tagDefinition.getName(), null);
                 } catch (TagDefinitionApiException e) {
                     theException.set(e);
@@ -151,8 +152,8 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         return Response.status(Response.Status.OK).build();
     }
 
-    protected Response getCustomFields(final UUID id) {
-        final Map<String, CustomField> fields = customFieldUserApi.getCustomFields(id, getObjectType());
+    protected Response getCustomFields(final UUID id, final TenantContext context) {
+        final Map<String, CustomField> fields = customFieldUserApi.getCustomFields(id, getObjectType(), context);
 
         final List<CustomFieldJson> result = new LinkedList<CustomFieldJson>();
         for (final CustomField cur : fields.values()) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/OverdueResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/OverdueResource.java
index 3fcc1fc..ace8be3 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/OverdueResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/OverdueResource.java
@@ -18,6 +18,7 @@ package com.ning.billing.jaxrs.resources;
 
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -33,10 +34,16 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.jaxrs.json.OverdueStateJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.OverdueUserApi;
 import com.ning.billing.overdue.config.api.OverdueException;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.TenantContext;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -45,7 +52,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.OVERDUE_PATH)
-public class OverdueResource implements JaxrsResource {
+public class OverdueResource extends JaxRsResourceBase {
 
     private final OverdueUserApi overdueApi;
     private final AccountUserApi accountApi;
@@ -54,7 +61,13 @@ public class OverdueResource implements JaxrsResource {
     @Inject
     public OverdueResource(final OverdueUserApi overdueApi,
                            final AccountUserApi accountApi,
-                           final EntitlementUserApi entitlementApi) {
+                           final EntitlementUserApi entitlementApi,
+                           final JaxrsUriBuilder uriBuilder,
+                           final TagUserApi tagUserApi,
+                           final CustomFieldUserApi customFieldUserApi,
+                           final AuditUserApi auditUserApi,
+                           final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.overdueApi = overdueApi;
         this.accountApi = accountApi;
         this.entitlementApi = entitlementApi;
@@ -63,9 +76,12 @@ public class OverdueResource implements JaxrsResource {
     @GET
     @Path("/" + ACCOUNTS + "/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getOverdueAccount(@PathParam("accountId") final String accountId) throws AccountApiException, OverdueException, OverdueApiException {
-        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-        final OverdueState<Account> overdueState = overdueApi.getOverdueStateFor(account);
+    public Response getOverdueAccount(@PathParam("accountId") final String accountId,
+                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, OverdueException, OverdueApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId), tenantContext);
+        final OverdueState<Account> overdueState = overdueApi.getOverdueStateFor(account, tenantContext);
 
         return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
     }
@@ -73,9 +89,12 @@ public class OverdueResource implements JaxrsResource {
     @GET
     @Path("/" + BUNDLES + "/{bundleId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getOverdueBundle(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException, OverdueException, OverdueApiException {
-        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
-        final OverdueState<SubscriptionBundle> overdueState = overdueApi.getOverdueStateFor(bundle);
+    public Response getOverdueBundle(@PathParam("bundleId") final String bundleId,
+                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException, OverdueException, OverdueApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId), tenantContext);
+        final OverdueState<SubscriptionBundle> overdueState = overdueApi.getOverdueStateFor(bundle, tenantContext);
 
         return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
     }
@@ -83,9 +102,12 @@ public class OverdueResource implements JaxrsResource {
     @GET
     @Path("/" + SUBSCRIPTIONS + "/{subscriptionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getOverdueSubscription(@PathParam("subscriptionId") final String subscriptionId) throws EntitlementUserApiException, OverdueException, OverdueApiException {
-        final Subscription subscription = entitlementApi.getSubscriptionFromId(UUID.fromString(subscriptionId));
-        final OverdueState<Subscription> overdueState = overdueApi.getOverdueStateFor(subscription);
+    public Response getOverdueSubscription(@PathParam("subscriptionId") final String subscriptionId,
+                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException, OverdueException, OverdueApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        final Subscription subscription = entitlementApi.getSubscriptionFromId(UUID.fromString(subscriptionId), tenantContext);
+        final OverdueState<Subscription> overdueState = overdueApi.getOverdueStateFor(subscription, tenantContext);
 
         return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
index 15d014b..7008bd5 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
@@ -18,6 +18,7 @@ package com.ning.billing.jaxrs.resources;
 
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -40,8 +41,11 @@ import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.inject.Inject;
@@ -55,30 +59,32 @@ public class PaymentMethodResource extends JaxRsResourceBase {
 
     private final PaymentApi paymentApi;
     private final AccountUserApi accountApi;
-    private final Context context;
 
     @Inject
-    public PaymentMethodResource(final JaxrsUriBuilder uriBuilder,
+    public PaymentMethodResource(final PaymentApi paymentApi,
                                  final AccountUserApi accountApi,
-                                 final PaymentApi paymentApi,
+                                 final JaxrsUriBuilder uriBuilder,
                                  final TagUserApi tagUserApi,
                                  final CustomFieldUserApi customFieldUserApi,
+                                 final AuditUserApi auditUserApi,
                                  final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.paymentApi = paymentApi;
         this.accountApi = accountApi;
-        this.context = context;
     }
 
     @GET
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getPaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
-                                     @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo) throws AccountApiException, PaymentApiException {
-        PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+                                     @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
+        PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), tenantContext);
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId(), tenantContext);
         if (withPluginInfo) {
-            paymentMethod = paymentApi.getPaymentMethod(account, paymentMethod.getId(), true);
+            paymentMethod = paymentApi.getPaymentMethod(account, paymentMethod.getId(), true, tenantContext);
         }
         final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod);
 
@@ -90,14 +96,20 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     public Response updatePaymentMethod(final PaymentMethodJson json,
-                                        @PathParam("paymentMethodId") final String paymentMethodId) throws PaymentApiException, AccountApiException {
+                                        @PathParam("paymentMethodId") final String paymentMethodId,
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final PaymentMethod input = json.toPaymentMethod();
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), callContext);
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId(), callContext);
 
-        paymentApi.updatePaymentMethod(account, paymentMethod.getId(), input.getPluginDetail());
+        paymentApi.updatePaymentMethod(account, paymentMethod.getId(), input.getPluginDetail(), callContext);
 
-        return getPaymentMethod(paymentMethod.getId().toString(), false);
+        return getPaymentMethod(paymentMethod.getId().toString(), false, request);
     }
 
     @DELETE
@@ -107,11 +119,14 @@ public class PaymentMethodResource extends JaxRsResourceBase {
                                         @QueryParam(QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF) @DefaultValue("false") final Boolean deleteDefaultPaymentMethodWithAutoPayOff,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) throws PaymentApiException, AccountApiException {
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), callContext);
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId(), callContext);
 
-        paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), deleteDefaultPaymentMethodWithAutoPayOff, context.createContext(createdBy, reason, comment));
+        paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), deleteDefaultPaymentMethodWithAutoPayOff, callContext);
 
         return Response.status(Status.OK).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
index cea02e2..83c15d9 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -54,10 +55,13 @@ import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.Refund;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.common.base.Function;
@@ -73,21 +77,20 @@ public class PaymentResource extends JaxRsResourceBase {
     private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
     private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
 
-    private final Context context;
     private final PaymentApi paymentApi;
     private final InvoicePaymentApi invoicePaymentApi;
     private final AccountUserApi accountApi;
 
     @Inject
-    public PaymentResource(final JaxrsUriBuilder uriBuilder,
-                           final AccountUserApi accountApi,
+    public PaymentResource(final AccountUserApi accountApi,
                            final PaymentApi paymentApi,
                            final InvoicePaymentApi invoicePaymentApi,
+                           final JaxrsUriBuilder uriBuilder,
                            final TagUserApi tagUserApi,
                            final CustomFieldUserApi customFieldUserApi,
+                           final AuditUserApi auditUserApi,
                            final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
-        this.context = context;
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.paymentApi = paymentApi;
         this.invoicePaymentApi = invoicePaymentApi;
         this.accountApi = accountApi;
@@ -97,19 +100,22 @@ public class PaymentResource extends JaxRsResourceBase {
     @Path("/{paymentId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getPayment(@PathParam(ID_PARAM_NAME) final String paymentIdString,
-                               @QueryParam(QUERY_PAYMENT_WITH_REFUNDS_AND_CHARGEBACKS) @DefaultValue("false") final Boolean withRefundsAndChargebacks) throws PaymentApiException {
+                               @QueryParam(QUERY_PAYMENT_WITH_REFUNDS_AND_CHARGEBACKS) @DefaultValue("false") final Boolean withRefundsAndChargebacks,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+        final TenantContext tenantContext = context.createContext(request);
+
         final UUID paymentId = UUID.fromString(paymentIdString);
-        final Payment payment = paymentApi.getPayment(paymentId);
+        final Payment payment = paymentApi.getPayment(paymentId, tenantContext);
 
         final PaymentJsonSimple paymentJsonSimple;
         if (withRefundsAndChargebacks) {
             final List<RefundJson> refunds = new ArrayList<RefundJson>();
-            for (final Refund refund : paymentApi.getPaymentRefunds(paymentId)) {
+            for (final Refund refund : paymentApi.getPaymentRefunds(paymentId, tenantContext)) {
                 refunds.add(new RefundJson(refund));
             }
 
             final List<ChargebackJson> chargebacks = new ArrayList<ChargebackJson>();
-            for (final InvoicePayment chargeback : invoicePaymentApi.getChargebacksByPaymentId(paymentId)) {
+            for (final InvoicePayment chargeback : invoicePaymentApi.getChargebacksByPaymentId(paymentId, tenantContext)) {
                 chargebacks.add(new ChargebackJson(chargeback));
             }
 
@@ -132,8 +138,9 @@ public class PaymentResource extends JaxRsResourceBase {
     @GET
     @Path("/{paymentId:" + UUID_PATTERN + "}/" + REFUNDS)
     @Produces(APPLICATION_JSON)
-    public Response getRefunds(@PathParam("paymentId") final String paymentId) throws PaymentApiException {
-        final List<Refund> refunds = paymentApi.getPaymentRefunds(UUID.fromString(paymentId));
+    public Response getRefunds(@PathParam("paymentId") final String paymentId,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+        final List<Refund> refunds = paymentApi.getPaymentRefunds(UUID.fromString(paymentId), context.createContext(request));
         final List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
             @Override
             public RefundJson apply(final Refund input) {
@@ -154,10 +161,13 @@ public class PaymentResource extends JaxRsResourceBase {
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
                                  @HeaderParam(HDR_COMMENT) final String comment,
-                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws PaymentApiException, AccountApiException {
+                                 @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid);
-        final Account account = accountApi.getAccountById(payment.getAccountId());
+        final Payment payment = paymentApi.getPayment(paymentUuid, callContext);
+        final Account account = accountApi.getAccountById(payment.getAccountId(), callContext);
 
         final Refund result;
         if (json.isAdjusted()) {
@@ -166,14 +176,14 @@ public class PaymentResource extends JaxRsResourceBase {
                 for (final InvoiceItemJsonSimple item : json.getAdjustments()) {
                     adjustments.put(UUID.fromString(item.getInvoiceItemId()), item.getAmount());
                 }
-                result = paymentApi.createRefundWithItemsAdjustments(account, paymentUuid, adjustments, context.createContext(createdBy, reason, comment));
+                result = paymentApi.createRefundWithItemsAdjustments(account, paymentUuid, adjustments, callContext);
             } else {
                 // Invoice adjustment
-                result = paymentApi.createRefundWithAdjustment(account, paymentUuid, json.getAmount(), context.createContext(createdBy, reason, comment));
+                result = paymentApi.createRefundWithAdjustment(account, paymentUuid, json.getAmount(), callContext);
             }
         } else {
             // Refund without adjustment
-            result = paymentApi.createRefund(account, paymentUuid, json.getAmount(), context.createContext(createdBy, reason, comment));
+            result = paymentApi.createRefund(account, paymentUuid, json.getAmount(), callContext);
         }
 
         return uriBuilder.buildResponse(RefundResource.class, "getRefund", result.getId(), uriInfo.getBaseUri().toString());
@@ -182,8 +192,9 @@ public class PaymentResource extends JaxRsResourceBase {
     @GET
     @Path(CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id) {
-        return super.getCustomFields(UUID.fromString(id));
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        return super.getCustomFields(UUID.fromString(id), context.createContext(request));
     }
 
     @POST
@@ -194,9 +205,10 @@ public class PaymentResource extends JaxRsResourceBase {
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -207,16 +219,19 @@ public class PaymentResource extends JaxRsResourceBase {
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id, @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit) throws TagDefinitionApiException {
-        return super.getTags(UUID.fromString(id), withAudit);
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+                            @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit,
+                            @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        return super.getTags(UUID.fromString(id), withAudit, context.createContext(request));
     }
 
     @POST
@@ -228,9 +243,10 @@ public class PaymentResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -241,9 +257,10 @@ public class PaymentResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
index c50c17a..c0fe294 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
@@ -18,6 +18,7 @@ package com.ning.billing.jaxrs.resources;
 
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -26,10 +27,12 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
 import com.ning.billing.jaxrs.json.RefundJson;
+import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.Refund;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
@@ -44,19 +47,22 @@ public class RefundResource extends JaxRsResourceBase {
     private final PaymentApi paymentApi;
 
     @Inject
-    public RefundResource(final JaxrsUriBuilder uriBuilder,
-                          final PaymentApi paymentApi,
+    public RefundResource(final PaymentApi paymentApi,
+                          final JaxrsUriBuilder uriBuilder,
                           final TagUserApi tagUserApi,
-                          final CustomFieldUserApi customFieldUserApi) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+                          final CustomFieldUserApi customFieldUserApi,
+                          final AuditUserApi auditUserApi,
+                          final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.paymentApi = paymentApi;
     }
 
     @GET
     @Path("/{refundId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getRefund(@PathParam("refundId") final String refundId) throws PaymentApiException {
-        final Refund refund = paymentApi.getRefund(UUID.fromString(refundId));
+    public Response getRefund(@PathParam("refundId") final String refundId,
+                              @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+        final Refund refund = paymentApi.getRefund(UUID.fromString(refundId), context.createContext(request));
         // TODO Return adjusted items and audits
         return Response.status(Status.OK).entity(new RefundJson(refund, null, null)).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
index 178eea9..d6d1cc7 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.TimeoutException;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -57,6 +58,7 @@ import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
@@ -78,30 +80,28 @@ public class SubscriptionResource extends JaxRsResourceBase {
     private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
 
     private final EntitlementUserApi entitlementApi;
-    private final Context context;
-    private final JaxrsUriBuilder uriBuilder;
     private final KillbillEventHandler killbillHandler;
 
     @Inject
-    public SubscriptionResource(final JaxrsUriBuilder uriBuilder,
-                                final EntitlementUserApi entitlementApi,
-                                final Context context,
+    public SubscriptionResource(final EntitlementUserApi entitlementApi,
                                 final KillbillEventHandler killbillHandler,
+                                final JaxrsUriBuilder uriBuilder,
                                 final TagUserApi tagUserApi,
-                                final CustomFieldUserApi customFieldUserApi) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
-        this.uriBuilder = uriBuilder;
+                                final CustomFieldUserApi customFieldUserApi,
+                                final AuditUserApi auditUserApi,
+                                final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.entitlementApi = entitlementApi;
-        this.context = context;
         this.killbillHandler = killbillHandler;
     }
 
     @GET
     @Path("/{subscriptionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getSubscription(@PathParam("subscriptionId") final String subscriptionId) throws EntitlementUserApiException {
+    public Response getSubscription(@PathParam("subscriptionId") final String subscriptionId,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
         final UUID uuid = UUID.fromString(subscriptionId);
-        final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
+        final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid, context.createContext(request));
         final SubscriptionJsonNoEvents json = new SubscriptionJsonNoEvents(subscription, null);
         return Response.status(Status.OK).entity(json).build();
     }
@@ -115,7 +115,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                        @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
-                                       @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final SubscriptionCallCompletionCallback<Subscription> callback = new SubscriptionCallCompletionCallback<Subscription>() {
             @Override
             public Subscription doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException, TimeoutException {
@@ -141,7 +144,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
         };
 
         final SubscriptionCallCompletion<Subscription> callCompletionCreation = new SubscriptionCallCompletion<Subscription>();
-        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
+        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
     }
 
     @PUT
@@ -156,7 +159,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                            @QueryParam(QUERY_POLICY) final String policyString,
                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                            @HeaderParam(HDR_REASON) final String reason,
-                                           @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+                                           @HeaderParam(HDR_COMMENT) final String comment,
+                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
@@ -165,7 +171,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             public Response doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException,
                                                                       TimeoutException {
                 final UUID uuid = UUID.fromString(subscriptionId);
-                final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+                final Subscription current = entitlementApi.getSubscriptionFromId(uuid, callContext);
                 final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
 
                 if (policyString == null) {
@@ -191,12 +197,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
                     return operationResponse;
                 }
 
-                return getSubscription(subscriptionId);
+                return getSubscription(subscriptionId, request);
             }
         };
 
         final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
-        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
+        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
     }
 
     @PUT
@@ -205,11 +211,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
     public Response uncancelSubscriptionPlan(@PathParam("subscriptionId") final String subscriptionId,
                                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                              @HeaderParam(HDR_REASON) final String reason,
-                                             @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+                                             @HeaderParam(HDR_COMMENT) final String comment,
+                                             @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
         final UUID uuid = UUID.fromString(subscriptionId);
-        final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+        final Subscription current = entitlementApi.getSubscriptionFromId(uuid, context.createContext(createdBy, reason, comment, request));
 
-        current.uncancel(context.createContext(createdBy, reason, comment));
+        current.uncancel(context.createContext(createdBy, reason, comment, request));
         return Response.status(Status.OK).build();
     }
 
@@ -224,7 +231,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                            @HeaderParam(HDR_REASON) final String reason,
                                            @HeaderParam(HDR_COMMENT) final String comment,
-                                           @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementUserApiException {
+                                           @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementUserApiException {
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
         final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
@@ -235,7 +245,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                            TimeoutException {
                 final UUID uuid = UUID.fromString(subscriptionId);
 
-                final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+                final Subscription current = entitlementApi.getSubscriptionFromId(uuid, callContext);
 
                 final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
                 if (policyString == null) {
@@ -259,7 +269,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
         };
 
         final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
-        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
+        return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
     }
 
     private static final class CompletionUserRequestSubscription extends CompletionUserRequestBase {
@@ -315,17 +325,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
         public Response withSynchronization(final SubscriptionCallCompletionCallback<T> callback,
                                             final long timeoutSec,
                                             final boolean callCompletion,
-                                            final String createdBy,
-                                            final String reason,
-                                            final String comment) throws EntitlementUserApiException {
-
-            final CallContext ctx = context.createContext(createdBy, reason, comment);
-            final CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(ctx.getUserToken()) : null;
+                                            final CallContext callContext) throws EntitlementUserApiException {
+            final CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(callContext.getUserToken()) : null;
             try {
                 if (waiter != null) {
                     killbillHandler.registerCompletionUserRequestWaiter(waiter);
                 }
-                final T operationValue = callback.doOperation(ctx);
+                final T operationValue = callback.doOperation(callContext);
                 if (waiter != null && callback.isImmOperation()) {
                     waiter.waitForCompletion(timeoutSec * 1000);
                 }
@@ -345,8 +351,9 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @GET
     @Path(CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id) {
-        return super.getCustomFields(UUID.fromString(id));
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+                                    @javax.ws.rs.core.Context final HttpServletRequest request) {
+        return super.getCustomFields(UUID.fromString(id), context.createContext(request));
     }
 
     @POST
@@ -358,9 +365,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -372,16 +380,19 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo,
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                                        context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment, request));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id, @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit) throws TagDefinitionApiException {
-        return super.getTags(UUID.fromString(id), withAudit);
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+                            @QueryParam(QUERY_AUDIT) @DefaultValue("false") final Boolean withAudit,
+                            @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        return super.getTags(UUID.fromString(id), withAudit, context.createContext(request));
     }
 
     @POST
@@ -393,9 +404,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @DELETE
@@ -406,9 +418,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment, request));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
index 642c881..962a927 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -20,6 +20,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -34,6 +35,7 @@ import javax.ws.rs.core.Response.Status;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
@@ -49,21 +51,19 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 @Path(JaxrsResource.TAG_DEFINITIONS_PATH)
 public class TagResource extends JaxRsResourceBase {
 
-    private final Context context;
-
     @Inject
     public TagResource(final JaxrsUriBuilder uriBuilder,
                        final TagUserApi tagUserApi,
                        final CustomFieldUserApi customFieldUserApi,
+                       final AuditUserApi auditUserApi,
                        final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
-        this.context = context;
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
     }
 
     @GET
     @Produces(APPLICATION_JSON)
-    public Response getTagDefinitions() {
-        final List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
+    public Response getTagDefinitions(@javax.ws.rs.core.Context final HttpServletRequest request) {
+        final List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions(context.createContext(request));
 
         final List<TagDefinitionJson> result = new LinkedList<TagDefinitionJson>();
         for (final TagDefinition cur : tagDefinitions) {
@@ -76,8 +76,9 @@ public class TagResource extends JaxRsResourceBase {
     @GET
     @Path("/{tagDefinitionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId) throws TagDefinitionApiException {
-        final TagDefinition tagDef = tagUserApi.getTagDefinition(UUID.fromString(tagDefId));
+    public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
+                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        final TagDefinition tagDef = tagUserApi.getTagDefinition(UUID.fromString(tagDefId), context.createContext(request));
         final TagDefinitionJson json = new TagDefinitionJson(tagDef);
         return Response.status(Status.OK).entity(json).build();
     }
@@ -88,8 +89,9 @@ public class TagResource extends JaxRsResourceBase {
     public Response createTagDefinition(final TagDefinitionJson json,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) throws TagDefinitionApiException {
-        final TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        final TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment, request));
         return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getId());
     }
 
@@ -99,8 +101,9 @@ public class TagResource extends JaxRsResourceBase {
     public Response deleteTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) throws TagDefinitionApiException {
-        tagUserApi.deleteTagDefinition(UUID.fromString(tagDefId), context.createContext(createdBy, reason, comment));
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        tagUserApi.deleteTagDefinition(UUID.fromString(tagDefId), context.createContext(createdBy, reason, comment, request));
         return Response.status(Status.NO_CONTENT).build();
     }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java
new file mode 100644
index 0000000..e94b49f
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.resources;
+
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.ning.billing.jaxrs.json.TenantJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.tenant.api.TenantApiException;
+import com.ning.billing.tenant.api.TenantData;
+import com.ning.billing.tenant.api.TenantUserApi;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.dao.ObjectType;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+@Singleton
+@Path(JaxrsResource.TENANTS_PATH)
+public class TenantResource extends JaxRsResourceBase {
+
+    private final TenantUserApi tenantApi;
+
+    @Inject
+    public TenantResource(final TenantUserApi tenantApi,
+                          final JaxrsUriBuilder uriBuilder,
+                          final TagUserApi tagUserApi,
+                          final CustomFieldUserApi customFieldUserApi,
+                          final AuditUserApi auditUserApi,
+                          final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
+        this.tenantApi = tenantApi;
+    }
+
+    @GET
+    @Path("/{tenantId:" + UUID_PATTERN + "}")
+    @Produces(APPLICATION_JSON)
+    public Response getTenant(@PathParam("tenantId") final String tenantId) throws TenantApiException {
+        final Tenant tenant = tenantApi.getTenantById(UUID.fromString(tenantId));
+        return Response.status(Status.OK).entity(new TenantJson(tenant)).build();
+    }
+
+    @GET
+    @Produces(APPLICATION_JSON)
+    public Response getTenantByApiKey(@QueryParam(QUERY_API_KEY) final String externalKey) throws TenantApiException {
+        final Tenant tenant = tenantApi.getTenantByApiKey(externalKey);
+        return Response.status(Status.OK).entity(new TenantJson(tenant)).build();
+    }
+
+    @POST
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createTenant(final TenantJson json,
+                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                 @HeaderParam(HDR_REASON) final String reason,
+                                 @HeaderParam(HDR_COMMENT) final String comment,
+                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
+        final TenantData data = json.toTenantData();
+        final Tenant tenant = tenantApi.createTenant(data, context.createContext(createdBy, reason, comment, request));
+        return uriBuilder.buildResponse(TenantResource.class, "getTenant", tenant.getId());
+    }
+
+    @Override
+    protected ObjectType getObjectType() {
+        return ObjectType.TENANT;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
index ea453a0..ad9f918 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
@@ -13,18 +13,24 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.util;
 
 import java.util.UUID;
 
-import com.google.common.base.Preconditions;
-import com.google.inject.Inject;
+import javax.servlet.ServletRequest;
+
 import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.tenant.api.Tenant;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.callcontext.UserType;
 
+import com.google.common.base.Preconditions;
+import com.google.inject.Inject;
+
 public class Context {
 
     private final CallOrigin origin;
@@ -33,19 +39,39 @@ public class Context {
 
     @Inject
     public Context(final CallContextFactory factory) {
-        super();
         this.origin = CallOrigin.EXTERNAL;
         this.userType = UserType.CUSTOMER;
         this.contextFactory = factory;
     }
 
-    public CallContext createContext(final String createdBy, final String reason, final String comment)
+    public CallContext createContext(final String createdBy, final String reason, final String comment, final ServletRequest request)
             throws IllegalArgumentException {
         try {
             Preconditions.checkNotNull(createdBy, String.format("Header %s needs to be set", JaxrsResource.HDR_CREATED_BY));
-            return contextFactory.createCallContext(createdBy, origin, userType, reason, comment, UUID.randomUUID());
+            final Tenant tenant = getTenantFromRequest(request);
+            return contextFactory.createCallContext(tenant == null ? null : tenant.getId(), createdBy, origin, userType, reason,
+                                                    comment, UUID.randomUUID());
         } catch (NullPointerException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
     }
+
+    public TenantContext createContext(final ServletRequest request) {
+        final Tenant tenant = getTenantFromRequest(request);
+        if (tenant == null) {
+            // Multi-tenancy may not have been configured - default to "default" tenant (see InternalCallContextFactory)
+            return contextFactory.createTenantContext(null);
+        } else {
+            return contextFactory.createTenantContext(tenant.getId());
+        }
+    }
+
+    private Tenant getTenantFromRequest(final ServletRequest request) {
+        final Object tenantObject = request.getAttribute("killbill_tenant");
+        if (tenantObject == null) {
+            return null;
+        } else {
+            return (Tenant) tenantObject;
+        }
+    }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAuditLogJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAuditLogJson.java
index 3c7e31c..4427556 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAuditLogJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAuditLogJson.java
@@ -26,12 +26,7 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.audit.DefaultAuditLog;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.DefaultClock;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.TableName;
@@ -87,21 +82,14 @@ public class TestAuditLogJson extends JaxrsTestSuite {
         final ChangeType changeType = ChangeType.DELETE;
         final EntityAudit entityAudit = new EntityAudit(tableName, recordId, changeType);
 
-        final String userName = UUID.randomUUID().toString();
-        final CallOrigin callOrigin = CallOrigin.EXTERNAL;
-        final UserType userType = UserType.CUSTOMER;
-        final UUID userToken = UUID.randomUUID();
-        final ClockMock clock = new ClockMock();
-        final CallContext callContext = new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
-
         final AuditLog auditLog = new DefaultAuditLog(entityAudit, callContext);
 
         final AuditLogJson auditLogJson = new AuditLogJson(auditLog);
         Assert.assertEquals(auditLogJson.getChangeType(), changeType.toString());
         Assert.assertNotNull(auditLogJson.getChangeDate());
-        Assert.assertEquals(auditLogJson.getChangedBy(), userName);
-        Assert.assertNull(auditLogJson.getReasonCode());
-        Assert.assertNull(auditLogJson.getComments());
-        Assert.assertEquals(auditLogJson.getUserToken(), userToken.toString());
+        Assert.assertEquals(auditLogJson.getChangedBy(), callContext.getUserName());
+        Assert.assertEquals(auditLogJson.getReasonCode(), callContext.getReasonCode());
+        Assert.assertEquals(auditLogJson.getComments(), callContext.getComment());
+        Assert.assertEquals(auditLogJson.getUserToken(), callContext.getUserToken().toString());
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java b/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
index 3635d26..2e8af01 100644
--- a/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
@@ -17,56 +17,60 @@
 package com.ning.billing.junction.api.blocking;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
-import com.google.inject.Inject;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.api.DefaultBlockingState;
 import com.ning.billing.junction.dao.BlockingStateDao;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class DefaultBlockingApi implements BlockingApi {
+
     private final BlockingStateDao dao;
     private final Clock clock;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultBlockingApi(final BlockingStateDao dao, final Clock clock) {
+    public DefaultBlockingApi(final BlockingStateDao dao, final Clock clock, final InternalCallContextFactory internalCallContextFactory) {
         this.dao = dao;
         this.clock = clock;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public BlockingState getBlockingStateFor(final Blockable overdueable) {
-        BlockingState state = dao.getBlockingStateFor(overdueable);
+    public BlockingState getBlockingStateFor(final Blockable overdueable, final TenantContext context) {
+        BlockingState state = dao.getBlockingStateFor(overdueable, internalCallContextFactory.createInternalTenantContext(context));
         if (state == null) {
             state = DefaultBlockingState.getClearState();
         }
         return state;
-
     }
 
     @Override
-    public BlockingState getBlockingStateFor(final UUID overdueableId) {
-        return dao.getBlockingStateFor(overdueableId);
+    public BlockingState getBlockingStateFor(final UUID overdueableId, final TenantContext context) {
+        return dao.getBlockingStateFor(overdueableId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<BlockingState> getBlockingHistory(final Blockable overdueable) {
-        return dao.getBlockingHistoryFor(overdueable);
+    public List<BlockingState> getBlockingHistory(final Blockable overdueable, final TenantContext context) {
+        return dao.getBlockingHistoryFor(overdueable, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<BlockingState> getBlockingHistory(final UUID overdueableId) {
-        return dao.getBlockingHistoryFor(overdueableId);
+    public List<BlockingState> getBlockingHistory(final UUID overdueableId, final TenantContext context) {
+        return dao.getBlockingHistoryFor(overdueableId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public <T extends Blockable> void setBlockingState(final BlockingState state) {
-        dao.setBlockingState(state, clock);
-
+    public <T extends Blockable> void setBlockingState(final BlockingState state, final CallContext context) {
+        // TODO accountId?
+        dao.setBlockingState(state, clock, internalCallContextFactory.createInternalCallContext(context));
     }
-
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java b/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
index e67560d..1c1aca3 100644
--- a/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
+++ b/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
@@ -20,18 +20,19 @@ import java.util.UUID;
 
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApiException;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface BlockingChecker {
 
-    public void checkBlockedChange(Blockable blockable) throws BlockingApiException;
+    public void checkBlockedChange(Blockable blockable, InternalTenantContext context) throws BlockingApiException;
 
-    public void checkBlockedEntitlement(Blockable blockable) throws BlockingApiException;
+    public void checkBlockedEntitlement(Blockable blockable, InternalTenantContext context) throws BlockingApiException;
 
-    public void checkBlockedBilling(Blockable blockable) throws BlockingApiException;
+    public void checkBlockedBilling(Blockable blockable, InternalTenantContext context) throws BlockingApiException;
 
-    public void checkBlockedChange(UUID bundleId, Blockable.Type type) throws BlockingApiException;
+    public void checkBlockedChange(UUID bundleId, Blockable.Type type, InternalTenantContext context) throws BlockingApiException;
 
-    public void checkBlockedEntitlement(UUID bundleId, Blockable.Type type) throws BlockingApiException;
+    public void checkBlockedEntitlement(UUID bundleId, Blockable.Type type, InternalTenantContext context) throws BlockingApiException;
 
-    public void checkBlockedBilling(UUID bundleId, Blockable.Type type) throws BlockingApiException;
+    public void checkBlockedBilling(UUID bundleId, Blockable.Type type, InternalTenantContext context) throws BlockingApiException;
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java b/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
index 5bfb8de..d84f88f 100644
--- a/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
+++ b/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
@@ -18,7 +18,6 @@ package com.ning.billing.junction.block;
 
 import java.util.UUID;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
@@ -29,6 +28,9 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApiException;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.dao.BlockingStateDao;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+
+import com.google.inject.Inject;
 
 public class DefaultBlockingChecker implements BlockingChecker {
 
@@ -86,12 +88,12 @@ public class DefaultBlockingChecker implements BlockingChecker {
         this.dao = dao;
     }
 
-    public BlockingAggregator getBlockedStateSubscriptionId(final UUID subscriptionId) throws EntitlementUserApiException {
-        final Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId);
-        return getBlockedStateSubscription(subscription);
+    public BlockingAggregator getBlockedStateSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws EntitlementUserApiException {
+        final Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId, context.toTenantContext());
+        return getBlockedStateSubscription(subscription, context);
     }
 
-    public BlockingAggregator getBlockedStateSubscription(final Subscription subscription) throws EntitlementUserApiException {
+    public BlockingAggregator getBlockedStateSubscription(final Subscription subscription, final InternalTenantContext context) throws EntitlementUserApiException {
         final BlockingAggregator result = new BlockingAggregator();
         if (subscription != null) {
             final BlockingState subscriptionState = subscription.getBlockingState();
@@ -99,19 +101,19 @@ public class DefaultBlockingChecker implements BlockingChecker {
                 result.or(subscriptionState);
             }
             if (subscription.getBundleId() != null) {
-                result.or(getBlockedStateBundleId(subscription.getBundleId()));
+                result.or(getBlockedStateBundleId(subscription.getBundleId(), context));
             }
         }
         return result;
     }
 
-    public BlockingAggregator getBlockedStateBundleId(final UUID bundleId) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(bundleId);
-        return getBlockedStateBundle(bundle);
+    public BlockingAggregator getBlockedStateBundleId(final UUID bundleId, final InternalTenantContext context) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(bundleId, context.toTenantContext());
+        return getBlockedStateBundle(bundle, context);
     }
 
-    public BlockingAggregator getBlockedStateBundle(final SubscriptionBundle bundle) {
-        final BlockingAggregator result = getBlockedStateAccountId(bundle.getAccountId());
+    public BlockingAggregator getBlockedStateBundle(final SubscriptionBundle bundle, final InternalTenantContext context) {
+        final BlockingAggregator result = getBlockedStateAccountId(bundle.getAccountId(), context);
         final BlockingState bundleState = bundle.getBlockingState();
         if (bundleState != null) {
             result.or(bundleState);
@@ -119,30 +121,30 @@ public class DefaultBlockingChecker implements BlockingChecker {
         return result;
     }
 
-    public BlockingAggregator getBlockedStateAccountId(final UUID accountId) {
+    public BlockingAggregator getBlockedStateAccountId(final UUID accountId, final InternalTenantContext context) {
         final BlockingAggregator result = new BlockingAggregator();
         if (accountId != null) {
-            final BlockingState accountState = dao.getBlockingStateFor(accountId);
+            final BlockingState accountState = dao.getBlockingStateFor(accountId, context);
             result.or(accountState);
         }
         return result;
     }
 
-    public BlockingAggregator getBlockedStateAccount(final Account account) {
+    public BlockingAggregator getBlockedStateAccount(final Account account, final InternalTenantContext context) {
         if (account != null) {
-            return getBlockedStateAccountId(account.getId());
+            return getBlockedStateAccountId(account.getId(), context);
         }
         return new BlockingAggregator();
     }
 
     @Override
-    public void checkBlockedChange(final Blockable blockable) throws BlockingApiException {
+    public void checkBlockedChange(final Blockable blockable, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockChange()) {
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockChange()) {
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_BUNDLE, blockable.getId().toString());
-            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockChange()) {
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
@@ -151,13 +153,13 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedEntitlement(final Blockable blockable) throws BlockingApiException {
+    public void checkBlockedEntitlement(final Blockable blockable, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockEntitlement()) {
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockEntitlement()) {
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_BUNDLE, blockable.getId().toString());
-            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockEntitlement()) {
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
@@ -166,13 +168,13 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedBilling(final Blockable blockable) throws BlockingApiException {
+    public void checkBlockedBilling(final Blockable blockable, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockBilling()) {
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockBilling()) {
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_BUNDLE, blockable.getId().toString());
-            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockBilling()) {
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
@@ -182,13 +184,13 @@ public class DefaultBlockingChecker implements BlockingChecker {
 
 
     @Override
-    public void checkBlockedChange(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
+    public void checkBlockedChange(final UUID blockableId, final Blockable.Type type, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockChange()) {
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockChange()) {
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_BUNDLE, blockableId.toString());
-            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockChange()) {
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId, context).isBlockChange()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_ACCOUNT, blockableId.toString());
 
             }
@@ -198,13 +200,13 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedEntitlement(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
+    public void checkBlockedEntitlement(final UUID blockableId, final Blockable.Type type, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockEntitlement()) {
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockEntitlement()) {
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_BUNDLE, blockableId.toString());
-            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockEntitlement()) {
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId, context).isBlockEntitlement()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockableId.toString());
             }
         } catch (EntitlementUserApiException e) {
@@ -213,13 +215,13 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedBilling(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
+    public void checkBlockedBilling(final UUID blockableId, final Blockable.Type type, final InternalTenantContext context) throws BlockingApiException {
         try {
-            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockBilling()) {
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockBilling()) {
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_BUNDLE, blockableId.toString());
-            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockBilling()) {
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId, context).isBlockBilling()) {
                 throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_ACCOUNT, blockableId.toString());
             }
         } catch (EntitlementUserApiException e) {
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
index 530a1a2..f33d3d4 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
@@ -17,25 +17,26 @@
 package com.ning.billing.junction.dao;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 
 public interface BlockingStateDao {
 
-    //Read
-    public BlockingState getBlockingStateFor(Blockable blockable);
+    // Read
+    public BlockingState getBlockingStateFor(Blockable blockable, InternalTenantContext context);
 
-    public BlockingState getBlockingStateFor(UUID blockableId);
+    public BlockingState getBlockingStateFor(UUID blockableId, InternalTenantContext context);
 
-    public List<BlockingState> getBlockingHistoryFor(Blockable blockable);
+    public List<BlockingState> getBlockingHistoryFor(Blockable blockable, InternalTenantContext context);
 
-    public List<BlockingState> getBlockingHistoryFor(UUID blockableId);
+    public List<BlockingState> getBlockingHistoryFor(UUID blockableId, InternalTenantContext context);
 
-    //Write
-    <T extends Blockable> void setBlockingState(BlockingState state, Clock clock);
+    // Write
+    <T extends Blockable> void setBlockingState(BlockingState state, Clock clock, InternalCallContext context);
 
 } 
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
index 3231d6b..45bae02 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
@@ -19,7 +19,6 @@ package com.ning.billing.junction.dao;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -42,6 +41,9 @@ import com.ning.billing.junction.api.BlockingApiException;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.api.DefaultBlockingState;
 import com.ning.billing.overdue.OverdueState;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
@@ -51,31 +53,33 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
 
     @Override
     @SqlUpdate
-    public abstract <T extends Blockable> void setBlockingState(
-            @Bind(binder = BlockingStateBinder.class) BlockingState state,
-            @Bind(binder = CurrentTimeBinder.class) Clock clock);
-
+    public abstract <T extends Blockable> void setBlockingState(@Bind(binder = BlockingStateBinder.class) BlockingState state,
+                                                                @Bind(binder = CurrentTimeBinder.class) Clock clock,
+                                                                @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract BlockingState getBlockingStateFor(@Bind(binder = BlockableBinder.class) Blockable overdueable);
+    public abstract BlockingState getBlockingStateFor(@Bind(binder = BlockableBinder.class) Blockable overdueable,
+                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract BlockingState getBlockingStateFor(@Bind(binder = UUIDBinder.class) UUID overdueableId);
+    public abstract BlockingState getBlockingStateFor(@Bind(binder = UUIDBinder.class) UUID overdueableId,
+                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract List<BlockingState> getBlockingHistoryFor(@Bind(binder = BlockableBinder.class) Blockable blockable);
+    public abstract List<BlockingState> getBlockingHistoryFor(@Bind(binder = BlockableBinder.class) Blockable blockable,
+                                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract List<BlockingState> getBlockingHistoryFor(@Bind(binder = UUIDBinder.class) UUID blockableId);
-
+    public abstract List<BlockingState> getBlockingHistoryFor(@Bind(binder = UUIDBinder.class) UUID blockableId,
+                                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     public class BlockingHistorySqlMapper extends MapperBase implements ResultSetMapper<BlockingState> {
 
@@ -117,6 +121,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     }
 
     public static class BlockingStateBinder extends BinderBase implements Binder<Bind, DefaultBlockingState> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final DefaultBlockingState state) {
             stmt.bind("id", state.getBlockedId().toString());
@@ -130,6 +135,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     }
 
     public static class UUIDBinder extends BinderBase implements Binder<Bind, UUID> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final UUID id) {
             stmt.bind("id", id.toString());
@@ -137,6 +143,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     }
 
     public static class BlockableBinder extends BinderBase implements Binder<Bind, Blockable> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Blockable overdueable) {
             stmt.bind("id", overdueable.getId().toString());
@@ -144,6 +151,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     }
 
     public static class OverdueStateBinder<T extends Blockable> extends BinderBase implements Binder<Bind, OverdueState<T>> {
+
         @Override
         public void bind(final SQLStatement<?> stmt, final Bind bind, final OverdueState<T> overdueState) {
             stmt.bind("state", overdueState.getName());
@@ -160,6 +168,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     }
 
     public static class CurrentTimeBinder extends BinderBase implements Binder<Bind, Clock> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Clock clock) {
             stmt.bind("created_date", clock.getUTCNow().toDate());
diff --git a/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java b/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
index b0d8fd8..ff01d9e 100644
--- a/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
+++ b/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
@@ -18,9 +18,6 @@ package com.ning.billing.junction.glue;
 
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.glue.JunctionModule;
@@ -36,6 +33,10 @@ import com.ning.billing.junction.plumbing.api.BlockingEntitlementUserApi;
 import com.ning.billing.junction.plumbing.billing.BlockingCalculator;
 import com.ning.billing.junction.plumbing.billing.DefaultBillingApi;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
 public class DefaultJunctionModule extends AbstractModule implements JunctionModule {
 
     @Override
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
index 3f3bf50..b2dfe54 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
@@ -26,15 +26,18 @@ import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class BlockingAccount implements Account {
     private final Account account;
+    private final TenantContext context;
     private BlockingState blockingState = null;
     private final BlockingApi blockingApi;
 
-    public BlockingAccount(final Account account, final BlockingApi blockingApi) {
+    public BlockingAccount(final Account account, final BlockingApi blockingApi, final TenantContext context) {
         this.account = account;
         this.blockingApi = blockingApi;
+        this.context = context;
     }
 
     @Override
@@ -95,7 +98,7 @@ public class BlockingAccount implements Account {
     @Override
     public BlockingState getBlockingState() {
         if (blockingState == null) {
-            blockingState = blockingApi.getBlockingStateFor(account);
+            blockingState = blockingApi.getBlockingStateFor(account, context);
         }
         return blockingState;
     }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
index fd7b8eb..4115ad5 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
@@ -19,7 +19,6 @@ package com.ning.billing.junction.plumbing.api;
 import java.util.List;
 import java.util.UUID;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
@@ -28,9 +27,13 @@ import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.account.api.MigrationAccountData;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.Inject;
+
 public class BlockingAccountUserApi implements AccountUserApi {
+
     private final AccountUserApi userApi;
     private final BlockingApi blockingApi;
 
@@ -67,28 +70,28 @@ public class BlockingAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public Account getAccountByKey(final String key) throws AccountApiException {
-        return new BlockingAccount(userApi.getAccountByKey(key), blockingApi);
+    public Account getAccountByKey(final String key, final TenantContext context) throws AccountApiException {
+        return new BlockingAccount(userApi.getAccountByKey(key, context), blockingApi, context);
     }
 
     @Override
-    public Account getAccountById(final UUID accountId) throws AccountApiException {
-        return userApi.getAccountById(accountId);
+    public Account getAccountById(final UUID accountId, final TenantContext context) throws AccountApiException {
+        return userApi.getAccountById(accountId, context);
     }
 
     @Override
-    public List<Account> getAccounts() {
-        return userApi.getAccounts();
+    public List<Account> getAccounts(final TenantContext context) {
+        return userApi.getAccounts(context);
     }
 
     @Override
-    public UUID getIdFromKey(final String externalKey) throws AccountApiException {
-        return userApi.getIdFromKey(externalKey);
+    public UUID getIdFromKey(final String externalKey, final TenantContext context) throws AccountApiException {
+        return userApi.getIdFromKey(externalKey, context);
     }
 
     @Override
-    public List<AccountEmail> getEmails(final UUID accountId) {
-        return userApi.getEmails(accountId);
+    public List<AccountEmail> getEmails(final UUID accountId, final TenantContext context) {
+        return userApi.getEmails(accountId, context);
     }
 
     @Override
@@ -107,14 +110,12 @@ public class BlockingAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public void updatePaymentMethod(UUID accountId, UUID paymentMethodId,
-            CallContext context) throws AccountApiException {
+    public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, CallContext context) throws AccountApiException {
         userApi.updatePaymentMethod(accountId, paymentMethodId, context);
     }
 
     @Override
-    public void removePaymentMethod(UUID accountId, CallContext context)
-            throws AccountApiException {
+    public void removePaymentMethod(final UUID accountId, final CallContext context) throws AccountApiException {
         userApi.removePaymentMethod(accountId, context);
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
index d89c64d..1e6aa02 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
@@ -24,8 +24,6 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
-
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -37,97 +35,104 @@ import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingApiException;
 import com.ning.billing.junction.block.BlockingChecker;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.Inject;
+
 public class BlockingEntitlementUserApi implements EntitlementUserApi {
+
     private final EntitlementUserApi entitlementUserApi;
     private final BlockingApi blockingApi;
     private final BlockingChecker checker;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public BlockingEntitlementUserApi(@RealImplementation final EntitlementUserApi userApi, final BlockingApi blockingApi, final BlockingChecker checker) {
+    public BlockingEntitlementUserApi(@RealImplementation final EntitlementUserApi userApi, final BlockingApi blockingApi,
+                                      final BlockingChecker checker, final InternalCallContextFactory internalCallContextFactory) {
         this.entitlementUserApi = userApi;
         this.blockingApi = blockingApi;
         this.checker = checker;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public SubscriptionBundle getBundleFromId(final UUID id) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(id);
-        return new BlockingSubscriptionBundle(bundle, blockingApi);
+    public SubscriptionBundle getBundleFromId(final UUID id, final TenantContext context) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(id, context);
+        return new BlockingSubscriptionBundle(bundle, blockingApi, context);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final UUID id) throws EntitlementUserApiException {
-        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(id);
-        return new BlockingSubscription(subscription, blockingApi, checker);
+    public Subscription getSubscriptionFromId(final UUID id, final TenantContext context) throws EntitlementUserApiException {
+        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(id, context);
+        return new BlockingSubscription(subscription, blockingApi, checker, context, internalCallContextFactory);
     }
 
     @Override
-    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementUserApi.getBundleForAccountAndKey(accountId, bundleKey);
-        return new BlockingSubscriptionBundle(bundle, blockingApi);
+    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementUserApi.getBundleForAccountAndKey(accountId, bundleKey, context);
+        return new BlockingSubscriptionBundle(bundle, blockingApi, context);
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId) {
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId, final TenantContext context) {
         final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>();
-        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId, context);
         for (final SubscriptionBundle bundle : bundles) {
-            result.add(new BlockingSubscriptionBundle(bundle, blockingApi));
+            result.add(new BlockingSubscriptionBundle(bundle, blockingApi, context));
         }
         return result;
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForKey(String bundleKey)
+    public List<SubscriptionBundle> getBundlesForKey(final String bundleKey, final TenantContext context)
             throws EntitlementUserApiException {
         final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>();
-        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForKey(bundleKey);
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForKey(bundleKey, context);
         for (final SubscriptionBundle bundle : bundles) {
-            result.add(new BlockingSubscriptionBundle(bundle, blockingApi));
+            result.add(new BlockingSubscriptionBundle(bundle, blockingApi, context));
         }
         return result;
     }
 
-
     @Override
-    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId) {
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId, final TenantContext context) {
         final List<Subscription> result = new ArrayList<Subscription>();
-        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundleId);
+        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundleId, context);
         for (final Subscription subscription : subscriptions) {
-            result.add(new BlockingSubscription(subscription, blockingApi, checker));
+            result.add(new BlockingSubscription(subscription, blockingApi, checker, context, internalCallContextFactory));
         }
         return result;
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey) {
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) {
         final List<Subscription> result = new ArrayList<Subscription>();
-        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForAccountAndKey(accountId, bundleKey);
+        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForAccountAndKey(accountId, bundleKey, context);
         for (final Subscription subscription : subscriptions) {
-            result.add(new BlockingSubscription(subscription, blockingApi, checker));
+            result.add(new BlockingSubscription(subscription, blockingApi, checker, context, internalCallContextFactory));
         }
         return result;
     }
 
     @Override
-    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String productName, final DateTime requestedDate)
-            throws EntitlementUserApiException {
-        return entitlementUserApi.getDryRunChangePlanStatus(subscriptionId, productName, requestedDate);
+    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String productName,
+                                                                    final DateTime requestedDate, final TenantContext context) throws EntitlementUserApiException {
+        return entitlementUserApi.getDryRunChangePlanStatus(subscriptionId, productName, requestedDate, context);
     }
 
     @Override
-    public Subscription getBaseSubscription(final UUID bundleId) throws EntitlementUserApiException {
-        return new BlockingSubscription(entitlementUserApi.getBaseSubscription(bundleId), blockingApi, checker);
+    public Subscription getBaseSubscription(final UUID bundleId, final TenantContext context) throws EntitlementUserApiException {
+        return new BlockingSubscription(entitlementUserApi.getBaseSubscription(bundleId, context), blockingApi, checker, context, internalCallContextFactory);
     }
 
     @Override
     public SubscriptionBundle createBundleForAccount(final UUID accountId, final String bundleKey, final CallContext context)
             throws EntitlementUserApiException {
         try {
-            checker.checkBlockedChange(accountId, Blockable.Type.ACCOUNT);
-            return new BlockingSubscriptionBundle(entitlementUserApi.createBundleForAccount(accountId, bundleKey, context), blockingApi);
+            checker.checkBlockedChange(accountId, Blockable.Type.ACCOUNT, internalCallContextFactory.createInternalTenantContext(accountId, context));
+            return new BlockingSubscriptionBundle(entitlementUserApi.createBundleForAccount(accountId, bundleKey, context), blockingApi, context);
         } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
@@ -137,15 +142,17 @@ public class BlockingEntitlementUserApi implements EntitlementUserApi {
     public Subscription createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final DateTime requestedDate,
                                            final CallContext context) throws EntitlementUserApiException {
         try {
-            checker.checkBlockedChange(bundleId, Blockable.Type.SUBSCRIPTION_BUNDLE);
-            return new BlockingSubscription(entitlementUserApi.createSubscription(bundleId, spec, requestedDate, context), blockingApi, checker);
+            // Retrieve the bundle to get the account id for the internal call context
+            final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId, context);
+            checker.checkBlockedChange(bundleId, Blockable.Type.SUBSCRIPTION_BUNDLE, internalCallContextFactory.createInternalTenantContext(bundle.getAccountId(), context));
+            return new BlockingSubscription(entitlementUserApi.createSubscription(bundleId, spec, requestedDate, context), blockingApi, checker, context, internalCallContextFactory);
         } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
     }
 
     @Override
-    public DateTime getNextBillingDate(final UUID account) {
-        return entitlementUserApi.getNextBillingDate(account);
+    public DateTime getNextBillingDate(final UUID account, final TenantContext context) {
+        return entitlementUserApi.getNextBillingDate(account, context);
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
index 1bf3906..a2c1358 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
@@ -36,18 +36,25 @@ import com.ning.billing.junction.api.BlockingApiException;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.block.BlockingChecker;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class BlockingSubscription implements Subscription {
     private final Subscription subscription;
     private final BlockingApi blockingApi;
     private final BlockingChecker checker;
+    private final TenantContext context;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private BlockingState blockingState = null;
 
-    public BlockingSubscription(final Subscription subscription, final BlockingApi blockingApi, final BlockingChecker checker) {
+    public BlockingSubscription(final Subscription subscription, final BlockingApi blockingApi, final BlockingChecker checker,
+                                final TenantContext context, final InternalCallContextFactory internalCallContextFactory) {
         this.subscription = subscription;
         this.blockingApi = blockingApi;
         this.checker = checker;
+        this.context = context;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
@@ -76,7 +83,7 @@ public class BlockingSubscription implements Subscription {
     public boolean changePlan(final String productName, final BillingPeriod term, final String priceList, final DateTime requestedDate,
             final CallContext context) throws EntitlementUserApiException {
         try {
-            checker.checkBlockedChange(this);
+            checker.checkBlockedChange(this, internalCallContextFactory.createInternalTenantContext(context));
         } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
@@ -87,7 +94,7 @@ public class BlockingSubscription implements Subscription {
     public boolean changePlanWithPolicy(final String productName, final BillingPeriod term, final String priceList,
             final DateTime requestedDate, final ActionPolicy policy, final CallContext context) throws EntitlementUserApiException {
         try {
-            checker.checkBlockedChange(this);
+            checker.checkBlockedChange(this, internalCallContextFactory.createInternalTenantContext(context));
         } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
@@ -183,7 +190,7 @@ public class BlockingSubscription implements Subscription {
     @Override
     public BlockingState getBlockingState() {
         if (blockingState == null) {
-            blockingState = blockingApi.getBlockingStateFor(this);
+            blockingState = blockingApi.getBlockingStateFor(this, context);
         }
         return blockingState;
     }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
index 2a26425..f5063e3 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
@@ -22,16 +22,19 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.OverdueState;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class BlockingSubscriptionBundle implements SubscriptionBundle {
     private final SubscriptionBundle subscriptionBundle;
     private final BlockingApi blockingApi;
+    private final TenantContext context;
 
     private BlockingState blockingState = null;
 
-    public BlockingSubscriptionBundle(final SubscriptionBundle subscriptionBundle, final BlockingApi blockingApi) {
+    public BlockingSubscriptionBundle(final SubscriptionBundle subscriptionBundle, final BlockingApi blockingApi, final TenantContext context) {
         this.subscriptionBundle = subscriptionBundle;
         this.blockingApi = blockingApi;
+        this.context = context;
     }
 
     public UUID getAccountId() {
@@ -53,7 +56,7 @@ public class BlockingSubscriptionBundle implements SubscriptionBundle {
     @Override
     public BlockingState getBlockingState() {
         if (blockingState == null) {
-            blockingState = blockingApi.getBlockingStateFor(this);
+            blockingState = blockingApi.getBlockingStateFor(this, context);
         }
         return blockingState;
     }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
index 0580d60..2500c09 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
@@ -42,6 +42,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.callcontext.TenantContext;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.Inject;
@@ -59,7 +60,7 @@ public class BillCycleDayCalculator {
         this.entitlementApi = entitlementApi;
     }
 
-    protected BillCycleDay calculateBcd(final SubscriptionBundle bundle, final Subscription subscription, final EffectiveSubscriptionEvent transition, final Account account)
+    protected BillCycleDay calculateBcd(final SubscriptionBundle bundle, final Subscription subscription, final EffectiveSubscriptionEvent transition, final Account account, final TenantContext context)
             throws CatalogApiException, AccountApiException, EntitlementUserApiException {
 
         final Catalog catalog = catalogService.getFullCatalog();
@@ -83,12 +84,12 @@ public class BillCycleDayCalculator {
                                        phase.getPhaseType()),
                 transition.getRequestedTransitionTime());
 
-        return calculateBcdForAlignment(alignment, bundle, subscription, account, catalog, plan);
+        return calculateBcdForAlignment(alignment, bundle, subscription, account, catalog, plan, context);
     }
 
     @VisibleForTesting
     BillCycleDay calculateBcdForAlignment(final BillingAlignment alignment, final SubscriptionBundle bundle, final Subscription subscription,
-                                          final Account account, final Catalog catalog, final Plan plan) throws AccountApiException, EntitlementUserApiException, CatalogApiException {
+                                          final Account account, final Catalog catalog, final Plan plan, final TenantContext context) throws AccountApiException, EntitlementUserApiException, CatalogApiException {
         BillCycleDay result = null;
         switch (alignment) {
             case ACCOUNT:
@@ -98,7 +99,7 @@ public class BillCycleDayCalculator {
                 }
                 break;
             case BUNDLE:
-                final Subscription baseSub = entitlementApi.getBaseSubscription(bundle.getId());
+                final Subscription baseSub = entitlementApi.getBaseSubscription(bundle.getId(), context);
                 Plan basePlan = baseSub.getCurrentPlan();
                 if (basePlan == null) {
                     // The BP has been cancelled
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
index 191d8fb..658bed4 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
@@ -40,6 +40,7 @@ import com.ning.billing.entitlement.api.billing.BillingModeType;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.callcontext.CallContext;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.Inject;
@@ -79,7 +80,7 @@ public class BlockingCalculator {
      *
      * @param billingEvents the original list of billing events to update (without overdue events)
      */
-    public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents) {
+    public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents, final CallContext context) {
         if (billingEvents.size() <= 0) {
             return;
         }
@@ -92,8 +93,8 @@ public class BlockingCalculator {
         final SortedSet<BillingEvent> billingEventsToRemove = new TreeSet<BillingEvent>();
 
         for (final UUID bundleId : bundleMap.keySet()) {
-            final List<BlockingState> blockingEvents = blockingApi.getBlockingHistory(bundleId);
-            blockingEvents.addAll(blockingApi.getBlockingHistory(account.getId()));
+            final List<BlockingState> blockingEvents = blockingApi.getBlockingHistory(bundleId, context);
+            blockingEvents.addAll(blockingApi.getBlockingHistory(account.getId(), context));
             final List<DisabledDuration> blockingDurations = createBlockingDurations(blockingEvents);
 
             for (final Subscription subscription : bundleMap.get(bundleId)) {
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
index 9d30ca4..c0fbc3f 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
@@ -21,7 +21,6 @@ import java.util.Map;
 import java.util.SortedSet;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,8 +45,7 @@ import com.ning.billing.junction.api.BillingEventSet;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
@@ -82,18 +80,19 @@ public class DefaultBillingApi implements BillingApi {
     }
 
     @Override
-    public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId) {
-        final CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
+    public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId, final CallContext context) {
+        // TODO
+        //final CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
 
-        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId, context);
         final DefaultBillingEventSet result = new DefaultBillingEventSet();
 
         try {
-            final Account account = accountApi.getAccountById(accountId);
+            final Account account = accountApi.getAccountById(accountId, context);
 
             // Check to see if billing is off for the account
-            final Map<String, Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT);
-            for (Tag cur : accountTags.values()) {
+            final Map<String, Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT, context);
+            for (final Tag cur : accountTags.values()) {
                 if (ControlTagType.AUTO_INVOICING_OFF.getId().equals(cur.getTagDefinitionId())) {
                     result.setAccountAutoInvoiceIsOff(true);
                     return result; // billing is off, we are done
@@ -106,7 +105,7 @@ public class DefaultBillingApi implements BillingApi {
         }
 
         debugLog(result, "********* Billing Events Raw");
-        blockCalculator.insertBlockingEvents(result);
+        blockCalculator.insertBlockingEvents(result, context);
         debugLog(result, "*********  Billing Events After Blocking");
 
         return result;
@@ -123,13 +122,13 @@ public class DefaultBillingApi implements BillingApi {
     private void addBillingEventsForBundles(final List<SubscriptionBundle> bundles, final Account account, final CallContext context,
                                             final DefaultBillingEventSet result) {
         for (final SubscriptionBundle bundle : bundles) {
-            final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundle.getId(), context);
 
             //Check if billing is off for the bundle
-            final Map<String, Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE);
+            final Map<String, Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE, context);
 
             boolean found_AUTO_INVOICING_OFF = false;
-            for (Tag cur : bundleTags.values()) {
+            for (final Tag cur : bundleTags.values()) {
                 if (ControlTagType.AUTO_INVOICING_OFF.getId().equals(cur.getTagDefinitionId())) {
                     found_AUTO_INVOICING_OFF = true;
                     break;
@@ -149,7 +148,7 @@ public class DefaultBillingApi implements BillingApi {
         for (final Subscription subscription : subscriptions) {
             for (final EffectiveSubscriptionEvent transition : subscription.getBillingTransitions()) {
                 try {
-                    final BillCycleDay bcd = bcdCalculator.calculateBcd(bundle, subscription, transition, account);
+                    final BillCycleDay bcd = bcdCalculator.calculateBcd(bundle, subscription, transition, account, context);
 
                     if (account.getBillCycleDay().getDayOfMonthUTC() == 0) {
                         final MutableAccountData modifiedData = account.toMutableAccountData();
@@ -170,8 +169,8 @@ public class DefaultBillingApi implements BillingApi {
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) throws EntitlementBillingApiException {
-        final UUID result = chargeThruApi.getAccountIdFromSubscriptionId(subscriptionId);
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final TenantContext context) throws EntitlementBillingApiException {
+        final UUID result = chargeThruApi.getAccountIdFromSubscriptionId(subscriptionId, context);
         if (result == null) {
             throw new EntitlementBillingApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId.toString());
         }
diff --git a/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg b/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
index ebe39e2..608db22 100644
--- a/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
+++ b/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group BlockingStateSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getBlockingStateFor() ::= <<
     select
         id
@@ -9,9 +12,11 @@ getBlockingStateFor() ::= <<
       , block_change
       , block_entitlement
       , block_billing
-      , created_date   
+      , created_date
+      , tenant_record_id
     from blocking_states
     where id = :id
+    <AND_CHECK_TENANT()>
     -- We want the current state, hence the order desc and limit 1
     order by created_date desc, record_id desc
     limit 1
@@ -27,9 +32,11 @@ getBlockingHistoryFor() ::= <<
       , block_change
       , block_entitlement
       , block_billing
-      , created_date   
+      , created_date
+      , tenant_record_id
     from blocking_states
     where id = :id
+    <AND_CHECK_TENANT()>
     -- We want the history in order
     order by created_date asc, record_id asc
     ;
@@ -44,7 +51,9 @@ setBlockingState() ::= <<
       , block_change
       , block_entitlement
       , block_billing
-      , created_date   
+      , created_date
+      , account_record_id
+      , tenant_record_id
     ) values (
         :id
       , :state
@@ -52,7 +61,9 @@ setBlockingState() ::= <<
       , :service
       , :block_change
       , :block_entitlement
-      , :block_billing   
-      , :created_date 
+      , :block_billing
+      , :created_date
+      , :accountRecordId
+      , :tenantRecordId
     );
 >>
diff --git a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
index 378fe68..d0306b3 100644
--- a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
@@ -17,7 +17,6 @@
 package com.ning.billing.junction.api.blocking;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import org.mockito.Mockito;
@@ -26,7 +25,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.JunctionTestSuiteWithEmbeddedDB;
 import com.ning.billing.junction.MockModule;
@@ -37,6 +35,8 @@ import com.ning.billing.junction.api.DefaultBlockingState;
 import com.ning.billing.mock.glue.MockEntitlementModule;
 import com.ning.billing.util.clock.ClockMock;
 
+import com.google.inject.Inject;
+
 @Guice(modules = {MockModule.class, MockEntitlementModule.class})
 public class TestBlockingApi extends JunctionTestSuiteWithEmbeddedDB {
     @Inject
@@ -61,18 +61,18 @@ public class TestBlockingApi extends JunctionTestSuiteWithEmbeddedDB {
         final boolean blockBilling = false;
 
         final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        api.setBlockingState(state1);
+        api.setBlockingState(state1, callContext);
         clock.setDeltaFromReality(1000 * 3600 * 24);
 
         final String overdueStateName2 = "NoReallyThisCantGoOn";
         final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        api.setBlockingState(state2);
+        api.setBlockingState(state2, callContext);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(uuid);
 
-        Assert.assertEquals(api.getBlockingStateFor(bundle).getStateName(), overdueStateName2);
-        Assert.assertEquals(api.getBlockingStateFor(bundle.getId()).getStateName(), overdueStateName2);
+        Assert.assertEquals(api.getBlockingStateFor(bundle, callContext).getStateName(), overdueStateName2);
+        Assert.assertEquals(api.getBlockingStateFor(bundle.getId(), callContext).getStateName(), overdueStateName2);
     }
 
     @Test(groups = "slow")
@@ -86,19 +86,19 @@ public class TestBlockingApi extends JunctionTestSuiteWithEmbeddedDB {
         final boolean blockBilling = false;
 
         final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        api.setBlockingState(state1);
+        api.setBlockingState(state1, callContext);
 
         clock.setDeltaFromReality(1000 * 3600 * 24);
 
         final String overdueStateName2 = "NoReallyThisCantGoOn";
         final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        api.setBlockingState(state2);
+        api.setBlockingState(state2, callContext);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(uuid);
 
-        final List<BlockingState> history1 = api.getBlockingHistory(bundle);
-        final List<BlockingState> history2 = api.getBlockingHistory(bundle.getId());
+        final List<BlockingState> history1 = api.getBlockingHistory(bundle, callContext);
+        final List<BlockingState> history2 = api.getBlockingHistory(bundle.getId(), callContext);
 
         Assert.assertEquals(history1.size(), 2);
         Assert.assertEquals(history1.get(0).getStateName(), overdueStateName);
diff --git a/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java b/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
index d1c5ff7..8b343ae 100644
--- a/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
+++ b/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
@@ -17,7 +17,6 @@
 package com.ning.billing.junction.blocking;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import org.mockito.Mockito;
@@ -25,9 +24,6 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -41,8 +37,15 @@ import com.ning.billing.junction.api.DefaultBlockingState;
 import com.ning.billing.junction.block.BlockingChecker;
 import com.ning.billing.junction.block.DefaultBlockingChecker;
 import com.ning.billing.junction.dao.BlockingStateDao;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
 public class TestBlockingChecker extends JunctionTestSuite {
     private BlockingState bundleState;
     private BlockingState subscriptionState;
@@ -50,7 +53,7 @@ public class TestBlockingChecker extends JunctionTestSuite {
 
     private final BlockingStateDao dao = new BlockingStateDao() {
         @Override
-        public BlockingState getBlockingStateFor(final Blockable blockable) {
+        public BlockingState getBlockingStateFor(final Blockable blockable, final InternalTenantContext context) {
             if (blockable.getId() == account.getId()) {
                 return accountState;
             } else if (blockable.getId() == subscription.getId()) {
@@ -61,7 +64,7 @@ public class TestBlockingChecker extends JunctionTestSuite {
         }
 
         @Override
-        public BlockingState getBlockingStateFor(final UUID blockableId) {
+        public BlockingState getBlockingStateFor(final UUID blockableId, final InternalTenantContext context) {
             if (blockableId == account.getId()) {
                 return accountState;
             } else if (blockableId == subscription.getId()) {
@@ -72,17 +75,17 @@ public class TestBlockingChecker extends JunctionTestSuite {
         }
 
         @Override
-        public List<BlockingState> getBlockingHistoryFor(final Blockable overdueable) {
+        public List<BlockingState> getBlockingHistoryFor(final Blockable overdueable, final InternalTenantContext context) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public List<BlockingState> getBlockingHistoryFor(final UUID overdueableId) {
+        public List<BlockingState> getBlockingHistoryFor(final UUID overdueableId, final InternalTenantContext context) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public <T extends Blockable> void setBlockingState(final BlockingState state, final Clock clock) {
+        public <T extends Blockable> void setBlockingState(final BlockingState state, final Clock clock, final InternalCallContext context) {
             throw new UnsupportedOperationException();
         }
 
@@ -118,7 +121,7 @@ public class TestBlockingChecker extends JunctionTestSuite {
                 final EntitlementUserApi entitlementUserApi = Mockito.mock(EntitlementUserApi.class);
                 bind(EntitlementUserApi.class).toInstance(entitlementUserApi);
                 try {
-                    Mockito.when(entitlementUserApi.getBundleFromId(Mockito.<UUID>any())).thenReturn(bundle);
+                    Mockito.when(entitlementUserApi.getBundleFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(bundle);
                 } catch (EntitlementUserApiException e) {
                     Assert.fail(e.toString());
                 }
@@ -146,36 +149,36 @@ public class TestBlockingChecker extends JunctionTestSuite {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
         setStateSubscription(false, false, false);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedEntitlement(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
 
         //BLOCKED SUBSCRIPTION
         setStateSubscription(true, false, false);
-        checker.checkBlockedEntitlement(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedChange(subscription);
+            checker.checkBlockedChange(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateSubscription(false, true, false);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(subscription);
+            checker.checkBlockedEntitlement(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateSubscription(false, false, true);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedEntitlement(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
         try {
-            checker.checkBlockedBilling(subscription);
+            checker.checkBlockedBilling(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
@@ -184,30 +187,30 @@ public class TestBlockingChecker extends JunctionTestSuite {
         //BLOCKED BUNDLE
         setStateSubscription(false, false, false);
         setStateBundle(true, false, false);
-        checker.checkBlockedEntitlement(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedChange(subscription);
+            checker.checkBlockedChange(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateBundle(false, true, false);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(subscription);
+            checker.checkBlockedEntitlement(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateBundle(false, false, true);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedEntitlement(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
         try {
-            checker.checkBlockedBilling(subscription);
+            checker.checkBlockedBilling(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
@@ -217,30 +220,30 @@ public class TestBlockingChecker extends JunctionTestSuite {
         setStateSubscription(false, false, false);
         setStateBundle(false, false, false);
         setStateAccount(true, false, false);
-        checker.checkBlockedEntitlement(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedChange(subscription);
+            checker.checkBlockedChange(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, true, false);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedBilling(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedBilling(subscription, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(subscription);
+            checker.checkBlockedEntitlement(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, false, true);
-        checker.checkBlockedChange(subscription);
-        checker.checkBlockedEntitlement(subscription);
+        checker.checkBlockedChange(subscription, internalCallContext);
+        checker.checkBlockedEntitlement(subscription, internalCallContext);
         try {
-            checker.checkBlockedBilling(subscription);
+            checker.checkBlockedBilling(subscription, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
@@ -252,37 +255,37 @@ public class TestBlockingChecker extends JunctionTestSuite {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
         setStateSubscription(false, false, false);
-        checker.checkBlockedChange(bundle);
-        checker.checkBlockedEntitlement(bundle);
-        checker.checkBlockedBilling(bundle);
+        checker.checkBlockedChange(bundle, internalCallContext);
+        checker.checkBlockedEntitlement(bundle, internalCallContext);
+        checker.checkBlockedBilling(bundle, internalCallContext);
 
         //BLOCKED BUNDLE
         setStateSubscription(false, false, false);
         setStateBundle(true, false, false);
-        checker.checkBlockedEntitlement(bundle);
-        checker.checkBlockedBilling(bundle);
+        checker.checkBlockedEntitlement(bundle, internalCallContext);
+        checker.checkBlockedBilling(bundle, internalCallContext);
         try {
-            checker.checkBlockedChange(bundle);
+            checker.checkBlockedChange(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateBundle(false, true, false);
-        checker.checkBlockedChange(bundle);
-        checker.checkBlockedBilling(bundle);
+        checker.checkBlockedChange(bundle, internalCallContext);
+        checker.checkBlockedBilling(bundle, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(bundle);
+            checker.checkBlockedEntitlement(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateBundle(false, false, true);
-        checker.checkBlockedChange(bundle);
-        checker.checkBlockedEntitlement(bundle);
+        checker.checkBlockedChange(bundle, internalCallContext);
+        checker.checkBlockedEntitlement(bundle, internalCallContext);
         try {
-            checker.checkBlockedBilling(bundle);
+            checker.checkBlockedBilling(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
@@ -292,30 +295,30 @@ public class TestBlockingChecker extends JunctionTestSuite {
         setStateSubscription(false, false, false);
         setStateBundle(false, false, false);
         setStateAccount(true, false, false);
-        checker.checkBlockedEntitlement(bundle);
-        checker.checkBlockedBilling(bundle);
+        checker.checkBlockedEntitlement(bundle, internalCallContext);
+        checker.checkBlockedBilling(bundle, internalCallContext);
         try {
-            checker.checkBlockedChange(bundle);
+            checker.checkBlockedChange(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, true, false);
-        checker.checkBlockedChange(bundle);
-        checker.checkBlockedBilling(bundle);
+        checker.checkBlockedChange(bundle, internalCallContext);
+        checker.checkBlockedBilling(bundle, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(bundle);
+            checker.checkBlockedEntitlement(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, false, true);
-        checker.checkBlockedChange(bundle);
-        checker.checkBlockedEntitlement(bundle);
+        checker.checkBlockedChange(bundle, internalCallContext);
+        checker.checkBlockedEntitlement(bundle, internalCallContext);
         try {
-            checker.checkBlockedBilling(bundle);
+            checker.checkBlockedBilling(bundle, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
@@ -327,38 +330,38 @@ public class TestBlockingChecker extends JunctionTestSuite {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
         setStateSubscription(false, false, false);
-        checker.checkBlockedChange(account);
-        checker.checkBlockedEntitlement(account);
-        checker.checkBlockedBilling(account);
+        checker.checkBlockedChange(account, internalCallContext);
+        checker.checkBlockedEntitlement(account, internalCallContext);
+        checker.checkBlockedBilling(account, internalCallContext);
 
         //BLOCKED ACCOUNT
         setStateSubscription(false, false, false);
         setStateBundle(false, false, false);
         setStateAccount(true, false, false);
-        checker.checkBlockedEntitlement(account);
-        checker.checkBlockedBilling(account);
+        checker.checkBlockedEntitlement(account, internalCallContext);
+        checker.checkBlockedBilling(account, internalCallContext);
         try {
-            checker.checkBlockedChange(account);
+            checker.checkBlockedChange(account, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, true, false);
-        checker.checkBlockedChange(account);
-        checker.checkBlockedBilling(account);
+        checker.checkBlockedChange(account, internalCallContext);
+        checker.checkBlockedBilling(account, internalCallContext);
         try {
-            checker.checkBlockedEntitlement(account);
+            checker.checkBlockedEntitlement(account, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
 
         setStateAccount(false, false, true);
-        checker.checkBlockedChange(account);
-        checker.checkBlockedEntitlement(account);
+        checker.checkBlockedChange(account, internalCallContext);
+        checker.checkBlockedEntitlement(account, internalCallContext);
         try {
-            checker.checkBlockedBilling(account);
+            checker.checkBlockedBilling(account, internalCallContext);
             Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
diff --git a/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java b/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
index 55d7e5a..da53d11 100644
--- a/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
+++ b/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
@@ -17,7 +17,6 @@
 package com.ning.billing.junction.dao;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import org.mockito.Mockito;
@@ -25,7 +24,6 @@ import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.JunctionTestSuiteWithEmbeddedDB;
 import com.ning.billing.junction.MockModule;
@@ -33,13 +31,21 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.api.DefaultBlockingState;
 import com.ning.billing.mock.glue.MockEntitlementModule;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.ClockMock;
 
+import com.google.inject.Inject;
+
 @Guice(modules = {MockModule.class, MockEntitlementModule.class})
 public class TestBlockingDao extends JunctionTestSuiteWithEmbeddedDB {
+
     @Inject
     private BlockingStateDao dao;
 
+    private final InternalTenantContext tenantContext = Mockito.mock(InternalTenantContext.class);
+    private final InternalCallContext context = Mockito.mock(InternalCallContext.class);
+
     @Test(groups = "slow")
     public void testDao() {
         final ClockMock clock = new ClockMock();
@@ -52,18 +58,18 @@ public class TestBlockingDao extends JunctionTestSuiteWithEmbeddedDB {
         final boolean blockBilling = false;
 
         final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        dao.setBlockingState(state1, clock);
+        dao.setBlockingState(state1, clock, context);
         clock.setDeltaFromReality(1000 * 3600 * 24);
 
         final String overdueStateName2 = "NoReallyThisCantGoOn";
         final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        dao.setBlockingState(state2, clock);
+        dao.setBlockingState(state2, clock, context);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(uuid);
 
-        Assert.assertEquals(dao.getBlockingStateFor(bundle).getStateName(), state2.getStateName());
-        Assert.assertEquals(dao.getBlockingStateFor(bundle.getId()).getStateName(), overdueStateName2);
+        Assert.assertEquals(dao.getBlockingStateFor(bundle, tenantContext).getStateName(), state2.getStateName());
+        Assert.assertEquals(dao.getBlockingStateFor(bundle.getId(), tenantContext).getStateName(), overdueStateName2);
     }
 
     @Test(groups = "slow")
@@ -78,18 +84,18 @@ public class TestBlockingDao extends JunctionTestSuiteWithEmbeddedDB {
         final boolean blockBilling = false;
 
         final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        dao.setBlockingState(state1, clock);
+        dao.setBlockingState(state1, clock, context);
         clock.setDeltaFromReality(1000 * 3600 * 24);
 
         final String overdueStateName2 = "NoReallyThisCantGoOn";
         final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
-        dao.setBlockingState(state2, clock);
+        dao.setBlockingState(state2, clock, context);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(uuid);
 
-        final List<BlockingState> history1 = dao.getBlockingHistoryFor(bundle);
-        final List<BlockingState> history2 = dao.getBlockingHistoryFor(bundle.getId());
+        final List<BlockingState> history1 = dao.getBlockingHistoryFor(bundle, tenantContext);
+        final List<BlockingState> history2 = dao.getBlockingHistoryFor(bundle.getId(), tenantContext);
 
         Assert.assertEquals(history1.size(), 2);
         Assert.assertEquals(history1.get(0).getStateName(), overdueStateName);
diff --git a/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java b/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
index 3158d68..c20ef92 100644
--- a/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
+++ b/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
@@ -18,10 +18,11 @@ package com.ning.billing.junction;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.dao.BlockingStateDao;
 
+import com.google.inject.AbstractModule;
+
 public class MockBlockingModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
index fc10afb..0a8786c 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
@@ -36,8 +36,10 @@ import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.junction.JunctionTestSuite;
+import com.ning.billing.util.callcontext.TenantContext;
 
-public class TestBillCycleDayCalculator {
+public class TestBillCycleDayCalculator extends JunctionTestSuite {
 
     @Test(groups = "fast")
     public void testCalculateBCDForAOWithBPCancelledBundleAligned() throws Exception {
@@ -57,7 +59,7 @@ public class TestBillCycleDayCalculator {
         Mockito.when(subscription.getStartDate()).thenReturn(bpStartDateUTC);
         Mockito.when(subscription.getPreviousTransition()).thenReturn(previousTransition);
         // subscription.getCurrentPlan() will return null as expected (cancelled BP)
-        Mockito.when(entitlementUserApi.getBaseSubscription(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementUserApi.getBaseSubscription(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         // Create a the base plan associated with that subscription
         final Plan plan = Mockito.mock(Plan.class);
@@ -68,7 +70,7 @@ public class TestBillCycleDayCalculator {
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
         final BillCycleDay billCycleDay = billCycleDayCalculator.calculateBcdForAlignment(BillingAlignment.BUNDLE, bundle, subscription,
-                                                                                          account, catalog, null);
+                                                                                          account, catalog, null, callContext);
 
         Assert.assertEquals(billCycleDay.getDayOfMonthUTC(), expectedBCDUTC);
     }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
index 20dd293..04ecf73 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
@@ -68,8 +68,10 @@ import com.ning.billing.mock.MockEffectiveSubscriptionEvent;
 import com.ning.billing.mock.MockSubscription;
 import com.ning.billing.mock.api.MockBillCycleDay;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.dao.ObjectType;
@@ -97,7 +99,7 @@ public class TestBillingApi extends JunctionTestSuite {
 
     private final BlockingCalculator blockCalculator = new BlockingCalculator(null) {
         @Override
-        public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents) {
+        public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents, final CallContext context) {
         }
     };
 
@@ -135,11 +137,11 @@ public class TestBillingApi extends JunctionTestSuite {
         subscriptions.add(subscription);
 
         entitlementApi = Mockito.mock(EntitlementUserApi.class);
-        Mockito.when(entitlementApi.getBundlesForAccount(Mockito.<UUID>any())).thenReturn(bundles);
-        Mockito.when(entitlementApi.getSubscriptionsForBundle(Mockito.<UUID>any())).thenReturn(subscriptions);
-        Mockito.when(entitlementApi.getSubscriptionFromId(Mockito.<UUID>any())).thenReturn(subscription);
-        Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any())).thenReturn(bundle);
-        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementApi.getBundlesForAccount(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(bundles);
+        Mockito.when(entitlementApi.getSubscriptionsForBundle(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscriptions);
+        Mockito.when(entitlementApi.getSubscriptionFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
+        Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(bundle);
+        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         tagApi = mock(TagUserApi.class);
 
@@ -153,7 +155,7 @@ public class TestBillingApi extends JunctionTestSuite {
 
     @Test(groups = "fast")
     public void testBillingEventsEmpty() throws AccountApiException {
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L), callContext);
         Assert.assertEquals(events.size(), 0);
     }
 
@@ -166,7 +168,7 @@ public class TestBillingApi extends JunctionTestSuite {
 
         final Account account = createAccount(10);
 
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
         checkFirstEvent(events, nextPlan, account.getBillCycleDay().getDayOfMonthUTC(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
     }
 
@@ -180,7 +182,7 @@ public class TestBillingApi extends JunctionTestSuite {
 
         ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.SUBSCRIPTION);
 
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
         // The expected BCD is when the subscription started since we skip the trial phase
         checkFirstEvent(events, nextPlan, subscription.getStartDate().getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
     }
@@ -193,7 +195,7 @@ public class TestBillingApi extends JunctionTestSuite {
 
         final Account account = createAccount(32);
 
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
         // The expected BCD is the account BCD (account aligned by default)
         checkFirstEvent(events, nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
     }
@@ -209,7 +211,7 @@ public class TestBillingApi extends JunctionTestSuite {
         ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.BUNDLE);
         ((MockSubscription) subscription).setPlan(catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now));
 
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
         // The expected BCD is when the subscription started
         checkFirstEvent(events, nextPlan, subscription.getStartDate().getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
     }
@@ -228,21 +230,21 @@ public class TestBillingApi extends JunctionTestSuite {
 
         final BlockingCalculator blockingCal = new BlockingCalculator(new BlockingApi() {
             @Override
-            public <T extends Blockable> void setBlockingState(final BlockingState state) {
+            public <T extends Blockable> void setBlockingState(final BlockingState state, final CallContext context) {
             }
 
             @Override
-            public BlockingState getBlockingStateFor(final UUID overdueableId) {
+            public BlockingState getBlockingStateFor(final UUID overdueableId, final TenantContext context) {
                 return null;
             }
 
             @Override
-            public BlockingState getBlockingStateFor(final Blockable overdueable) {
+            public BlockingState getBlockingStateFor(final Blockable overdueable, final TenantContext context) {
                 return null;
             }
 
             @Override
-            public List<BlockingState> getBlockingHistory(final UUID overdueableId) {
+            public List<BlockingState> getBlockingHistory(final UUID overdueableId, final TenantContext context) {
                 if (overdueableId == bunId) {
                     return blockingStates;
                 }
@@ -250,13 +252,13 @@ public class TestBillingApi extends JunctionTestSuite {
             }
 
             @Override
-            public List<BlockingState> getBlockingHistory(final Blockable overdueable) {
+            public List<BlockingState> getBlockingHistory(final Blockable overdueable, final TenantContext context) {
                 return new ArrayList<BlockingState>();
             }
         });
 
         final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockingCal, catalogService, tagApi);
-        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
 
         Assert.assertEquals(events.size(), 3);
         final Iterator<BillingEvent> it = events.iterator();
@@ -278,10 +280,10 @@ public class TestBillingApi extends JunctionTestSuite {
         final Tag aioTag = mock(Tag.class);
         when(aioTag.getTagDefinitionId()).thenReturn(ControlTagType.AUTO_INVOICING_OFF.getId());
         tags.put(ControlTagType.AUTO_INVOICING_OFF.name(), aioTag);
-        when(tagApi.getTags(account.getId(), ObjectType.ACCOUNT)).thenReturn(tags);
-        assertEquals(tagApi.getTags(account.getId(), ObjectType.ACCOUNT), tags);
+        when(tagApi.getTags(account.getId(), ObjectType.ACCOUNT, callContext)).thenReturn(tags);
+        assertEquals(tagApi.getTags(account.getId(), ObjectType.ACCOUNT, callContext), tags);
 
-        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
 
         assertEquals(events.isAccountAutoInvoiceOff(), true);
         assertEquals(events.size(), 0);
@@ -299,9 +301,9 @@ public class TestBillingApi extends JunctionTestSuite {
         final Tag aioTag = mock(Tag.class);
         when(aioTag.getTagDefinitionId()).thenReturn(ControlTagType.AUTO_INVOICING_OFF.getId());
         tags.put(ControlTagType.AUTO_INVOICING_OFF.name(), aioTag);
-        when(tagApi.getTags(bunId, ObjectType.BUNDLE)).thenReturn(tags);
+        when(tagApi.getTags(bunId, ObjectType.BUNDLE, callContext)).thenReturn(tags);
 
-        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), callContext);
 
         assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().size(), 1);
         assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().get(0), subId);
@@ -346,7 +348,7 @@ public class TestBillingApi extends JunctionTestSuite {
         Mockito.when(account.getCurrency()).thenReturn(Currency.USD);
         Mockito.when(account.getId()).thenReturn(UUID.randomUUID());
         Mockito.when(account.getTimeZone()).thenReturn(DateTimeZone.UTC);
-        Mockito.when(accountApi.getAccountById(Mockito.<UUID>any())).thenReturn(account);
+        Mockito.when(accountApi.getAccountById(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(account);
         return account;
     }
 
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
index acd17e0..c2df046 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
@@ -139,9 +139,9 @@ public class TestBlockingCalculator extends JunctionTestSuite {
         blockingStates.add(new DefaultBlockingState(bundleId1, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now));
         blockingStates.add(new DefaultBlockingState(bundleId1, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
 
-        Mockito.when(blockingApi.getBlockingHistory(bundleId1)).thenReturn(blockingStates);
+        Mockito.when(blockingApi.getBlockingHistory(bundleId1, callContext)).thenReturn(blockingStates);
 
-        odc.insertBlockingEvents(billingEvents);
+        odc.insertBlockingEvents(billingEvents, callContext);
 
         assertEquals(billingEvents.size(), 7);
 
@@ -751,9 +751,9 @@ public class TestBlockingCalculator extends JunctionTestSuite {
         blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
         blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
 
-        Mockito.when(blockingApi.getBlockingHistory(bundleId1)).thenReturn(blockingEvents);
+        Mockito.when(blockingApi.getBlockingHistory(bundleId1, callContext)).thenReturn(blockingEvents);
 
-        odc.insertBlockingEvents(billingEvents);
+        odc.insertBlockingEvents(billingEvents, callContext);
 
         assertEquals(billingEvents.size(), 5);
         final List<BillingEvent> events = new ArrayList<BillingEvent>(billingEvents);
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
index 5c90516..ed401f1 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
@@ -22,14 +22,16 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.service.DefaultOverdueService;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
+import com.google.inject.Inject;
+
 public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
     private static final Logger log = LoggerFactory.getLogger(DefaultOverdueCheckNotifier.class);
 
@@ -43,14 +45,14 @@ public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
     }
 
     @Override
-    public void insertOverdueCheckNotification(final Blockable overdueable, final DateTime futureNotificationTime) {
+    public void insertOverdueCheckNotification(final Blockable overdueable, final DateTime futureNotificationTime, final InternalCallContext context) {
         final NotificationQueue checkOverdueQueue;
         try {
             checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
                                                                               DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
             log.info("Queuing overdue check notification. id: {}, timestamp: {}", overdueable.getId().toString(), futureNotificationTime.toString());
 
-            checkOverdueQueue.recordFutureNotification(futureNotificationTime, null, new OverdueCheckNotificationKey(overdueable.getId(), Blockable.Type.get(overdueable)));
+            checkOverdueQueue.recordFutureNotification(futureNotificationTime, null, new OverdueCheckNotificationKey(overdueable.getId(), Blockable.Type.get(overdueable)), context);
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to put items on a non-existent queue (DefaultOverdueCheck).", e);
         } catch (IOException e) {
@@ -60,7 +62,7 @@ public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
 
 
     @Override
-    public void clearNotificationsFor(final Blockable overdueable) {
+    public void clearNotificationsFor(final Blockable overdueable, final InternalCallContext context) {
         final NotificationQueue checkOverdueQueue;
         try {
             checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
@@ -71,7 +73,7 @@ public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
                     return overdueable.getId().toString();
                 }
             };
-            checkOverdueQueue.removeNotificationsByKey(key);
+            checkOverdueQueue.removeNotificationsByKey(key, context);
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to clear items from a non-existent queue (DefaultOverdueCheck).", e);
         }
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
index 18f492a..826765e 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
@@ -19,12 +19,12 @@ package com.ning.billing.ovedue.notification;
 import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.Blockable;
-
+import com.ning.billing.util.callcontext.InternalCallContext;
 
 public interface OverdueCheckPoster {
 
-    void insertOverdueCheckNotification(Blockable blockable, DateTime futureNotificationTime);
+    void insertOverdueCheckNotification(Blockable blockable, DateTime futureNotificationTime, final InternalCallContext context);
 
-    void clearNotificationsFor(Blockable blockable);
+    void clearNotificationsFor(Blockable blockable, final InternalCallContext context);
 
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index 3e5ffa5..1ba62b3 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -19,9 +19,7 @@ package com.ning.billing.overdue.api;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
-import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
@@ -34,26 +32,34 @@ import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.overdue.config.api.OverdueStateSet;
 import com.ning.billing.overdue.wrapper.OverdueWrapper;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.inject.Inject;
 
 public class DefaultOverdueUserApi implements OverdueUserApi {
+
     Logger log = LoggerFactory.getLogger(DefaultOverdueUserApi.class);
 
     private final OverdueWrapperFactory factory;
     private final BlockingApi accessApi;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private OverdueConfig overdueConfig;
 
     @Inject
-    public DefaultOverdueUserApi(final OverdueWrapperFactory factory, final BlockingApi accessApi, final CatalogService catalogService) {
+    public DefaultOverdueUserApi(final OverdueWrapperFactory factory, final BlockingApi accessApi, final InternalCallContextFactory internalCallContextFactory) {
         this.factory = factory;
         this.accessApi = accessApi;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends Blockable> OverdueState<T> getOverdueStateFor(final T overdueable) throws OverdueException {
+    public <T extends Blockable> OverdueState<T> getOverdueStateFor(final T overdueable, final TenantContext context) throws OverdueException {
         try {
-            final String stateName = accessApi.getBlockingStateFor(overdueable).getStateName();
+            final String stateName = accessApi.getBlockingStateFor(overdueable, context).getStateName();
             final OverdueStateSet<SubscriptionBundle> states = overdueConfig.getBundleStateSet();
             return (OverdueState<T>) states.findState(stateName);
         } catch (OverdueApiException e) {
@@ -62,28 +68,26 @@ public class DefaultOverdueUserApi implements OverdueUserApi {
     }
 
     @Override
-    public <T extends Blockable> BillingState<T> getBillingStateFor(final T overdueable) throws OverdueException {
+    public <T extends Blockable> BillingState<T> getBillingStateFor(final T overdueable, final TenantContext context) throws OverdueException {
         log.info(String.format("Billing state of of %s requested", overdueable.getId()));
         final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
-        return wrapper.billingState();
+        return wrapper.billingState(internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(final T blockable) throws OverdueException, OverdueApiException {
+    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(final T blockable, final CallContext context) throws OverdueException, OverdueApiException {
         log.info(String.format("Refresh of %s requested", blockable.getId()));
         final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(blockable);
-        return wrapper.refresh();
+        // TODO accountId?
+        return wrapper.refresh(internalCallContextFactory.createInternalCallContext(context));
     }
 
-
     @Override
-    public <T extends Blockable> void setOverrideBillingStateForAccount(
-            final T overdueable, final BillingState<T> state) {
+    public <T extends Blockable> void setOverrideBillingStateForAccount(final T overdueable, final BillingState<T> state, final CallContext context) {
         throw new UnsupportedOperationException();
     }
 
     public void setOverdueConfig(final OverdueConfig config) {
         this.overdueConfig = config;
     }
-
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index 7492ae9..9fd004f 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -50,10 +50,9 @@ import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.email.DefaultEmailSender;
 import com.ning.billing.util.email.EmailApiException;
@@ -96,7 +95,8 @@ public class OverdueStateApplicator<T extends Blockable> {
     }
 
     public void apply(final OverdueState<T> firstOverdueState, final BillingState<T> billingState,
-                      final T overdueable, final String previousOverdueStateName, final OverdueState<T> nextOverdueState) throws OverdueException {
+                      final T overdueable, final String previousOverdueStateName,
+                      final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
         try {
             // We did not reach first state, we we need to check if there is any pending condition for which we will not receive
             // any notifications.. (last two conditions are there for test purpose)
@@ -104,7 +104,7 @@ public class OverdueStateApplicator<T extends Blockable> {
                 final LocalDate firstUnpaidInvoice = billingState.getDateOfEarliestUnpaidInvoice();
                 if (firstUnpaidInvoice != null) {
                     final Period reevaluationInterval = firstOverdueState.getReevaluationInterval();
-                    createFutureNotification(overdueable, firstUnpaidInvoice.toDateTimeAtCurrentTime().plus(reevaluationInterval));
+                    createFutureNotification(overdueable, firstUnpaidInvoice.toDateTimeAtCurrentTime().plus(reevaluationInterval), context);
                 }
             }
 
@@ -112,16 +112,16 @@ public class OverdueStateApplicator<T extends Blockable> {
                 return; // That's it, we are done...
             }
 
-            storeNewState(overdueable, nextOverdueState);
+            storeNewState(overdueable, nextOverdueState, context);
 
-            cancelSubscriptionsIfRequired(overdueable, nextOverdueState);
+            cancelSubscriptionsIfRequired(overdueable, nextOverdueState, context);
 
-            sendEmailIfRequired(billingState, overdueable, nextOverdueState);
+            sendEmailIfRequired(billingState, overdueable, nextOverdueState, context);
 
             // Add entry in notification queue
             final Period reevaluationInterval = nextOverdueState.getReevaluationInterval();
             if (!nextOverdueState.isClearState()) {
-                createFutureNotification(overdueable, clock.getUTCNow().plus(reevaluationInterval));
+                createFutureNotification(overdueable, clock.getUTCNow().plus(reevaluationInterval), context);
             }
         } catch (OverdueApiException e) {
             if (e.getCode() != ErrorCode.OVERDUE_NO_REEVALUATION_INTERVAL.getCode()) {
@@ -130,7 +130,7 @@ public class OverdueStateApplicator<T extends Blockable> {
         }
 
         if (nextOverdueState.isClearState()) {
-            clear(overdueable);
+            clear(overdueable, context);
         }
 
         try {
@@ -144,10 +144,16 @@ public class OverdueStateApplicator<T extends Blockable> {
         return new DefaultOverdueChangeEvent(overdueable.getId(), Blockable.Type.get(overdueable), previousOverdueStateName, nextOverdueStateName, null);
     }
 
-    protected void storeNewState(final T blockable, final OverdueState<T> nextOverdueState) throws OverdueException {
+    protected void storeNewState(final T blockable, final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
         try {
-            blockingApi.setBlockingState(new DefaultBlockingState(blockable.getId(), nextOverdueState.getName(), Blockable.Type.get(blockable),
-                                                                  OverdueService.OVERDUE_SERVICE_NAME, blockChanges(nextOverdueState), blockEntitlement(nextOverdueState), blockBilling(nextOverdueState)));
+            blockingApi.setBlockingState(new DefaultBlockingState(blockable.getId(),
+                                                                  nextOverdueState.getName(),
+                                                                  Blockable.Type.get(blockable),
+                                                                  OverdueService.OVERDUE_SERVICE_NAME,
+                                                                  blockChanges(nextOverdueState),
+                                                                  blockEntitlement(nextOverdueState),
+                                                                  blockBilling(nextOverdueState)),
+                                         context.toCallContext());
         } catch (Exception e) {
             throw new OverdueException(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, blockable.getId(), blockable.getClass().getName());
         }
@@ -165,16 +171,16 @@ public class OverdueStateApplicator<T extends Blockable> {
         return nextOverdueState.disableEntitlementAndChangesBlocked();
     }
 
-    protected void createFutureNotification(final T overdueable, final DateTime timeOfNextCheck) {
-        poster.insertOverdueCheckNotification(overdueable, timeOfNextCheck);
+    protected void createFutureNotification(final T overdueable, final DateTime timeOfNextCheck, final InternalCallContext context) {
+        poster.insertOverdueCheckNotification(overdueable, timeOfNextCheck, context);
     }
 
-    protected void clear(final T blockable) {
+    protected void clear(final T blockable, final InternalCallContext context) {
         // Need to clear the override table here too (when we add it)
-        poster.clearNotificationsFor(blockable);
+        poster.clearNotificationsFor(blockable, context);
     }
 
-    private void cancelSubscriptionsIfRequired(final T blockable, final OverdueState<T> nextOverdueState) throws OverdueException {
+    private void cancelSubscriptionsIfRequired(final T blockable, final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
         if (nextOverdueState.getSubscriptionCancellationPolicy() == OverdueCancellationPolicicy.NONE) {
             return;
         }
@@ -191,10 +197,9 @@ public class OverdueStateApplicator<T extends Blockable> {
                     throw new IllegalStateException("Unexpected OverdueCancellationPolicy " + nextOverdueState.getSubscriptionCancellationPolicy());
             }
             final List<Subscription> toBeCancelled = new LinkedList<Subscription>();
-            computeSubscriptionsToCancel(blockable, toBeCancelled);
-            final CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
+            computeSubscriptionsToCancel(blockable, toBeCancelled, context);
             for (final Subscription cur : toBeCancelled) {
-                cur.cancelWithPolicy(clock.getUTCNow(), actionPolicy, context);
+                cur.cancelWithPolicy(clock.getUTCNow(), actionPolicy, context.toCallContext());
             }
         } catch (EntitlementUserApiException e) {
             throw new OverdueException(e);
@@ -202,21 +207,22 @@ public class OverdueStateApplicator<T extends Blockable> {
     }
 
     @SuppressWarnings("unchecked")
-    private void computeSubscriptionsToCancel(final T blockable, final List<Subscription> result) throws EntitlementUserApiException {
+    private void computeSubscriptionsToCancel(final T blockable, final List<Subscription> result, final InternalTenantContext context) throws EntitlementUserApiException {
         if (blockable instanceof Subscription) {
             result.add((Subscription) blockable);
         } else if (blockable instanceof SubscriptionBundle) {
-            for (final Subscription cur : entitlementUserApi.getSubscriptionsForBundle(blockable.getId())) {
-                computeSubscriptionsToCancel((T) cur, result);
+            for (final Subscription cur : entitlementUserApi.getSubscriptionsForBundle(blockable.getId(), context.toTenantContext())) {
+                computeSubscriptionsToCancel((T) cur, result, context);
             }
         } else if (blockable instanceof Account) {
-            for (final SubscriptionBundle cur : entitlementUserApi.getBundlesForAccount(blockable.getId())) {
-                computeSubscriptionsToCancel((T) cur, result);
+            for (final SubscriptionBundle cur : entitlementUserApi.getBundlesForAccount(blockable.getId(), context.toTenantContext())) {
+                computeSubscriptionsToCancel((T) cur, result, context);
             }
         }
     }
 
-    private void sendEmailIfRequired(final BillingState<T> billingState, final T overdueable, final OverdueState<T> nextOverdueState) {
+    private void sendEmailIfRequired(final BillingState<T> billingState, final T overdueable,
+                                     final OverdueState<T> nextOverdueState, final InternalTenantContext context) {
         // Note: we don't want to fail the full refresh call because sending the email failed.
         // That's the reason why we catch all exceptions here.
         // The alternative would be to: throw new OverdueApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
@@ -232,12 +238,12 @@ public class OverdueStateApplicator<T extends Blockable> {
         try {
             if (Type.SUBSCRIPTION.equals(overdueableType)) {
                 final UUID bundleId = ((Subscription) overdueable).getBundleId();
-                final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
-                account = accountUserApi.getAccountById(bundle.getAccountId());
+                final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId, context.toTenantContext());
+                account = accountUserApi.getAccountById(bundle.getAccountId(), context.toTenantContext());
             } else if (Type.SUBSCRIPTION_BUNDLE.equals(overdueableType)) {
                 final UUID bundleId = ((SubscriptionBundle) overdueable).getId();
-                final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
-                account = accountUserApi.getAccountById(bundle.getAccountId());
+                final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId, context.toTenantContext());
+                account = accountUserApi.getAccountById(bundle.getAccountId(), context.toTenantContext());
             } else if (Type.ACCOUNT.equals(overdueableType)) {
                 account = (Account) overdueable;
             } else {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
index feb0bf4..8cbf13b 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
@@ -32,6 +32,7 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueException;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.inject.Inject;
@@ -60,7 +61,7 @@ public abstract class BillingStateCalculator<T extends Blockable> {
         this.clock = clock;
     }
 
-    public abstract BillingState<T> calculateBillingState(T overdueable) throws OverdueException;
+    public abstract BillingState<T> calculateBillingState(T overdueable, InternalTenantContext context) throws OverdueException;
 
     protected Invoice earliest(final SortedSet<Invoice> unpaidInvoices) {
         try {
@@ -78,8 +79,8 @@ public abstract class BillingStateCalculator<T extends Blockable> {
         return sum;
     }
 
-    protected SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId, final DateTimeZone accountTimeZone) {
-        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, clock.getToday(accountTimeZone));
+    protected SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId, final DateTimeZone accountTimeZone, final InternalTenantContext context) {
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, clock.getToday(accountTimeZone), context.toTenantContext());
         final SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new InvoiceDateComparator());
         sortedInvoices.addAll(invoices);
         return sortedInvoices;
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
index 3a5b607..1322bf1 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -21,12 +21,9 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 
-import com.google.inject.Inject;
-
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -44,9 +41,12 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.overdue.config.api.BillingStateBundle;
 import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.overdue.config.api.PaymentResponse;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.tag.Tag;
 
+import com.google.inject.Inject;
+
 public class BillingStateCalculatorBundle extends BillingStateCalculator<SubscriptionBundle> {
 
     private final EntitlementUserApi entitlementApi;
@@ -61,12 +61,12 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
     }
 
     @Override
-    public BillingStateBundle calculateBillingState(final SubscriptionBundle bundle) throws OverdueException {
+    public BillingStateBundle calculateBillingState(final SubscriptionBundle bundle, final InternalTenantContext context) throws OverdueException {
         try {
-            final Account account = accountApi.getAccountById(bundle.getAccountId());
-            final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId(), account.getTimeZone());
+            final Account account = accountApi.getAccountById(bundle.getAccountId(), context.toTenantContext());
+            final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId(), account.getTimeZone(), context);
 
-            final Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
+            final Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId(), context.toTenantContext());
 
             final UUID id = bundle.getId();
             final int numberOfUnpaidInvoices = unpaidInvoices.size();
@@ -117,8 +117,8 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
         }
     }
 
-    public SortedSet<Invoice> unpaidInvoicesForBundle(final UUID bundleId, final UUID accountId, final DateTimeZone accountTimeZone) {
-        final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(accountId, accountTimeZone);
+    public SortedSet<Invoice> unpaidInvoicesForBundle(final UUID bundleId, final UUID accountId, final DateTimeZone accountTimeZone, final InternalTenantContext context) {
+        final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(accountId, accountTimeZone, context);
         final SortedSet<Invoice> result = new TreeSet<Invoice>(new InvoiceDateComparator());
         result.addAll(unpaidInvoices);
         for (final Invoice invoice : unpaidInvoices) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
index e7dcda8..5be633a 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
@@ -22,7 +22,6 @@ import java.util.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
@@ -30,6 +29,9 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
+import com.ning.billing.util.callcontext.InternalCallContext;
+
+import com.google.inject.Inject;
 
 public class OverdueDispatcher {
     Logger log = LoggerFactory.getLogger(OverdueDispatcher.class);
@@ -45,25 +47,25 @@ public class OverdueDispatcher {
         this.factory = factory;
     }
 
-    public void processOverdueForAccount(final UUID accountId) {
-        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+    public void processOverdueForAccount(final UUID accountId, final InternalCallContext context) {
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId, context.toCallContext());
         for (final SubscriptionBundle bundle : bundles) {
-            processOverdue(bundle);
+            processOverdue(bundle, context);
         }
     }
 
-    public void processOverdueForBundle(final UUID bundleId) {
+    public void processOverdueForBundle(final UUID bundleId, final InternalCallContext context) {
         try {
-            final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
-            processOverdue(bundle);
+            final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId, context.toCallContext());
+            processOverdue(bundle, context);
         } catch (EntitlementUserApiException e) {
             log.error("Error processing Overdue for Bundle with id: " + bundleId.toString(), e);
         }
     }
 
-    public void processOverdue(final Blockable blockable) {
+    public void processOverdue(final Blockable blockable, final InternalCallContext context) {
         try {
-            factory.createOverdueWrapperFor(blockable).refresh();
+            factory.createOverdueWrapperFor(blockable).refresh(context);
         } catch (OverdueException e) {
             log.error("Error processing Overdue for Blockable with id: " + blockable.getId().toString(), e);
         } catch (OverdueApiException e) {
@@ -71,9 +73,9 @@ public class OverdueDispatcher {
         }
     }
 
-    public void processOverdue(final Blockable.Type type, final UUID blockableId) {
+    public void processOverdue(final Blockable.Type type, final UUID blockableId, final InternalCallContext context) {
         try {
-            factory.createOverdueWrapperFor(type, blockableId).refresh();
+            factory.createOverdueWrapperFor(type, blockableId, context).refresh(context);
         } catch (OverdueException e) {
             log.error("Error processing Overdue for Blockable with id: " + blockableId.toString(), e);
         } catch (OverdueApiException e) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
index b9c7c89..5cd0f54 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
@@ -18,6 +18,8 @@ package com.ning.billing.overdue.listener;
 
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -25,6 +27,11 @@ import com.ning.billing.invoice.api.InvoiceAdjustmentEvent;
 import com.ning.billing.ovedue.notification.OverdueCheckNotificationKey;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.bus.BusEvent;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
@@ -32,37 +39,45 @@ import com.google.inject.Inject;
 public class OverdueListener {
 
     private final OverdueDispatcher dispatcher;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private static final Logger log = LoggerFactory.getLogger(OverdueListener.class);
 
     @Inject
-    public OverdueListener(final OverdueDispatcher dispatcher) {
+    public OverdueListener(final OverdueDispatcher dispatcher,
+                           final InternalCallContextFactory internalCallContextFactory) {
         this.dispatcher = dispatcher;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Subscribe
     public void handlePaymentInfoEvent(final PaymentInfoEvent event) {
         log.info(String.format("Received PaymentInfo event %s", event.toString()));
-        dispatcher.processOverdueForAccount(event.getAccountId());
+        dispatcher.processOverdueForAccount(event.getAccountId(), createCallContext(event));
     }
 
     @Subscribe
     public void handlePaymentErrorEvent(final PaymentErrorEvent event) {
         log.info(String.format("Received PaymentError event %s", event.toString()));
         final UUID accountId = event.getAccountId();
-        dispatcher.processOverdueForAccount(accountId);
+        dispatcher.processOverdueForAccount(accountId, createCallContext(event));
     }
 
     @Subscribe
     public void handleInvoiceAdjustmentEvent(final InvoiceAdjustmentEvent event) {
         log.info(String.format("Received InvoiceAdjustment event %s", event.toString()));
         final UUID accountId = event.getAccountId();
-        dispatcher.processOverdueForAccount(accountId);
+        dispatcher.processOverdueForAccount(accountId, createCallContext(event));
     }
 
     public void handleNextOverdueCheck(final OverdueCheckNotificationKey notificationKey) {
         log.info(String.format("Received OD checkup notification for type = %s, id = %s",
                 notificationKey.getType(), notificationKey.getUuidKey()));
-        dispatcher.processOverdue(notificationKey.getType(), notificationKey.getUuidKey());
+        dispatcher.processOverdue(notificationKey.getType(), notificationKey.getUuidKey(), createCallContext(null));
+    }
+
+    private InternalCallContext createCallContext(@Nullable final BusEvent event) {
+        return internalCallContextFactory.createInternalCallContext("OverdueService", CallOrigin.INTERNAL, UserType.SYSTEM,
+                                                                    event == null ? null : event.getUserToken());
     }
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index e7330ac..be9569f 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -25,6 +25,8 @@ import com.ning.billing.overdue.calculator.BillingStateCalculator;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.overdue.config.api.OverdueStateSet;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 
 public class OverdueWrapper<T extends Blockable> {
@@ -48,21 +50,21 @@ public class OverdueWrapper<T extends Blockable> {
         this.overdueStateApplicator = overdueStateApplicator;
     }
 
-    public OverdueState<T> refresh() throws OverdueException, OverdueApiException {
+    public OverdueState<T> refresh(final InternalCallContext context) throws OverdueException, OverdueApiException {
         if (overdueStateSet.size() < 1) { // No configuration available
             return overdueStateSet.getClearState();
         }
 
-        final BillingState<T> billingState = billingState();
-        final String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
+        final BillingState<T> billingState = billingState(context);
+        final String previousOverdueStateName = api.getBlockingStateFor(overdueable, context.toCallContext()).getStateName();
         final OverdueState<T> nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getToday(billingState.getAccountTimeZone()));
 
-        overdueStateApplicator.apply(overdueStateSet.getFirstState(), billingState, overdueable, previousOverdueStateName, nextOverdueState);
+        overdueStateApplicator.apply(overdueStateSet.getFirstState(), billingState, overdueable, previousOverdueStateName, nextOverdueState, context);
 
         return nextOverdueState;
     }
 
-    public BillingState<T> billingState() throws OverdueException {
-        return billingStateCalcuator.calculateBillingState(overdueable);
+    public BillingState<T> billingState(final InternalTenantContext context) throws OverdueException {
+        return billingStateCalcuator.calculateBillingState(overdueable, context);
     }
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
index c410e28..07bce1a 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -21,14 +21,12 @@ import java.util.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
-import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.applicator.OverdueStateApplicator;
 import com.ning.billing.overdue.calculator.BillingStateCalculatorBundle;
 import com.ning.billing.overdue.config.DefaultOverdueState;
@@ -36,8 +34,11 @@ import com.ning.billing.overdue.config.DefaultOverdueStateSet;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.config.api.OverdueException;
 import com.ning.billing.overdue.config.api.OverdueStateSet;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class OverdueWrapperFactory {
     private static final Logger log = LoggerFactory.getLogger(OverdueWrapperFactory.class);
 
@@ -72,11 +73,11 @@ public class OverdueWrapperFactory {
     }
 
     @SuppressWarnings("unchecked")
-    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(final Blockable.Type type, final UUID id) throws OverdueException {
+    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(final Blockable.Type type, final UUID id, final InternalTenantContext context) throws OverdueException {
         try {
             switch (type) {
                 case SUBSCRIPTION_BUNDLE: {
-                    final SubscriptionBundle bundle = entitlementApi.getBundleFromId(id);
+                    final SubscriptionBundle bundle = entitlementApi.getBundleFromId(id, context.toTenantContext());
                     return (OverdueWrapper<T>) new OverdueWrapper<SubscriptionBundle>(bundle, api, getOverdueStateSetBundle(),
                                                                                       clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle);
                 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
index 1f49c9d..f336844 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
@@ -17,7 +17,6 @@
 package com.ning.billing.overdue.applicator;
 
 import java.util.List;
-import java.util.SortedSet;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -27,9 +26,13 @@ import com.ning.billing.junction.api.Blockable.Type;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class ApplicatorMockJunctionModule extends MockJunctionModule {
+
     public static class ApplicatorBlockingApi implements BlockingApi {
+
         private BlockingState blockingState;
 
         public BlockingState getBlockingState() {
@@ -37,7 +40,7 @@ public class ApplicatorMockJunctionModule extends MockJunctionModule {
         }
 
         @Override
-        public BlockingState getBlockingStateFor(final Blockable overdueable) {
+        public BlockingState getBlockingStateFor(final Blockable overdueable, TenantContext context) {
             return new BlockingState() {
 
                 @Override
@@ -85,22 +88,22 @@ public class ApplicatorMockJunctionModule extends MockJunctionModule {
         }
 
         @Override
-        public BlockingState getBlockingStateFor(final UUID overdueableId) {
+        public BlockingState getBlockingStateFor(final UUID overdueableId, final TenantContext context) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public List<BlockingState> getBlockingHistory(final Blockable overdueable) {
+        public List<BlockingState> getBlockingHistory(final Blockable overdueable, final TenantContext context) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public List<BlockingState> getBlockingHistory(final UUID overdueableId) {
+        public List<BlockingState> getBlockingHistory(final UUID overdueableId, final TenantContext context) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public <T extends Blockable> void setBlockingState(final BlockingState state) {
+        public <T extends Blockable> void setBlockingState(final BlockingState state, final CallContext context) {
             blockingState = state;
         }
 
diff --git a/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java b/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
index 067b2c1..432e491 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
@@ -26,7 +26,6 @@ import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.overdue.OverdueChangeEvent;
@@ -36,6 +35,8 @@ import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.config.XMLLoader;
 
+import com.google.inject.Inject;
+
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.SECONDS;
 
@@ -63,17 +64,17 @@ public class TestOverdueStateApplicator extends OverdueTestBase {
         OverdueState<SubscriptionBundle> state;
 
         state = config.getBundleStateSet().findState("OD1");
-        applicator.apply(null, null, bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        applicator.apply(null, null, bundle, BlockingApi.CLEAR_STATE_NAME, state, internalCallContext);
         checkStateApplied(state);
         checkBussEvent("OD1");
 
         state = config.getBundleStateSet().findState("OD2");
-        applicator.apply(null, null,bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        applicator.apply(null, null,bundle, BlockingApi.CLEAR_STATE_NAME, state, internalCallContext);
         checkStateApplied(state);
         checkBussEvent("OD2");
 
         state = config.getBundleStateSet().findState("OD3");
-        applicator.apply(null, null, bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        applicator.apply(null, null, bundle, BlockingApi.CLEAR_STATE_NAME, state, internalCallContext);
         checkStateApplied(state);
         checkBussEvent("OD3");
         bus.stop();
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
index 344a1fa..c741047 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
@@ -38,6 +38,8 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.overdue.OverdueTestSuite;
 import com.ning.billing.overdue.config.api.BillingState;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
@@ -52,7 +54,7 @@ public class TestBillingStateCalculator extends OverdueTestSuite {
     public void setUp() throws Exception {
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getTimeZone()).thenReturn(DateTimeZone.UTC);
-        Mockito.when(accountApi.getAccountById(Mockito.<UUID>any())).thenReturn(account);
+        Mockito.when(accountApi.getAccountById(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(account);
     }
 
     public BillingStateCalculator<SubscriptionBundle> createBSCalc() {
@@ -62,12 +64,12 @@ public class TestBillingStateCalculator extends OverdueTestSuite {
         invoices.add(createInvoice(now.plusDays(1), BigDecimal.TEN, null));
         invoices.add(createInvoice(now.plusDays(2), new BigDecimal("100.0"), null));
 
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(invoices);
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(invoices);
 
         return new BillingStateCalculator<SubscriptionBundle>(invoiceApi, clock) {
             @Override
-            public BillingState<SubscriptionBundle> calculateBillingState(
-                    final SubscriptionBundle overdueable) {
+            public BillingState<SubscriptionBundle> calculateBillingState(final SubscriptionBundle overdueable,
+                                                                          final InternalTenantContext context) {
                 return null;
             }
         };
@@ -86,7 +88,7 @@ public class TestBillingStateCalculator extends OverdueTestSuite {
     @Test(groups = "fast")
     public void testUnpaidInvoices() {
         final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC);
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC, internalCallContext);
 
         Assert.assertEquals(invoices.size(), 3);
         Assert.assertEquals(BigDecimal.ZERO.compareTo(invoices.first().getBalance()), 0);
@@ -96,14 +98,14 @@ public class TestBillingStateCalculator extends OverdueTestSuite {
     @Test(groups = "fast")
     public void testSum() {
         final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC);
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC, internalCallContext);
         Assert.assertEquals(new BigDecimal("110.0").compareTo(calc.sumBalance(invoices)), 0);
     }
 
     @Test(groups = "fast")
     public void testEarliest() {
         final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC);
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), DateTimeZone.UTC, internalCallContext);
         Assert.assertEquals(calc.earliest(invoices).getInvoiceDate(), now);
     }
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
index 7f7b45e..a6b147d 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
@@ -16,24 +16,20 @@
 
 package com.ning.billing.overdue.calculator;
 
-import javax.annotation.Nullable;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.SortedSet;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-
 import com.ning.billing.catalog.MockPlan;
 import com.ning.billing.catalog.MockPriceList;
 import com.ning.billing.catalog.api.Plan;
@@ -46,9 +42,14 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.overdue.config.api.BillingStateBundle;
 import com.ning.billing.overdue.config.api.PaymentResponse;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
 public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator {
     private List<InvoiceItem> createInvoiceItems(final UUID[] bundleIds) {
         final List<InvoiceItem> result = new ArrayList<InvoiceItem>();
@@ -62,7 +63,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
     @Test(groups = "fast")
     public void testBillingStateAfterCancellation() throws Exception {
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(ImmutableList.<Invoice>of());
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(ImmutableList.<Invoice>of());
 
         final UUID bundleId = UUID.randomUUID();
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
@@ -70,10 +71,10 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
         final Subscription subscription = Mockito.mock(Subscription.class);
-        Mockito.when(entitlementApi.getBaseSubscription(bundleId)).thenReturn(subscription);
+        Mockito.when(entitlementApi.getBaseSubscription(Mockito.eq(bundleId), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, accountApi, clock);
-        final BillingStateBundle billingStateBundle = calc.calculateBillingState(bundle);
+        final BillingStateBundle billingStateBundle = calc.calculateBillingState(bundle, internalCallContext);
         Assert.assertNull(billingStateBundle.getBasePlanBillingPeriod());
         Assert.assertNull(billingStateBundle.getBasePlanPhaseType());
         Assert.assertNull(billingStateBundle.getBasePlanPriceList());
@@ -97,7 +98,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
         final Clock clock = new ClockMock();
         final InvoiceUserApi invoiceApi = Mockito.mock(InvoiceUserApi.class);
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(Collections2.filter(invoices, new Predicate<Invoice>() {
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(Collections2.filter(invoices, new Predicate<Invoice>() {
             @Override
             public boolean apply(@Nullable final Invoice invoice) {
                 return invoice != null && BigDecimal.ZERO.compareTo(invoice.getBalance()) < 0;
@@ -105,7 +106,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
         }));
 
         final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, accountApi, clock);
-        final SortedSet<Invoice> resultinvoices = calc.unpaidInvoicesForBundle(thisBundleId, new UUID(0L, 0L), DateTimeZone.UTC);
+        final SortedSet<Invoice> resultinvoices = calc.unpaidInvoicesForBundle(thisBundleId, new UUID(0L, 0L), DateTimeZone.UTC, internalCallContext);
 
         Assert.assertEquals(resultinvoices.size(), 3);
         Assert.assertEquals(new BigDecimal("100.0").compareTo(resultinvoices.first().getBalance()), 0);
@@ -127,7 +128,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final Clock clock = new ClockMock();
         final InvoiceUserApi invoiceApi = Mockito.mock(InvoiceUserApi.class);
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(invoices);
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(invoices);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(thisBundleId);
@@ -135,7 +136,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
         final Subscription subscription = Mockito.mock(Subscription.class);
-        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
         final PriceList pricelist = new MockPriceList();
@@ -145,7 +146,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, accountApi, clock);
 
-        final BillingStateBundle state = calc.calculateBillingState(bundle);
+        final BillingStateBundle state = calc.calculateBillingState(bundle, internalCallContext);
 
         Assert.assertEquals(state.getNumberOfUnpaidInvoices(), 4);
         Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 11100);
@@ -168,7 +169,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final Clock clock = new ClockMock();
         final InvoiceUserApi invoiceApi = Mockito.mock(InvoiceUserApi.class);
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(invoices);
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(invoices);
 
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
         Mockito.when(bundle.getId()).thenReturn(thisBundleId);
@@ -176,7 +177,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
         final Subscription subscription = Mockito.mock(Subscription.class);
-        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
         final PriceList pricelist = new MockPriceList();
@@ -186,7 +187,7 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
 
         final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, accountApi, clock);
 
-        final BillingStateBundle state = calc.calculateBillingState(bundle);
+        final BillingStateBundle state = calc.calculateBillingState(bundle, internalCallContext);
 
         Assert.assertEquals(state.getNumberOfUnpaidInvoices(), 0);
         Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 0);
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index 2cd0dc0..c3349b8 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -30,9 +30,6 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.catalog.DefaultCatalogService;
 import com.ning.billing.catalog.api.CatalogService;
@@ -59,6 +56,8 @@ import com.ning.billing.overdue.listener.OverdueListener;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
@@ -68,13 +67,15 @@ import com.ning.billing.util.email.templates.TemplateModule;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
 import com.ning.billing.util.glue.BusModule;
-import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
-import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 import com.ning.billing.util.tag.dao.TagDao;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.MINUTES;
 
@@ -91,7 +92,7 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
         UUID latestSubscriptionId = null;
 
         public OverdueListenerMock() {
-            super(null);
+            super(null, new InternalCallContextFactory(getMysqlTestingHelper().getDBI(), new ClockMock()));
         }
 
         @Override
@@ -146,7 +147,7 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
 
         final Subscription subscription = Mockito.mock(Subscription.class);
         final EntitlementUserApi entitlementUserApi = Mockito.mock(EntitlementUserApi.class);
-        Mockito.when(entitlementUserApi.getSubscriptionFromId(Mockito.<UUID>any())).thenReturn(subscription);
+        Mockito.when(entitlementUserApi.getSubscriptionFromId(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(subscription);
 
         listener = new OverdueListenerMock();
         notifier = new DefaultOverdueCheckNotifier(notificationQueueService,
@@ -166,7 +167,7 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
         final DateTime readyTime = now.plusMillis(2000);
         final OverdueCheckPoster poster = new DefaultOverdueCheckPoster(notificationQueueService);
 
-        poster.insertOverdueCheckNotification(blockable, readyTime);
+        poster.insertOverdueCheckNotification(blockable, readyTime, internalCallContext);
 
         // Move time in the future after the notification effectiveDate
         ((ClockMock) clock).setDeltaFromReality(3000);
diff --git a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
index 477d1bb..854a89c 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.mockito.Mockito;
@@ -31,7 +30,6 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -59,6 +57,7 @@ import com.ning.billing.overdue.glue.DefaultOverdueModule;
 import com.ning.billing.overdue.service.DefaultOverdueService;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.email.EmailModule;
 import com.ning.billing.util.email.templates.TemplateModule;
@@ -66,6 +65,8 @@ import com.ning.billing.util.glue.CallContextModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 
+import com.google.inject.Inject;
+
 @Guice(modules = {DefaultOverdueModule.class, OverdueListenerTesterModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class,
                   CallContextModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, NotificationQueueModule.class,
                   EmailModule.class, TemplateModule.class, TestDbiModule.class})
@@ -190,7 +191,7 @@ public abstract class OverdueTestBase extends OverdueTestSuiteWithEmbeddedDB {
         account = Mockito.mock(Account.class);
         Mockito.when(account.getId()).thenReturn(accountId);
         Mockito.when(account.getTimeZone()).thenReturn(DateTimeZone.UTC);
-        Mockito.when(accountUserApi.getAccountById(account.getId())).thenReturn(account);
+        Mockito.when(accountUserApi.getAccountById(Mockito.eq(account.getId()), Mockito.<TenantContext>any())).thenReturn(account);
 
         Mockito.when(bundle.getAccountId()).thenReturn(accountId);
 
@@ -208,13 +209,13 @@ public abstract class OverdueTestBase extends OverdueTestSuiteWithEmbeddedDB {
 
         final List<Invoice> invoices = new ArrayList<Invoice>();
         invoices.add(invoice);
-        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any())).thenReturn(invoices);
+        Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<TenantContext>any())).thenReturn(invoices);
 
         final Subscription base = Mockito.mock(Subscription.class);
         Mockito.when(base.getCurrentPlan()).thenReturn(MockPlan.createBicycleNoTrialEvergreen1USD());
         Mockito.when(base.getCurrentPriceList()).thenReturn(new MockPriceList());
         Mockito.when(base.getCurrentPhase()).thenReturn(MockPlan.createBicycleNoTrialEvergreen1USD().getFinalPhase());
-        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any())).thenReturn(base);
+        Mockito.when(entitlementApi.getBaseSubscription(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(base);
 
         return bundle;
     }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java b/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
index 0a1f1c2..7eec80d 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
@@ -43,19 +43,19 @@ public class TestOverdueWrapper extends OverdueTestBase {
         state = config.getBundleStateSet().findState("OD1");
         bundle = createBundle(clock.getUTCToday().minusDays(31));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
-        wrapper.refresh();
+        wrapper.refresh(internalCallContext);
         checkStateApplied(state);
 
         state = config.getBundleStateSet().findState("OD2");
         bundle = createBundle(clock.getUTCToday().minusDays(41));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
-        wrapper.refresh();
+        wrapper.refresh(internalCallContext);
         checkStateApplied(state);
 
         state = config.getBundleStateSet().findState("OD3");
         bundle = createBundle(clock.getUTCToday().minusDays(51));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
-        wrapper.refresh();
+        wrapper.refresh(internalCallContext);
         checkStateApplied(state);
     }
 
@@ -72,7 +72,7 @@ public class TestOverdueWrapper extends OverdueTestBase {
         state = config.getBundleStateSet().findState(BlockingApi.CLEAR_STATE_NAME);
         bundle = createBundle(clock.getUTCToday().minusDays(31));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
-        final OverdueState<SubscriptionBundle> result = wrapper.refresh();
+        final OverdueState<SubscriptionBundle> result = wrapper.refresh(internalCallContext);
 
         Assert.assertEquals(result.getName(), state.getName());
         Assert.assertEquals(result.blockChanges(), state.blockChanges());
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 2b10f8a..6256c43 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -29,6 +29,8 @@ import com.ning.billing.payment.core.PaymentMethodProcessor;
 import com.ning.billing.payment.core.PaymentProcessor;
 import com.ning.billing.payment.core.RefundProcessor;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
@@ -38,30 +40,35 @@ public class DefaultPaymentApi implements PaymentApi {
     private final PaymentMethodProcessor methodProcessor;
     private final PaymentProcessor paymentProcessor;
     private final RefundProcessor refundProcessor;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultPaymentApi(final PaymentMethodProcessor methodProcessor,
                              final PaymentProcessor paymentProcessor,
-                             final RefundProcessor refundProcessor) {
+                             final RefundProcessor refundProcessor,
+                             final InternalCallContextFactory internalCallContextFactory) {
         this.methodProcessor = methodProcessor;
         this.paymentProcessor = paymentProcessor;
         this.refundProcessor = refundProcessor;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
     public Payment createPayment(final Account account, final UUID invoiceId,
                                  final BigDecimal amount, final CallContext context) throws PaymentApiException {
-        return paymentProcessor.createPayment(account, invoiceId, amount, context, true, false);
+        return paymentProcessor.createPayment(account, invoiceId, amount,
+                                              internalCallContextFactory.createInternalCallContext(account.getId(), context), true, false);
     }
 
     @Override
     public Payment createExternalPayment(final Account account, final UUID invoiceId, final BigDecimal amount, final CallContext context) throws PaymentApiException {
-        return paymentProcessor.createPayment(account, invoiceId, amount, context, true, true);
+        return paymentProcessor.createPayment(account, invoiceId, amount,
+                                              internalCallContextFactory.createInternalCallContext(account.getId(), context), true, true);
     }
 
     @Override
-    public Payment getPayment(final UUID paymentId) throws PaymentApiException {
-        final Payment payment = paymentProcessor.getPayment(paymentId);
+    public Payment getPayment(final UUID paymentId, final TenantContext context) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId, internalCallContextFactory.createInternalTenantContext(context));
         if (payment == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
         }
@@ -69,19 +76,19 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public List<Payment> getInvoicePayments(final UUID invoiceId) {
-        return paymentProcessor.getInvoicePayments(invoiceId);
+    public List<Payment> getInvoicePayments(final UUID invoiceId, final TenantContext context) {
+        return paymentProcessor.getInvoicePayments(invoiceId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public List<Payment> getAccountPayments(final UUID accountId)
+    public List<Payment> getAccountPayments(final UUID accountId, final TenantContext context)
             throws PaymentApiException {
-        return paymentProcessor.getAccountPayments(accountId);
+        return paymentProcessor.getAccountPayments(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
     }
 
     @Override
-    public Refund getRefund(final UUID refundId) throws PaymentApiException {
-        return refundProcessor.getRefund(refundId);
+    public Refund getRefund(final UUID refundId, final TenantContext context) throws PaymentApiException {
+        return refundProcessor.getRefund(refundId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
@@ -89,7 +96,8 @@ public class DefaultPaymentApi implements PaymentApi {
         if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new PaymentApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
         }
-        return refundProcessor.createRefund(account, paymentId, refundAmount, false, ImmutableMap.<UUID, BigDecimal>of(), context);
+        return refundProcessor.createRefund(account, paymentId, refundAmount, false, ImmutableMap.<UUID, BigDecimal>of(),
+                                            internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
@@ -97,7 +105,8 @@ public class DefaultPaymentApi implements PaymentApi {
         if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new PaymentApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
         }
-        return refundProcessor.createRefund(account, paymentId, refundAmount, true, ImmutableMap.<UUID, BigDecimal>of(), context);
+        return refundProcessor.createRefund(account, paymentId, refundAmount, true, ImmutableMap.<UUID, BigDecimal>of(),
+                                            internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
@@ -107,24 +116,26 @@ public class DefaultPaymentApi implements PaymentApi {
             invoiceItemIdsWithAmounts.put(invoiceItemId, null);
         }
 
-        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts, context);
+        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts,
+                                            internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
     public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final CallContext context) throws PaymentApiException {
-        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts, context);
+        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts,
+                                            internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public List<Refund> getAccountRefunds(final Account account)
+    public List<Refund> getAccountRefunds(final Account account, final TenantContext context)
             throws PaymentApiException {
-        return refundProcessor.getAccountRefunds(account);
+        return refundProcessor.getAccountRefunds(account, internalCallContextFactory.createInternalTenantContext(account.getId(), context));
     }
 
     @Override
-    public List<Refund> getPaymentRefunds(final UUID paymentId)
+    public List<Refund> getPaymentRefunds(final UUID paymentId, final TenantContext context)
             throws PaymentApiException {
-        return refundProcessor.getPaymentRefunds(paymentId);
+        return refundProcessor.getPaymentRefunds(paymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
@@ -133,58 +144,59 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public String initializeAccountPlugin(final String pluginName, final Account account)
+    public String initializeAccountPlugin(final String pluginName, final Account account, final CallContext context)
             throws PaymentApiException {
-        return methodProcessor.initializeAccountPlugin(pluginName, account);
+        return methodProcessor.initializeAccountPlugin(pluginName, account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
     public UUID addPaymentMethod(final String pluginName, final Account account,
                                  final boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
             throws PaymentApiException {
-        return methodProcessor.addPaymentMethod(pluginName, account, setDefault, paymentMethodInfo, context);
+        return methodProcessor.addPaymentMethod(pluginName, account, setDefault, paymentMethodInfo,
+                                                internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
     public List<PaymentMethod> refreshPaymentMethods(final String pluginName,
                                                      final Account account, final CallContext context)
             throws PaymentApiException {
-        return methodProcessor.refreshPaymentMethods(pluginName, account, context);
+        return methodProcessor.refreshPaymentMethods(pluginName, account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail)
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail, final TenantContext context)
             throws PaymentApiException {
-        return methodProcessor.getPaymentMethods(account, withPluginDetail);
+        return methodProcessor.getPaymentMethods(account, withPluginDetail, internalCallContextFactory.createInternalTenantContext(account.getId(), context));
     }
 
     @Override
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final TenantContext context)
             throws PaymentApiException {
-        return methodProcessor.getPaymentMethodById(paymentMethodId);
+        return methodProcessor.getPaymentMethodById(paymentMethodId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethod, final boolean withPluginDetail)
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethod, final boolean withPluginDetail, final TenantContext context)
             throws PaymentApiException {
-        return methodProcessor.getPaymentMethod(account, paymentMethod, withPluginDetail);
+        return methodProcessor.getPaymentMethod(account, paymentMethod, withPluginDetail, internalCallContextFactory.createInternalTenantContext(account.getId(), context));
     }
 
     @Override
-    public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMethodInfo)
+    public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
             throws PaymentApiException {
-        methodProcessor.updatePaymentMethod(account, paymentMethodId, paymentMethodInfo);
+        methodProcessor.updatePaymentMethod(account, paymentMethodId, paymentMethodInfo, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
     public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff, final CallContext context)
             throws PaymentApiException {
-        methodProcessor.deletedPaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff);
+        methodProcessor.deletedPaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
     public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
             throws PaymentApiException {
-        methodProcessor.setDefaultPaymentMethod(account, paymentMethodId, context);
+        methodProcessor.setDefaultPaymentMethod(account, paymentMethodId, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java b/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
index 2006984..f936f3a 100644
--- a/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
+++ b/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.payment.bus;
 
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,25 +26,22 @@ import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.core.PaymentProcessor;
-import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
 
-
 public class InvoiceHandler {
 
-    public static final String PAYMENT_PROVIDER_KEY = "paymentProvider";
-
     private final PaymentProcessor paymentProcessor;
     private final AccountUserApi accountUserApi;
     private final Clock clock;
-
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private static final Logger log = LoggerFactory.getLogger(InvoiceHandler.class);
 
@@ -53,25 +49,25 @@ public class InvoiceHandler {
     public InvoiceHandler(final Clock clock,
                           final AccountUserApi accountUserApi,
                           final PaymentProcessor paymentProcessor,
-                          final TagUserApi tagUserApi) {
+                          final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.accountUserApi = accountUserApi;
         this.paymentProcessor = paymentProcessor;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
-
     @Subscribe
     public void processInvoiceEvent(final InvoiceCreationEvent event) {
 
         log.info("Received invoice creation notification for account {} and invoice {}",
                  event.getAccountId(), event.getInvoiceId());
 
-        Account account = null;
+        final Account account;
         try {
-
-            final CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken(), clock);
-            account = accountUserApi.getAccountById(event.getAccountId());
-            paymentProcessor.createPayment(account, event.getInvoiceId(), null, context, false, false);
+            // TODO retrieve tenantId?
+            final CallContext context = new DefaultCallContext(null, "PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken(), clock);
+            account = accountUserApi.getAccountById(event.getAccountId(), context);
+            paymentProcessor.createPayment(account, event.getInvoiceId(), null, internalCallContextFactory.createInternalCallContext(event.getAccountId(), context), false, false);
         } catch (AccountApiException e) {
             log.error("Failed to process invoice payment", e);
         } catch (PaymentApiException e) {
diff --git a/payment/src/main/java/com/ning/billing/payment/bus/TagHandler.java b/payment/src/main/java/com/ning/billing/payment/bus/TagHandler.java
index 53527ab..5208d21 100644
--- a/payment/src/main/java/com/ning/billing/payment/bus/TagHandler.java
+++ b/payment/src/main/java/com/ning/billing/payment/bus/TagHandler.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.bus;
 
 import java.util.UUID;
@@ -20,8 +21,6 @@ import java.util.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -30,12 +29,16 @@ import com.ning.billing.payment.core.PaymentProcessor;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.api.ControlTagDeletionEvent;
 
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+
 public class TagHandler {
 
     private static final Logger log = LoggerFactory.getLogger(TagHandler.class);
@@ -43,19 +46,22 @@ public class TagHandler {
     private final Clock clock;
     private final AccountUserApi accountUserApi;
     private final PaymentProcessor paymentProcessor;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public TagHandler(final Clock clock,
-            final AccountUserApi accountUserApi,
-            final PaymentProcessor paymentProcessor) {
+                      final AccountUserApi accountUserApi,
+                      final PaymentProcessor paymentProcessor,
+                      final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.accountUserApi = accountUserApi;
         this.paymentProcessor = paymentProcessor;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Subscribe
     public void process_AUTO_PAY_OFF_removal(final ControlTagDeletionEvent event) {
-        if (event.getTagDefinition().getName().equals(ControlTagType.AUTO_PAY_OFF.toString()) && event.getObjectType() ==  ObjectType.ACCOUNT) {
+        if (event.getTagDefinition().getName().equals(ControlTagType.AUTO_PAY_OFF.toString()) && event.getObjectType() == ObjectType.ACCOUNT) {
             final UUID accountId = event.getObjectId();
             processUnpaid_AUTO_PAY_OFF_payments(accountId, event.getUserToken());
         }
@@ -63,10 +69,11 @@ public class TagHandler {
 
     private void processUnpaid_AUTO_PAY_OFF_payments(final UUID accountId, final UUID userToken) {
         try {
-            final CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, userToken, clock);
-            final Account account = accountUserApi.getAccountById(accountId);
+            // TODO retrieve tenantId?
+            final CallContext context = new DefaultCallContext(null, "PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, userToken, clock);
+            final Account account = accountUserApi.getAccountById(accountId, context);
 
-            paymentProcessor.process_AUTO_PAY_OFF_removal(account, context);
+            paymentProcessor.process_AUTO_PAY_OFF_removal(account, internalCallContextFactory.createInternalCallContext(accountId, context));
 
         } catch (AccountApiException e) {
             log.warn(String.format("Failed to process process  removal AUTO_PAY_OFF for account %s", accountId), e);
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
index d1ca916..c91ac48 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.core;
 
 import java.util.ArrayList;
@@ -25,17 +26,10 @@ import java.util.concurrent.ExecutorService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.account.api.DefaultMutableAccountData;
-import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.payment.api.DefaultPaymentMethod;
 import com.ning.billing.payment.api.DefaultPaymentMethodPlugin;
 import com.ning.billing.payment.api.PaymentApiException;
@@ -51,40 +45,38 @@ import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
 import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
 
 public class PaymentMethodProcessor extends ProcessorBase {
 
     private static final Logger log = LoggerFactory.getLogger(PaymentMethodProcessor.class);
 
-    private final Clock clock;
-
     @Inject
     public PaymentMethodProcessor(final PaymentProviderPluginRegistry pluginRegistry,
                                   final AccountUserApi accountUserApi,
                                   final Bus eventBus,
                                   final PaymentDao paymentDao,
                                   final TagUserApi tagUserApi,
-                                  final Clock clock,
                                   final GlobalLocker locker,
                                   @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, tagUserApi, locker, executor);
-        this.clock = clock;
     }
 
     public Set<String> getAvailablePlugins() {
         return pluginRegistry.getRegisteredPluginNames();
     }
 
-
-    public String initializeAccountPlugin(final String pluginName, final Account account) throws PaymentApiException {
+    public String initializeAccountPlugin(final String pluginName, final Account account, final InternalCallContext context) throws PaymentApiException {
 
         return new WithAccountLock<String>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<String>() {
 
@@ -94,7 +86,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 try {
                     // STEPH do we want to really have a default or fail?? probably fail
                     pluginApi = pluginRegistry.getPlugin(pluginName);
-                    return pluginApi.createPaymentProviderAccount(account);
+                    return pluginApi.createPaymentProviderAccount(account, context.toCallContext());
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_ACCOUNT_INIT,
                                                   account.getId(), pluginApi != null ? pluginApi.getName() : null, e.getErrorMessage());
@@ -103,9 +95,8 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-
     public UUID addPaymentMethod(final String pluginName, final Account account,
-                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final CallContext context)
+                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final InternalCallContext context)
             throws PaymentApiException {
 
         return new WithAccountLock<UUID>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<UUID>() {
@@ -117,12 +108,12 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 try {
                     pluginApi = pluginRegistry.getPlugin(pluginName);
                     pm = new DefaultPaymentMethod(account.getId(), pluginName, paymentMethodProps);
-                    final String externalId = pluginApi.addPaymentMethod(account.getExternalKey(), paymentMethodProps, setDefault);
+                    final String externalId = pluginApi.addPaymentMethod(account.getExternalKey(), paymentMethodProps, setDefault, context.toCallContext());
                     final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getAccountId(), pm.getPluginName(), pm.isActive(), externalId);
                     paymentDao.insertPaymentMethod(pmModel, context);
 
                     if (setDefault) {
-                        accountUserApi.updatePaymentMethod(account.getId(), pm.getId(), context);
+                        accountUserApi.updatePaymentMethod(account.getId(), pm.getId(), context.toCallContext());
                     }
                 } catch (PaymentPluginApiException e) {
                     // STEPH all errors should also take a pluginName
@@ -135,7 +126,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
+    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final InternalCallContext context)
             throws PaymentApiException {
 
         return new WithAccountLock<List<PaymentMethod>>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<List<PaymentMethod>>() {
@@ -145,7 +136,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 final PaymentPluginApi pluginApi;
                 try {
                     pluginApi = pluginRegistry.getPlugin(pluginName);
-                    final List<PaymentMethodPlugin> pluginPms = pluginApi.getPaymentMethodDetails(account.getExternalKey());
+                    final List<PaymentMethodPlugin> pluginPms = pluginApi.getPaymentMethodDetails(account.getExternalKey(), context.toCallContext());
                     // The method should never return null by convention, but let's not trust the plugin...
                     if (pluginPms == null) {
                         return ImmutableList.<PaymentMethod>of();
@@ -158,7 +149,9 @@ public class PaymentMethodProcessor extends ProcessorBase {
                         finalPaymentMethods.add(pmModel);
                     }
 
-                    final List<PaymentMethodModelDao> refreshedPaymentMethods = paymentDao.refreshPaymentMethods(account.getId(), finalPaymentMethods, context);
+                    final List<PaymentMethodModelDao> refreshedPaymentMethods = paymentDao.refreshPaymentMethods(account.getId(),
+                                                                                                                 finalPaymentMethods,
+                                                                                                                 context);
                     return ImmutableList.<PaymentMethod>copyOf(Collections2.transform(refreshedPaymentMethods, new Function<PaymentMethodModelDao, PaymentMethod>() {
                         @Override
                         public PaymentMethod apply(final PaymentMethodModelDao input) {
@@ -173,36 +166,37 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail) throws PaymentApiException {
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail, final InternalTenantContext context) throws PaymentApiException {
 
-        final List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId());
+        final List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId(), context);
         if (paymentMethodModels.size() == 0) {
             return Collections.emptyList();
         }
-        return getPaymentMethodInternal(paymentMethodModels, account.getId(), account.getExternalKey(), withPluginDetail);
+        return getPaymentMethodInternal(paymentMethodModels, account.getId(), account.getExternalKey(), withPluginDetail, context);
     }
 
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final InternalTenantContext context)
             throws PaymentApiException {
-        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
         if (paymentMethodModel == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
         return new DefaultPaymentMethod(paymentMethodModel, null);
     }
 
-    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail)
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail, final InternalTenantContext context)
             throws PaymentApiException {
-        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
         if (paymentMethodModel == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
-        final List<PaymentMethod> result = getPaymentMethodInternal(Collections.singletonList(paymentMethodModel), account.getId(), account.getExternalKey(), withPluginDetail);
+        final List<PaymentMethod> result = getPaymentMethodInternal(Collections.singletonList(paymentMethodModel), account.getId(),
+                                                                    account.getExternalKey(), withPluginDetail, context);
         return (result.size() == 0) ? null : result.get(0);
     }
 
-    public PaymentMethod getExternalPaymentMethod(final Account account) throws PaymentApiException {
-        final List<PaymentMethod> paymentMethods = getPaymentMethods(account, false);
+    public PaymentMethod getExternalPaymentMethod(final Account account, final InternalTenantContext context) throws PaymentApiException {
+        final List<PaymentMethod> paymentMethods = getPaymentMethods(account, false, context);
         for (final PaymentMethod paymentMethod : paymentMethods) {
             if (ExternalPaymentProviderPlugin.PLUGIN_NAME.equals(paymentMethod.getPluginName())) {
                 return paymentMethod;
@@ -212,10 +206,10 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return null;
     }
 
-    public ExternalPaymentProviderPlugin getExternalPaymentProviderPlugin(final Account account, final CallContext context) throws PaymentApiException {
+    public ExternalPaymentProviderPlugin getExternalPaymentProviderPlugin(final Account account, final InternalCallContext context) throws PaymentApiException {
         // Check if this account has already used the external payment plugin
         // If not, it's the first time - add a payment method for it
-        if (getExternalPaymentMethod(account) == null) {
+        if (getExternalPaymentMethod(account, context) == null) {
             final DefaultNoOpPaymentMethodPlugin props = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, ImmutableList.<PaymentMethodKVInfo>of());
             addPaymentMethod(ExternalPaymentProviderPlugin.PLUGIN_NAME, account, false, props, context);
         }
@@ -223,7 +217,8 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return (ExternalPaymentProviderPlugin) pluginRegistry.getPlugin(ExternalPaymentProviderPlugin.PLUGIN_NAME);
     }
 
-    private List<PaymentMethod> getPaymentMethodInternal(final List<PaymentMethodModelDao> paymentMethodModels, final UUID accountId, final String accountKey, final boolean withPluginDetail)
+    private List<PaymentMethod> getPaymentMethodInternal(final List<PaymentMethodModelDao> paymentMethodModels, final UUID accountId,
+                                                         final String accountKey, final boolean withPluginDetail, final InternalTenantContext context)
             throws PaymentApiException {
 
         final List<PaymentMethod> result = new ArrayList<PaymentMethod>(paymentMethodModels.size());
@@ -234,7 +229,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
 
                 if (withPluginDetail) {
                     pluginApi = pluginRegistry.getPlugin(cur.getPluginName());
-                    pluginDetails = pluginApi.getPaymentMethodDetails(accountKey);
+                    pluginDetails = pluginApi.getPaymentMethodDetails(accountKey, context.toTenantContext());
                 }
 
                 final PaymentMethod pm = new DefaultPaymentMethod(cur, getPaymentMethodDetail(pluginDetails, cur.getExternalId()));
@@ -246,7 +241,6 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return result;
     }
 
-
     private PaymentMethodPlugin getPaymentMethodDetail(final List<PaymentMethodPlugin> pluginDetails, final String externalId) {
         if (pluginDetails == null) {
             return null;
@@ -260,22 +254,22 @@ public class PaymentMethodProcessor extends ProcessorBase {
     }
 
     public void updatePaymentMethod(final Account account, final UUID paymentMethodId,
-                                    final PaymentMethodPlugin paymentMethodProps)
+                                    final PaymentMethodPlugin paymentMethodProps, final InternalCallContext context)
             throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
                 }
 
                 try {
                     final PaymentMethodPlugin inputWithId = new DefaultPaymentMethodPlugin(paymentMethodProps, paymentMethodModel.getExternalId());
-                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
-                    pluginApi.updatePaymentMethod(account.getExternalKey(), inputWithId);
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId(), context);
+                    pluginApi.updatePaymentMethod(account.getExternalKey(), inputWithId, context.toCallContext());
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
@@ -284,15 +278,15 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-
-    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff)
+    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId,
+                                     final boolean deleteDefaultPaymentMethodWithAutoPayOff, final InternalCallContext context)
             throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
                 }
@@ -302,18 +296,17 @@ public class PaymentMethodProcessor extends ProcessorBase {
                         if (!deleteDefaultPaymentMethodWithAutoPayOff) {
                             throw new PaymentApiException(ErrorCode.PAYMENT_DEL_DEFAULT_PAYMENT_METHOD, account.getId());
                         } else {
-                            final CallContext context = new DefaultCallContext("PaymentMethodProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, null, clock);
-                            final boolean isAccountAutoPayOoff = isAccountAutoPayOff(account.getId());
+                            final boolean isAccountAutoPayOoff = isAccountAutoPayOff(account.getId(), context);
                             if (!isAccountAutoPayOoff) {
                                 log.info("Setting account {} to AUTO_PAY_OFF because of default payment method deletion");
                                 setAccountAutoPayOff(account.getId(), context);
                             }
-                            accountUserApi.removePaymentMethod(account.getId(), context);
+                            accountUserApi.removePaymentMethod(account.getId(), context.toCallContext());
                         }
                     }
-                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
-                    pluginApi.deletePaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId());
-                    paymentDao.deletedPaymentMethod(paymentMethodId);
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId(), context);
+                    pluginApi.deletePaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId(), context.toCallContext());
+                    paymentDao.deletedPaymentMethod(paymentMethodId, context);
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_DEL_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
@@ -324,23 +317,23 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final InternalCallContext context)
             throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
                 }
 
                 try {
-                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId(), context);
 
-                    pluginApi.setDefaultPaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId());
-                    accountUserApi.updatePaymentMethod(account.getId(), paymentMethodId, context);
+                    pluginApi.setDefaultPaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId(), context.toCallContext());
+                    accountUserApi.updatePaymentMethod(account.getId(), paymentMethodId, context.toCallContext());
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
@@ -351,9 +344,9 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    private PaymentPluginApi getPluginApi(final UUID paymentMethodId, final UUID accountId)
+    private PaymentPluginApi getPluginApi(final UUID paymentMethodId, final UUID accountId, final InternalTenantContext context)
             throws PaymentApiException {
-        final PaymentMethodModelDao paymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
+        final PaymentMethodModelDao paymentMethod = paymentDao.getPaymentMethod(paymentMethodId, context);
         if (paymentMethod == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index b837f5e..12cb9d5 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -15,8 +15,6 @@
  */
 package com.ning.billing.payment.core;
 
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.Collection;
@@ -63,10 +61,8 @@ import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRet
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusEvent;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextFactory;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
@@ -74,6 +70,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.inject.name.Named;
 
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
 public class PaymentProcessor extends ProcessorBase {
 
     private final PaymentMethodProcessor paymentMethodProcessor;
@@ -82,7 +80,6 @@ public class PaymentProcessor extends ProcessorBase {
     private final PluginFailureRetryServiceScheduler pluginFailureRetryService;
     private final AutoPayRetryServiceScheduler autoPayoffRetryService;
 
-    private final CallContextFactory factory;
     private final Clock clock;
 
     private final PaymentConfig paymentConfig;
@@ -106,8 +103,7 @@ public class PaymentProcessor extends ProcessorBase {
                             final Clock clock,
                             final GlobalLocker locker,
                             final PaymentConfig paymentConfig,
-                            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
-                            final CallContextFactory factory) {
+                            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, tagUserApi, locker, executor);
         this.paymentMethodProcessor = paymentMethodProcessor;
         this.invoicePaymentApi = invoicePaymentApi;
@@ -115,45 +111,44 @@ public class PaymentProcessor extends ProcessorBase {
         this.pluginFailureRetryService = pluginFailureRetryService;
         this.autoPayoffRetryService = autoPayoffRetryService;
         this.clock = clock;
-        this.factory = factory;
         this.paymentConfig = paymentConfig;
         this.paymentPluginDispatcher = new PluginDispatcher<Payment>(executor);
         this.voidPluginDispatcher = new PluginDispatcher<Void>(executor);
     }
 
-    public Payment getPayment(final UUID paymentId) {
-        final PaymentModelDao model = paymentDao.getPayment(paymentId);
+    public Payment getPayment(final UUID paymentId, final InternalTenantContext context) {
+        final PaymentModelDao model = paymentDao.getPayment(paymentId, context);
         if (model == null) {
             return null;
         }
-        return getPayments(Collections.singletonList(model)).get(0);
+        return getPayments(Collections.singletonList(model), context).get(0);
     }
 
 
-    public List<Payment> getInvoicePayments(final UUID invoiceId) {
-        return getPayments(paymentDao.getPaymentsForInvoice(invoiceId));
+    public List<Payment> getInvoicePayments(final UUID invoiceId, final InternalTenantContext context) {
+        return getPayments(paymentDao.getPaymentsForInvoice(invoiceId, context), context);
     }
 
 
-    public List<Payment> getAccountPayments(final UUID accountId) {
-        return getPayments(paymentDao.getPaymentsForAccount(accountId));
+    public List<Payment> getAccountPayments(final UUID accountId, final InternalTenantContext context) {
+        return getPayments(paymentDao.getPaymentsForAccount(accountId, context), context);
     }
 
-    private List<Payment> getPayments(final List<PaymentModelDao> payments) {
+    private List<Payment> getPayments(final List<PaymentModelDao> payments, final InternalTenantContext context) {
         if (payments == null) {
             return Collections.emptyList();
         }
         final List<Payment> result = new LinkedList<Payment>();
         for (final PaymentModelDao cur : payments) {
-            final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(cur.getId());
-            final List<RefundModelDao> refunds = paymentDao.getRefundsForPayment(cur.getId());
+            final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(cur.getId(), context);
+            final List<RefundModelDao> refunds = paymentDao.getRefundsForPayment(cur.getId(), context);
             final Payment entry = new DefaultPayment(cur, attempts, refunds);
             result.add(entry);
         }
         return result;
     }
 
-    public void process_AUTO_PAY_OFF_removal(final Account account, final CallContext context) throws PaymentApiException  {
+    public void process_AUTO_PAY_OFF_removal(final Account account, final InternalCallContext context) throws PaymentApiException  {
 
         try {
             voidPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Void>(locker,
@@ -163,7 +158,7 @@ public class PaymentProcessor extends ProcessorBase {
                 @Override
                 public Void doOperation() throws PaymentApiException {
 
-                    final List<PaymentModelDao> payments = paymentDao.getPaymentsForAccount(account.getId());
+                    final List<PaymentModelDao> payments = paymentDao.getPaymentsForAccount(account.getId(), context);
                     final Collection<PaymentModelDao> paymentsToBeCompleted = Collections2.filter(payments, new Predicate<PaymentModelDao>() {
                         @Override
                         public boolean apply(final PaymentModelDao in) {
@@ -180,10 +175,10 @@ public class PaymentProcessor extends ProcessorBase {
                             autoPayoffRetryService.scheduleRetry(cur.getId(), clock.getUTCNow());
                             break;
                         case PAYMENT_FAILURE:
-                            scheduleRetryOnPaymentFailure(cur.getId());
+                            scheduleRetryOnPaymentFailure(cur.getId(), context);
                             break;
                         case PLUGIN_FAILURE:
-                            scheduleRetryOnPluginFailure(cur.getId());
+                            scheduleRetryOnPluginFailure(cur.getId(), context);
                             break;
                         default:
                             // Impossible...
@@ -200,7 +195,7 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     public Payment createPayment(final Account account, final UUID invoiceId, @Nullable final BigDecimal inputAmount,
-                                 final CallContext context, final boolean isInstantPayment, final boolean isExternalPayment)
+                                 final InternalCallContext context, final boolean isInstantPayment, final boolean isExternalPayment)
             throws PaymentApiException {
         // Use the special external payment plugin to handle external payments
         final PaymentPluginApi plugin;
@@ -208,9 +203,9 @@ public class PaymentProcessor extends ProcessorBase {
         try {
             if (isExternalPayment) {
                 plugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, context);
-                paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account).getId();
+                paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account, context).getId();
             } else {
-                plugin = getPaymentProviderPlugin(account);
+                plugin = getPaymentProviderPlugin(account, context);
                 paymentMethodId = account.getPaymentMethodId();
             }
         } catch (PaymentApiException e) {
@@ -233,14 +228,14 @@ public class PaymentProcessor extends ProcessorBase {
 
 
                     try {
-                        final Invoice invoice = invoicePaymentApi.getInvoice(invoiceId);
+                        final Invoice invoice = invoicePaymentApi.getInvoice(invoiceId, context.toCallContext());
 
                         if (invoice.isMigrationInvoice()) {
                             log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
                             return null;
                         }
 
-                        final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId());
+                        final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId(), context);
                         setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(account.getId(), paymentMethodId, isAccountAutoPayOff, context, isInstantPayment);
 
                         final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
@@ -268,10 +263,11 @@ public class PaymentProcessor extends ProcessorBase {
         }
     }
 
-    private void setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(final UUID accountId, final UUID paymentMethodId, final boolean isAccountAutoPayOff, final CallContext context, final boolean isInstantPayment)
+    private void setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(final UUID accountId, final UUID paymentMethodId, final boolean isAccountAutoPayOff,
+                                                              final InternalCallContext context, final boolean isInstantPayment)
     throws PaymentApiException  {
 
-        final PaymentModelDao lastPaymentForPaymentMethod = paymentDao.getLastPaymentForPaymentMethod(accountId, paymentMethodId);
+        final PaymentModelDao lastPaymentForPaymentMethod = paymentDao.getLastPaymentForPaymentMethod(accountId, paymentMethodId, context);
         final boolean isLastPaymentForPaymentMethodBad = lastPaymentForPaymentMethod != null &&
         (lastPaymentForPaymentMethod.getPaymentStatus() == PaymentStatus.PLUGIN_FAILURE_ABORTED ||
                 lastPaymentForPaymentMethod.getPaymentStatus() == PaymentStatus.UNKNOWN);
@@ -304,37 +300,36 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
 
-    public void retryAutoPayOff(final UUID paymentId) {
-        retryFailedPaymentInternal(paymentId, PaymentStatus.AUTO_PAY_OFF);
+    public void retryAutoPayOff(final UUID paymentId, final InternalCallContext context) {
+        retryFailedPaymentInternal(paymentId, context, PaymentStatus.AUTO_PAY_OFF);
     }
 
-    public void retryPluginFailure(final UUID paymentId) {
-        retryFailedPaymentInternal(paymentId, PaymentStatus.PLUGIN_FAILURE);
+    public void retryPluginFailure(final UUID paymentId, final InternalCallContext context) {
+        retryFailedPaymentInternal(paymentId, context, PaymentStatus.PLUGIN_FAILURE);
     }
 
-    public void retryFailedPayment(final UUID paymentId) {
-        retryFailedPaymentInternal(paymentId, PaymentStatus.PAYMENT_FAILURE);
+    public void retryFailedPayment(final UUID paymentId, final InternalCallContext context) {
+        retryFailedPaymentInternal(paymentId, context, PaymentStatus.PAYMENT_FAILURE);
     }
 
 
-    private void retryFailedPaymentInternal(final UUID paymentId, final PaymentStatus... expectedPaymentStates) {
+    private void retryFailedPaymentInternal(final UUID paymentId, final InternalCallContext context, final PaymentStatus... expectedPaymentStates) {
 
         try {
 
-            final PaymentModelDao payment = paymentDao.getPayment(paymentId);
+            final PaymentModelDao payment = paymentDao.getPayment(paymentId, context);
             if (payment == null) {
                 log.error("Invalid retry for non existnt paymentId {}", paymentId);
                 return;
             }
 
-            if (isAccountAutoPayOff(payment.getAccountId())) {
+            if (isAccountAutoPayOff(payment.getAccountId(), context)) {
                 log.info(String.format("Skip retry payment %s in state %s because AUTO_PAY_OFF", payment.getId(), payment.getPaymentStatus()));
                 return;
             }
 
-            final Account account = accountUserApi.getAccountById(payment.getAccountId());
-            final PaymentPluginApi plugin = getPaymentProviderPlugin(account);
-            final CallContext context = factory.createCallContext("PaymentRetry", CallOrigin.INTERNAL, UserType.SYSTEM);
+            final Account account = accountUserApi.getAccountById(payment.getAccountId(), context.toCallContext());
+            final PaymentPluginApi plugin = getPaymentProviderPlugin(account, context);
 
             voidPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Void>(locker,
                     account.getExternalKey(),
@@ -344,7 +339,7 @@ public class PaymentProcessor extends ProcessorBase {
                 public Void doOperation() throws PaymentApiException {
                     try {
                         // Fetch again with account lock this time
-                        final PaymentModelDao payment = paymentDao.getPayment(paymentId);
+                        final PaymentModelDao payment = paymentDao.getPayment(paymentId, context);
                         boolean foundExpectedState = false;
                         for (final PaymentStatus cur : expectedPaymentStates) {
                             if (payment.getPaymentStatus() == cur) {
@@ -357,7 +352,7 @@ public class PaymentProcessor extends ProcessorBase {
                             return null;
                         }
 
-                        final Invoice invoice = invoicePaymentApi.getInvoice(payment.getInvoiceId());
+                        final Invoice invoice = invoicePaymentApi.getInvoice(payment.getInvoiceId(), context.toCallContext());
                         if (invoice.isMigrationInvoice()) {
                             return null;
                         }
@@ -383,7 +378,7 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     private Payment processNewPaymentForAutoPayOffWithAccountLocked(final UUID paymentMethodId, final Account account, final Invoice invoice,
-                                                                    final BigDecimal requestedAmount, final CallContext context)
+                                                                    final BigDecimal requestedAmount, final InternalCallContext context)
             throws PaymentApiException {
         final PaymentStatus paymentStatus = PaymentStatus.AUTO_PAY_OFF;
 
@@ -395,7 +390,7 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     private Payment processNewPaymentWithAccountLocked(final UUID paymentMethodId, final PaymentPluginApi plugin, final Account account, final Invoice invoice,
-                                                       final BigDecimal requestedAmount, final boolean isInstantPayment, final CallContext context) throws PaymentApiException {
+                                                       final BigDecimal requestedAmount, final boolean isInstantPayment, final InternalCallContext context) throws PaymentApiException {
         final PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), paymentMethodId, requestedAmount.setScale(2, RoundingMode.HALF_UP), invoice.getCurrency(), clock.getUTCNow());
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
 
@@ -404,7 +399,7 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     private Payment processRetryPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice, final PaymentModelDao payment,
-            final BigDecimal requestedAmount, final CallContext context) throws PaymentApiException {
+            final BigDecimal requestedAmount, final InternalCallContext context) throws PaymentApiException {
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
         paymentDao.insertNewAttemptForPayment(payment.getId(), attempt, context);
         return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, false, context);
@@ -412,13 +407,13 @@ public class PaymentProcessor extends ProcessorBase {
 
 
     private Payment processPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice,
-            final PaymentModelDao paymentInput, final PaymentAttemptModelDao attemptInput, final boolean isInstantPayment, final CallContext context) throws PaymentApiException {
+            final PaymentModelDao paymentInput, final PaymentAttemptModelDao attemptInput, final boolean isInstantPayment, final InternalCallContext context) throws PaymentApiException {
 
 
         List<PaymentAttemptModelDao> allAttempts = null;
         if (paymentConfig.isPaymentOff()) {
             paymentDao.updateStatusForPaymentWithAttempt(paymentInput.getId(), PaymentStatus.PAYMENT_SYSTEM_OFF, null, null, null, null, attemptInput.getId(), context);
-            allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
+            allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
             return new DefaultPayment(paymentInput, allAttempts, Collections.<RefundModelDao>emptyList());
         }
 
@@ -427,7 +422,7 @@ public class PaymentProcessor extends ProcessorBase {
         PaymentStatus paymentStatus;
         try {
 
-            final PaymentInfoPlugin paymentPluginInfo = plugin.processPayment(account.getExternalKey(), paymentInput.getId(), attemptInput.getRequestedAmount());
+            final PaymentInfoPlugin paymentPluginInfo = plugin.processPayment(account.getExternalKey(), paymentInput.getId(), attemptInput.getRequestedAmount(), context.toCallContext());
             switch (paymentPluginInfo.getStatus()) {
             case PROCESSED:
                 // Update Payment/PaymentAttempt status
@@ -435,15 +430,15 @@ public class PaymentProcessor extends ProcessorBase {
                 paymentDao.updateStatusForPaymentWithAttempt(paymentInput.getId(), paymentStatus, paymentPluginInfo.getGatewayErrorCode(), null, paymentPluginInfo.getExtFirstReferenceId(), paymentPluginInfo.getExtSecondReferenceId(), attemptInput.getId(), context);
 
                 // Fetch latest objects
-                allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
+                allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
 
-                payment = paymentDao.getPayment(paymentInput.getId());
+                payment = paymentDao.getPayment(paymentInput.getId(), context);
                 invoicePaymentApi.notifyOfPayment(invoice.getId(),
                         payment.getAmount(),
                         paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
                                 payment.getId(),
                                 payment.getEffectiveDate(),
-                                context);
+                                context.toCallContext());
 
                 // Create Bus event
                 event = new DefaultPaymentInfoEvent(account.getId(),
@@ -452,10 +447,10 @@ public class PaymentProcessor extends ProcessorBase {
                 break;
 
             case ERROR:
-                allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
+                allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
                 // Schedule if non instant payment and max attempt for retry not reached yet
                 if (!isInstantPayment) {
-                    paymentStatus = scheduleRetryOnPaymentFailure(paymentInput.getId());
+                    paymentStatus = scheduleRetryOnPaymentFailure(paymentInput.getId(), context);
                 } else {
                     paymentStatus = PaymentStatus.PAYMENT_FAILURE_ABORTED;
                 }
@@ -478,13 +473,15 @@ public class PaymentProcessor extends ProcessorBase {
             //
             // An exception occurred, we are left in an unknown state, we need to schedule a retry
             //
-            paymentStatus = isInstantPayment ? PaymentStatus.PAYMENT_FAILURE_ABORTED : scheduleRetryOnPluginFailure(paymentInput.getId());
+            paymentStatus = isInstantPayment ? PaymentStatus.PAYMENT_FAILURE_ABORTED : scheduleRetryOnPluginFailure(paymentInput.getId(), context);
             // STEPH message might need truncation to fit??
 
             paymentDao.updateStatusForPaymentWithAttempt(paymentInput.getId(), paymentStatus, null, e.getMessage(), null, null, attemptInput.getId(), context);
 
             throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), e.toString());
 
+        } catch (InvoiceApiException e) {
+            throw new PaymentApiException(ErrorCode.INVOICE_NOT_FOUND, invoice.getId(), e.toString());
         } finally {
             if (event != null) {
                 postPaymentEvent(event, account.getId());
@@ -493,15 +490,15 @@ public class PaymentProcessor extends ProcessorBase {
         return new DefaultPayment(payment, allAttempts, Collections.<RefundModelDao>emptyList());
     }
 
-    private PaymentStatus scheduleRetryOnPluginFailure(final UUID paymentId) {
-        final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId);
+    private PaymentStatus scheduleRetryOnPluginFailure(final UUID paymentId, final InternalTenantContext context) {
+        final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId, context);
         final int retryAttempt = getNumberAttemptsInState(paymentId, allAttempts, PaymentStatus.UNKNOWN, PaymentStatus.PLUGIN_FAILURE);
         final boolean isScheduledForRetry = pluginFailureRetryService.scheduleRetry(paymentId, retryAttempt);
         return isScheduledForRetry ? PaymentStatus.PLUGIN_FAILURE : PaymentStatus.PLUGIN_FAILURE_ABORTED;
     }
 
-    private PaymentStatus scheduleRetryOnPaymentFailure(final UUID paymentId) {
-        final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId);
+    private PaymentStatus scheduleRetryOnPaymentFailure(final UUID paymentId, final InternalTenantContext context) {
+        final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId, context);
         final int retryAttempt = getNumberAttemptsInState(paymentId, allAttempts,
                 PaymentStatus.UNKNOWN, PaymentStatus.PAYMENT_FAILURE);
         final boolean isScheduledForRetry = failedPaymentRetryService.scheduleRetry(paymentId, retryAttempt);
diff --git a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
index d10b308..10cbfee 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.core;
 
 import java.util.Map;
@@ -37,7 +38,8 @@ import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.bus.BusEvent;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.globallocker.GlobalLock;
 import com.ning.billing.util.globallocker.GlobalLocker;
@@ -76,8 +78,8 @@ public abstract class ProcessorBase {
         this.tagUserApi = tagUserApi;
     }
 
-    protected boolean isAccountAutoPayOff(final UUID accountId) {
-        final Map<String, Tag> accountTags = tagUserApi.getTags(accountId, ObjectType.ACCOUNT);
+    protected boolean isAccountAutoPayOff(final UUID accountId, final InternalTenantContext context) {
+        final Map<String, Tag> accountTags = tagUserApi.getTags(accountId, ObjectType.ACCOUNT, context.toTenantContext());
         for (final Tag cur : accountTags.values()) {
             if (ControlTagType.AUTO_PAY_OFF.getId().equals(cur.getTagDefinitionId())) {
                 return true;
@@ -86,18 +88,17 @@ public abstract class ProcessorBase {
         return false;
     }
 
-
-    protected void setAccountAutoPayOff(UUID accountId, CallContext context) throws PaymentApiException {
+    protected void setAccountAutoPayOff(final UUID accountId, final InternalCallContext context) throws PaymentApiException {
         try {
-            tagUserApi.addTag(accountId, ObjectType.ACCOUNT, ControlTagType.AUTO_PAY_OFF.getId(), context);
+            tagUserApi.addTag(accountId, ObjectType.ACCOUNT, ControlTagType.AUTO_PAY_OFF.getId(), context.toCallContext());
         } catch (TagApiException e) {
             log.error("Failed to add AUTO_PAY_OFF on account " + accountId, e);
             throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, "Failed to add AUTO_PAY_OFF on account " + accountId);
         }
     }
 
-    protected PaymentPluginApi getPaymentProviderPlugin(final UUID paymentMethodId) throws PaymentApiException {
-        final PaymentMethodModelDao methodDao = paymentDao.getPaymentMethodIncludedDeleted(paymentMethodId);
+    protected PaymentPluginApi getPaymentProviderPlugin(final UUID paymentMethodId, final InternalTenantContext context) throws PaymentApiException {
+        final PaymentMethodModelDao methodDao = paymentDao.getPaymentMethodIncludedDeleted(paymentMethodId, context);
         if (methodDao == null) {
             log.error("PaymentMethod dpes not exist", paymentMethodId);
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
@@ -105,24 +106,23 @@ public abstract class ProcessorBase {
         return pluginRegistry.getPlugin(methodDao.getPluginName());
     }
 
-
-    protected PaymentPluginApi getPaymentProviderPlugin(final String accountKey)
+    protected PaymentPluginApi getPaymentProviderPlugin(final String accountKey, final InternalTenantContext context)
             throws AccountApiException, PaymentApiException {
 
         final String paymentProviderName = null;
         if (accountKey != null) {
-            final Account account = accountUserApi.getAccountByKey(accountKey);
-            return getPaymentProviderPlugin(account);
+            final Account account = accountUserApi.getAccountByKey(accountKey, context.toTenantContext());
+            return getPaymentProviderPlugin(account, context);
         }
         return pluginRegistry.getPlugin(paymentProviderName);
     }
 
-    protected PaymentPluginApi getPaymentProviderPlugin(final Account account) throws PaymentApiException {
+    protected PaymentPluginApi getPaymentProviderPlugin(final Account account, final InternalTenantContext context) throws PaymentApiException {
         final UUID paymentMethodId = account.getPaymentMethodId();
         if (paymentMethodId == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, account.getId());
         }
-        return getPaymentProviderPlugin(paymentMethodId);
+        return getPaymentProviderPlugin(paymentMethodId, context);
     }
 
     protected void postPaymentEvent(final BusEvent ev, final UUID accountId) {
@@ -136,12 +136,11 @@ public abstract class ProcessorBase {
         }
     }
 
-
     public interface WithAccountLockCallback<T> {
+
         public T doOperation() throws PaymentApiException;
     }
 
-
     public static class CallableWithAccountLock<T> implements Callable<T> {
 
         private final GlobalLocker locker;
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index 3184081..fb2986d 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.payment.core;
 
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -33,12 +31,6 @@ import javax.inject.Inject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.name.Named;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -58,32 +50,42 @@ import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.name.Named;
+
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
 public class RefundProcessor extends ProcessorBase {
 
     private static final Logger log = LoggerFactory.getLogger(RefundProcessor.class);
 
     private final InvoicePaymentApi invoicePaymentApi;
-    private final CallContextFactory factory;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public RefundProcessor(final PaymentProviderPluginRegistry pluginRegistry,
                            final AccountUserApi accountUserApi,
                            final InvoicePaymentApi invoicePaymentApi,
                            final Bus eventBus,
-                           final CallContextFactory factory,
+                           final InternalCallContextFactory internalCallContextFactory,
                            final TagUserApi tagUserApi,
                            final PaymentDao paymentDao,
                            final GlobalLocker locker,
                            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, tagUserApi, locker, executor);
         this.invoicePaymentApi = invoicePaymentApi;
-        this.factory = factory;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     /**
@@ -99,7 +101,7 @@ public class RefundProcessor extends ProcessorBase {
      * @throws PaymentApiException
      */
     public Refund createRefund(final Account account, final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount,
-                               final boolean isAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final CallContext context)
+                               final boolean isAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final InternalCallContext context)
             throws PaymentApiException {
 
         return new WithAccountLock<Refund>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Refund>() {
@@ -107,11 +109,11 @@ public class RefundProcessor extends ProcessorBase {
             @Override
             public Refund doOperation() throws PaymentApiException {
                 // First, compute the refund amount, if necessary
-                final BigDecimal refundAmount = computeRefundAmount(paymentId, specifiedRefundAmount, invoiceItemIdsWithAmounts);
+                final BigDecimal refundAmount = computeRefundAmount(paymentId, specifiedRefundAmount, invoiceItemIdsWithAmounts, context);
 
                 try {
 
-                    final PaymentModelDao payment = paymentDao.getPayment(paymentId);
+                    final PaymentModelDao payment = paymentDao.getPayment(paymentId, context);
                     if (payment == null) {
                         throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_SUCCESS_PAYMENT, paymentId);
                     }
@@ -125,7 +127,7 @@ public class RefundProcessor extends ProcessorBase {
                     int foundPluginCompletedRefunds = 0;
                     RefundModelDao refundInfo = null;
                     BigDecimal totalAmountRefunded = BigDecimal.ZERO;
-                    final List<RefundModelDao> existingRefunds = paymentDao.getRefundsForPayment(paymentId);
+                    final List<RefundModelDao> existingRefunds = paymentDao.getRefundsForPayment(paymentId, context);
                     for (final RefundModelDao cur : existingRefunds) {
 
                         final BigDecimal existingPositiveAmount = cur.getAmount();
@@ -152,19 +154,19 @@ public class RefundProcessor extends ProcessorBase {
                         paymentDao.insertRefund(refundInfo, context);
                     }
 
-                    final PaymentPluginApi plugin = getPaymentProviderPlugin(payment.getPaymentMethodId());
-                    final int nbExistingRefunds = plugin.getNbRefundForPaymentAmount(account, paymentId, refundAmount);
+                    final PaymentPluginApi plugin = getPaymentProviderPlugin(payment.getPaymentMethodId(), context);
+                    final int nbExistingRefunds = plugin.getNbRefundForPaymentAmount(account, paymentId, refundAmount, context.toCallContext());
                     log.debug(String.format("found %d pluginRefunds for paymentId %s and amount %s", nbExistingRefunds, paymentId, refundAmount));
 
                     if (nbExistingRefunds > foundPluginCompletedRefunds) {
                         log.info("Found existing plugin refund for paymentId {}, skip plugin", paymentId);
                     } else {
                         // If there is no such existing refund we create it
-                        plugin.processRefund(account, paymentId, refundAmount);
+                        plugin.processRefund(account, paymentId, refundAmount, context.toCallContext());
                     }
                     paymentDao.updateRefundStatus(refundInfo.getId(), RefundStatus.PLUGIN_COMPLETED, context);
 
-                    invoicePaymentApi.createRefund(paymentId, refundAmount, isAdjusted, invoiceItemIdsWithAmounts, refundInfo.getId(), context);
+                    invoicePaymentApi.createRefund(paymentId, refundAmount, isAdjusted, invoiceItemIdsWithAmounts, refundInfo.getId(), context.toCallContext());
 
                     paymentDao.updateRefundStatus(refundInfo.getId(), RefundStatus.COMPLETED, context);
 
@@ -187,10 +189,11 @@ public class RefundProcessor extends ProcessorBase {
      * @param invoiceItemIdsWithAmounts invoice item ids and associated amounts to adjust
      * @return the refund amount
      */
-    private BigDecimal computeRefundAmount(final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts)
+    private BigDecimal computeRefundAmount(final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount,
+                                           final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final InternalTenantContext context)
             throws PaymentApiException {
         try {
-            final List<InvoiceItem> items = invoicePaymentApi.getInvoiceForPaymentId(paymentId).getInvoiceItems();
+            final List<InvoiceItem> items = invoicePaymentApi.getInvoiceForPaymentId(paymentId, context.toTenantContext()).getInvoiceItems();
 
             BigDecimal amountFromItems = BigDecimal.ZERO;
             for (final UUID itemId : invoiceItemIdsWithAmounts.keySet()) {
@@ -219,9 +222,9 @@ public class RefundProcessor extends ProcessorBase {
         throw new IllegalArgumentException("Unable to find invoice item for id " + itemId);
     }
 
-    public Refund getRefund(final UUID refundId)
+    public Refund getRefund(final UUID refundId, final InternalTenantContext context)
             throws PaymentApiException {
-        RefundModelDao result = paymentDao.getRefund(refundId);
+        RefundModelDao result = paymentDao.getRefund(refundId, context);
         if (result == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_REFUND, refundId);
         }
@@ -231,27 +234,27 @@ public class RefundProcessor extends ProcessorBase {
         }
 
         if (completePluginCompletedRefund(filteredInput)) {
-            result = paymentDao.getRefund(refundId);
+            result = paymentDao.getRefund(refundId, context);
         }
         return new DefaultRefund(result.getId(), result.getPaymentId(), result.getAmount(), result.getCurrency(),
                                  result.isAdjsuted(), result.getCreatedDate());
     }
 
-    public List<Refund> getAccountRefunds(final Account account)
+    public List<Refund> getAccountRefunds(final Account account, final InternalTenantContext context)
             throws PaymentApiException {
-        List<RefundModelDao> result = paymentDao.getRefundsForAccount(account.getId());
+        List<RefundModelDao> result = paymentDao.getRefundsForAccount(account.getId(), context);
         if (completePluginCompletedRefund(result)) {
-            result = paymentDao.getRefundsForAccount(account.getId());
+            result = paymentDao.getRefundsForAccount(account.getId(), context);
         }
         final List<RefundModelDao> filteredInput = filterUncompletedPluginRefund(result);
         return toRefunds(filteredInput);
     }
 
-    public List<Refund> getPaymentRefunds(final UUID paymentId)
+    public List<Refund> getPaymentRefunds(final UUID paymentId, final InternalTenantContext context)
             throws PaymentApiException {
-        List<RefundModelDao> result = paymentDao.getRefundsForPayment(paymentId);
+        List<RefundModelDao> result = paymentDao.getRefundsForPayment(paymentId, context);
         if (completePluginCompletedRefund(result)) {
-            result = paymentDao.getRefundsForPayment(paymentId);
+            result = paymentDao.getRefundsForPayment(paymentId, context);
         }
         final List<RefundModelDao> filteredInput = filterUncompletedPluginRefund(result);
         return toRefunds(filteredInput);
@@ -289,16 +292,16 @@ public class RefundProcessor extends ProcessorBase {
         }
 
         try {
-            final Account account = accountUserApi.getAccountById(refundsToBeFixed.iterator().next().getAccountId());
+            final InternalCallContext context = internalCallContextFactory.createInternalCallContext("RefundProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, null);
+            final Account account = accountUserApi.getAccountById(refundsToBeFixed.iterator().next().getAccountId(), context.toCallContext());
             new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
                 @Override
                 public Void doOperation() throws PaymentApiException {
                     try {
-                        final CallContext context = factory.createCallContext("RefundProcessor", CallOrigin.INTERNAL, UserType.SYSTEM);
                         for (final RefundModelDao cur : refundsToBeFixed) {
                             // TODO - we currently don't save the items to be adjusted. If we crash, they won't be adjusted...
-                            invoicePaymentApi.createRefund(cur.getPaymentId(), cur.getAmount(), cur.isAdjsuted(), ImmutableMap.<UUID, BigDecimal>of(), cur.getId(), context);
+                            invoicePaymentApi.createRefund(cur.getPaymentId(), cur.getAmount(), cur.isAdjsuted(), ImmutableMap.<UUID, BigDecimal>of(), cur.getId(), context.toCallContext());
                             paymentDao.updateRefundStatus(cur.getId(), RefundStatus.COMPLETED, context);
                         }
                     } catch (InvoiceApiException e) {
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
index b4271ac..3eafe6b 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
@@ -29,7 +30,8 @@ import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
 import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
 import com.ning.billing.util.ChangeType;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.TableName;
@@ -38,7 +40,6 @@ import com.google.inject.Inject;
 
 public class AuditedPaymentDao implements PaymentDao {
 
-
     private final PaymentSqlDao paymentSqlDao;
     private final PaymentAttemptSqlDao paymentAttemptSqlDao;
     private final PaymentMethodSqlDao paymentMethodSqlDao;
@@ -52,10 +53,8 @@ public class AuditedPaymentDao implements PaymentDao {
         this.refundSqlDao = dbi.onDemand(RefundSqlDao.class);
     }
 
-
     @Override
-    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId,
-                                                             final PaymentAttemptModelDao attempt, final CallContext context) {
+    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
 
         return paymentAttemptSqlDao.inTransaction(new Transaction<PaymentAttemptModelDao, PaymentAttemptSqlDao>() {
             @Override
@@ -69,9 +68,8 @@ public class AuditedPaymentDao implements PaymentDao {
         });
     }
 
-
     @Override
-    public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final CallContext context) {
+    public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
 
         return paymentSqlDao.inTransaction(new Transaction<PaymentModelDao, PaymentSqlDao>() {
 
@@ -86,38 +84,38 @@ public class AuditedPaymentDao implements PaymentDao {
         });
     }
 
-    private PaymentModelDao insertPaymentFromTransaction(final PaymentModelDao payment, final CallContext context, final PaymentSqlDao transactional) {
+    private PaymentModelDao insertPaymentFromTransaction(final PaymentModelDao payment, final InternalCallContext context, final PaymentSqlDao transactional) {
         transactional.insertPayment(payment, context);
-        final PaymentModelDao savedPayment = transactional.getPayment(payment.getId().toString());
-        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final PaymentModelDao savedPayment = transactional.getPayment(payment.getId().toString(), context);
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString(), context);
         final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.INSERT);
         transactional.insertHistoryFromTransaction(history, context);
 
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_HISTORY, historyRecordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
         return savedPayment;
     }
 
-    private PaymentAttemptModelDao insertPaymentAttemptFromTransaction(final PaymentAttemptModelDao attempt, final CallContext context, final PaymentAttemptSqlDao transactional) {
+    private PaymentAttemptModelDao insertPaymentAttemptFromTransaction(final PaymentAttemptModelDao attempt, final InternalCallContext context, final PaymentAttemptSqlDao transactional) {
         transactional.insertPaymentAttempt(attempt, context);
-        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attempt.getId().toString());
-        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
+        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attempt.getId().toString(), context);
+        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString(), context);
         final EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.INSERT);
         transactional.insertHistoryFromTransaction(history, context);
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPT_HISTORY, historyRecordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
         return savedAttempt;
     }
 
     @Override
-    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId) {
+    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId, final InternalTenantContext context) {
         return paymentAttemptSqlDao.inTransaction(new Transaction<PaymentAttemptModelDao, PaymentAttemptSqlDao>() {
             @Override
             public PaymentAttemptModelDao inTransaction(final PaymentAttemptSqlDao transactional, final TransactionStatus status)
                     throws Exception {
-                return transactional.getPaymentAttempt(attemptId.toString());
+                return transactional.getPaymentAttempt(attemptId.toString(), context);
             }
         });
     }
@@ -130,7 +128,7 @@ public class AuditedPaymentDao implements PaymentDao {
                                                   final String extFirstPaymentRefId,
                                                   final String extSecondPaymentRefId,
                                                   final UUID attemptId,
-                                                  final CallContext context) {
+                                                  final InternalCallContext context) {
         paymentSqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
 
             @Override
@@ -144,41 +142,43 @@ public class AuditedPaymentDao implements PaymentDao {
         });
     }
 
-    private void updatePaymentAmountFromTransaction(final UUID paymentId, final BigDecimal amount, final CallContext context, final PaymentSqlDao transactional) {
+    private void updatePaymentAmountFromTransaction(final UUID paymentId, final BigDecimal amount, final InternalCallContext context, final PaymentSqlDao transactional) {
         transactional.updatePaymentAmount(paymentId.toString(), amount, context);
-        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
-        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString(), context);
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString(), context);
         final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_HISTORY, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
 
-    private void updatePaymentStatusFromTransaction(final UUID paymentId, final PaymentStatus paymentStatus, final String extFirstPaymentRefId, final String extSecondPaymentRefId, final CallContext context, final PaymentSqlDao transactional) {
+    private void updatePaymentStatusFromTransaction(final UUID paymentId, final PaymentStatus paymentStatus, final String extFirstPaymentRefId,
+                                                    final String extSecondPaymentRefId, final InternalCallContext context, final PaymentSqlDao transactional) {
         transactional.updatePaymentStatusAndExtRef(paymentId.toString(), paymentStatus.toString(), extFirstPaymentRefId, extSecondPaymentRefId, context);
-        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
-        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString(), context);
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString(), context);
         final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_HISTORY, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
 
-    private void updatePaymentAttemptStatusFromTransaction(final UUID attemptId, final PaymentStatus processingStatus, final String gatewayErrorCode, final String gatewayErrorMsg, final CallContext context, final PaymentAttemptSqlDao transactional) {
-        transactional.updatePaymentAttemptStatus(attemptId.toString(), processingStatus.toString(), gatewayErrorCode, gatewayErrorMsg);
-        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attemptId.toString());
-        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
+    private void updatePaymentAttemptStatusFromTransaction(final UUID attemptId, final PaymentStatus processingStatus, final String gatewayErrorCode,
+                                                           final String gatewayErrorMsg, final InternalCallContext context, final PaymentAttemptSqlDao transactional) {
+        transactional.updatePaymentAttemptStatus(attemptId.toString(), processingStatus.toString(), gatewayErrorCode, gatewayErrorMsg, context);
+        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attemptId.toString(), context);
+        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString(), context);
         final EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPT_HISTORY, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
 
     @Override
-    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context) {
+    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final InternalCallContext context) {
         return paymentMethodSqlDao.inTransaction(new Transaction<PaymentMethodModelDao, PaymentMethodSqlDao>() {
             @Override
             public PaymentMethodModelDao inTransaction(final PaymentMethodSqlDao transactional, final TransactionStatus status)
@@ -188,25 +188,25 @@ public class AuditedPaymentDao implements PaymentDao {
         });
     }
 
-    private PaymentMethodModelDao insertPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final PaymentMethodModelDao paymentMethod, final CallContext context) {
+    private PaymentMethodModelDao insertPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final PaymentMethodModelDao paymentMethod, final InternalCallContext context) {
         transactional.insertPaymentMethod(paymentMethod, context);
-        final PaymentMethodModelDao savedPaymentMethod = transactional.getPaymentMethod(paymentMethod.getId().toString());
-        final Long recordId = transactional.getRecordId(savedPaymentMethod.getId().toString());
+        final PaymentMethodModelDao savedPaymentMethod = transactional.getPaymentMethod(paymentMethod.getId().toString(), context);
+        final Long recordId = transactional.getRecordId(savedPaymentMethod.getId().toString(), context);
         final EntityHistory<PaymentMethodModelDao> history = new EntityHistory<PaymentMethodModelDao>(savedPaymentMethod.getId(), recordId, savedPaymentMethod, ChangeType.INSERT);
         transactional.insertHistoryFromTransaction(history, context);
-        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
         final EntityAudit audit = new EntityAudit(TableName.PAYMENT_METHOD_HISTORY, historyRecordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
         return savedPaymentMethod;
     }
 
     @Override
-    public List<PaymentMethodModelDao> refreshPaymentMethods(final UUID accountId, final List<PaymentMethodModelDao> paymentMethods, final CallContext context) {
+    public List<PaymentMethodModelDao> refreshPaymentMethods(final UUID accountId, final List<PaymentMethodModelDao> paymentMethods, final InternalCallContext context) {
         return paymentMethodSqlDao.inTransaction(new Transaction<List<PaymentMethodModelDao>, PaymentMethodSqlDao>() {
 
             @Override
             public List<PaymentMethodModelDao> inTransaction(final PaymentMethodSqlDao transactional, final TransactionStatus status) throws Exception {
-                final List<PaymentMethodModelDao> existingPaymentMethods = getPaymentMethodsInTransaction(transactional, accountId);
+                final List<PaymentMethodModelDao> existingPaymentMethods = getPaymentMethodsInTransaction(transactional, accountId, context);
 
                 final Set<String> externalPaymentIdProcessed = new HashSet<String>();
                 for (final PaymentMethodModelDao finalPaymentMethod : paymentMethods) {
@@ -220,7 +220,7 @@ public class AuditedPaymentDao implements PaymentDao {
                         } else if (existingPaymentMethod.equalsButActive(finalPaymentMethod)) {
                             // We already have it but its status has changed - update it accordingly
                             // Note - in the remote system, the payment method will always be active
-                            undeletedPaymentMethodInTransaction(transactional, existingPaymentMethod.getId());
+                            undeletedPaymentMethodInTransaction(transactional, existingPaymentMethod.getId(), context);
                             isExistingPaymentMethod = true;
                             break;
                         }
@@ -237,29 +237,29 @@ public class AuditedPaymentDao implements PaymentDao {
                 // Finally, mark as deleted the ones that don't exist in the specified list (remote system)
                 for (final PaymentMethodModelDao existingPaymentMethod : existingPaymentMethods) {
                     if (!externalPaymentIdProcessed.contains(existingPaymentMethod.getExternalId())) {
-                        deletedPaymentMethodInTransaction(transactional, existingPaymentMethod.getId());
+                        deletedPaymentMethodInTransaction(transactional, existingPaymentMethod.getId(), context);
                     }
                 }
 
-                return getPaymentMethodsInTransaction(transactional, accountId);
+                return getPaymentMethodsInTransaction(transactional, accountId, context);
             }
         });
     }
 
     @Override
-    public RefundModelDao insertRefund(final RefundModelDao refundInfo, final CallContext context) {
+    public RefundModelDao insertRefund(final RefundModelDao refundInfo, final InternalCallContext context) {
         return refundSqlDao.inTransaction(new Transaction<RefundModelDao, RefundSqlDao>() {
 
             @Override
             public RefundModelDao inTransaction(RefundSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+                                                TransactionStatus status) throws Exception {
 
                 transactional.insertRefund(refundInfo, context);
-                final RefundModelDao savedRefund = transactional.getRefund(refundInfo.getId().toString());
-                final Long recordId = transactional.getRecordId(savedRefund.getId().toString());
+                final RefundModelDao savedRefund = transactional.getRefund(refundInfo.getId().toString(), context);
+                final Long recordId = transactional.getRecordId(savedRefund.getId().toString(), context);
                 final EntityHistory<RefundModelDao> history = new EntityHistory<RefundModelDao>(savedRefund.getId(), recordId, savedRefund, ChangeType.INSERT);
                 transactional.insertHistoryFromTransaction(history, context);
-                final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+                final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
                 final EntityAudit audit = new EntityAudit(TableName.REFUND_HISTORY, historyRecordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
                 return savedRefund;
@@ -267,22 +267,20 @@ public class AuditedPaymentDao implements PaymentDao {
         });
     }
 
-
     @Override
-    public void updateRefundStatus(final UUID refundId,
-            final RefundStatus refundStatus, final CallContext context) {
+    public void updateRefundStatus(final UUID refundId, final RefundStatus refundStatus, final InternalCallContext context) {
         refundSqlDao.inTransaction(new Transaction<Void, RefundSqlDao>() {
 
             @Override
             public Void inTransaction(RefundSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                transactional.updateStatus(refundId.toString(), refundStatus.toString());
+                                      TransactionStatus status) throws Exception {
+                transactional.updateStatus(refundId.toString(), refundStatus.toString(), context);
 
-                final RefundModelDao savedRefund = transactional.getRefund(refundId.toString());
-                final Long recordId = transactional.getRecordId(savedRefund.getId().toString());
+                final RefundModelDao savedRefund = transactional.getRefund(refundId.toString(), context);
+                final Long recordId = transactional.getRecordId(savedRefund.getId().toString(), context);
                 final EntityHistory<RefundModelDao> history = new EntityHistory<RefundModelDao>(savedRefund.getId(), recordId, savedRefund, ChangeType.UPDATE);
                 transactional.insertHistoryFromTransaction(history, context);
-                final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+                final Long historyRecordId = transactional.getHistoryRecordId(recordId, context);
                 final EntityAudit audit = new EntityAudit(TableName.REFUND_HISTORY, historyRecordId, ChangeType.UPDATE);
                 transactional.insertAuditFromTransaction(audit, context);
                 return null;
@@ -291,107 +289,104 @@ public class AuditedPaymentDao implements PaymentDao {
     }
 
     @Override
-    public RefundModelDao getRefund(final UUID refundId) {
+    public RefundModelDao getRefund(final UUID refundId, final InternalTenantContext context) {
         return refundSqlDao.inTransaction(new Transaction<RefundModelDao, RefundSqlDao>() {
 
             @Override
             public RefundModelDao inTransaction(RefundSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                return transactional.getRefund(refundId.toString());
+                                                TransactionStatus status) throws Exception {
+                return transactional.getRefund(refundId.toString(), context);
             }
         });
     }
 
-
     @Override
-    public List<RefundModelDao> getRefundsForPayment(final UUID paymentId) {
+    public List<RefundModelDao> getRefundsForPayment(final UUID paymentId, final InternalTenantContext context) {
         return refundSqlDao.inTransaction(new Transaction<List<RefundModelDao>, RefundSqlDao>() {
 
             @Override
             public List<RefundModelDao> inTransaction(RefundSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                return transactional.getRefundsForPayment(paymentId.toString());
+                                                      TransactionStatus status) throws Exception {
+                return transactional.getRefundsForPayment(paymentId.toString(), context);
             }
         });
     }
 
-
     @Override
-    public List<RefundModelDao> getRefundsForAccount(final UUID accountId) {
+    public List<RefundModelDao> getRefundsForAccount(final UUID accountId, final InternalTenantContext context) {
         return refundSqlDao.inTransaction(new Transaction<List<RefundModelDao>, RefundSqlDao>() {
 
             @Override
             public List<RefundModelDao> inTransaction(RefundSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                return transactional.getRefundsForAccount(accountId.toString());
+                                                      TransactionStatus status) throws Exception {
+                return transactional.getRefundsForAccount(accountId.toString(), context);
             }
         });
     }
 
     @Override
-    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId) {
-        return getPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId);
+    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId, final InternalTenantContext context) {
+        return getPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId, context);
     }
 
     @Override
-    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId) {
-        return paymentMethodSqlDao.getPaymentMethodIncludedDelete(paymentMethodId.toString());
+    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId, final InternalTenantContext context) {
+        return paymentMethodSqlDao.getPaymentMethodIncludedDelete(paymentMethodId.toString(), context);
     }
 
-    private PaymentMethodModelDao getPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId) {
-        return transactional.getPaymentMethod(paymentMethodId.toString());
+    private PaymentMethodModelDao getPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId, final InternalTenantContext context) {
+        return transactional.getPaymentMethod(paymentMethodId.toString(), context);
     }
 
     @Override
-    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId) {
-        return getPaymentMethodsInTransaction(paymentMethodSqlDao, accountId);
+    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId, final InternalTenantContext context) {
+        return getPaymentMethodsInTransaction(paymentMethodSqlDao, accountId, context);
     }
 
-    private List<PaymentMethodModelDao> getPaymentMethodsInTransaction(final PaymentMethodSqlDao transactional, final UUID accountId) {
-        return transactional.getPaymentMethods(accountId.toString());
+    private List<PaymentMethodModelDao> getPaymentMethodsInTransaction(final PaymentMethodSqlDao transactional, final UUID accountId, final InternalTenantContext context) {
+        return transactional.getPaymentMethods(accountId.toString(), context);
     }
 
     @Override
-    public void deletedPaymentMethod(final UUID paymentMethodId) {
-        deletedPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId);
+    public void deletedPaymentMethod(final UUID paymentMethodId, final InternalCallContext context) {
+        deletedPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId, context);
     }
 
-    private void deletedPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId) {
-        transactional.markPaymentMethodAsDeleted(paymentMethodId.toString());
+    private void deletedPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId, final InternalCallContext context) {
+        transactional.markPaymentMethodAsDeleted(paymentMethodId.toString(), context);
     }
 
     @Override
-    public void undeletedPaymentMethod(final UUID paymentMethodId) {
-        undeletedPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId);
+    public void undeletedPaymentMethod(final UUID paymentMethodId, final InternalCallContext context) {
+        undeletedPaymentMethodInTransaction(paymentMethodSqlDao, paymentMethodId, context);
     }
 
-    private void undeletedPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId) {
-        transactional.unmarkPaymentMethodAsDeleted(paymentMethodId.toString());
+    private void undeletedPaymentMethodInTransaction(final PaymentMethodSqlDao transactional, final UUID paymentMethodId, final InternalCallContext context) {
+        transactional.unmarkPaymentMethodAsDeleted(paymentMethodId.toString(), context);
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId) {
-        return paymentSqlDao.getPaymentsForInvoice(invoiceId.toString());
+    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId, final InternalTenantContext context) {
+        return paymentSqlDao.getPaymentsForInvoice(invoiceId.toString(), context);
     }
 
     @Override
-    public PaymentModelDao getLastPaymentForPaymentMethod(final UUID accountId, final UUID paymentMethodId) {
-        return paymentSqlDao.getLastPaymentForAccountAndPaymentMethod(accountId.toString(), paymentMethodId.toString());
+    public PaymentModelDao getLastPaymentForPaymentMethod(final UUID accountId, final UUID paymentMethodId, final InternalTenantContext context) {
+        return paymentSqlDao.getLastPaymentForAccountAndPaymentMethod(accountId.toString(), paymentMethodId.toString(), context);
     }
 
     @Override
-    public PaymentModelDao getPayment(final UUID paymentId) {
-        return paymentSqlDao.getPayment(paymentId.toString());
+    public PaymentModelDao getPayment(final UUID paymentId, final InternalTenantContext context) {
+        return paymentSqlDao.getPayment(paymentId.toString(), context);
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId) {
-        return paymentSqlDao.getPaymentsForAccount(accountId.toString());
+    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId, final InternalTenantContext context) {
+        return paymentSqlDao.getPaymentsForAccount(accountId.toString(), context);
     }
 
     @Override
-    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId) {
-        return paymentAttemptSqlDao.getPaymentAttempts(paymentId.toString());
+    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId, final InternalTenantContext context) {
+        return paymentAttemptSqlDao.getPaymentAttempts(paymentId.toString(), context);
     }
-
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
index f69622f..199ad81 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
@@ -13,8 +13,8 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.payment.dao;
 
+package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
 import java.sql.ResultSet;
@@ -37,8 +37,9 @@ import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTempla
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.payment.api.PaymentStatus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.MapperBase;
@@ -48,30 +49,32 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 @RegisterMapper(PaymentAttemptSqlDao.PaymentAttemptModelDaoMapper.class)
 public interface PaymentAttemptSqlDao extends Transactional<PaymentAttemptSqlDao>, UpdatableEntitySqlDao<PaymentAttemptModelDao>, Transmogrifier, CloseMe {
 
-
     @SqlUpdate
     void insertPaymentAttempt(@Bind(binder = PaymentAttemptModelDaoBinder.class) final PaymentAttemptModelDao attempt,
-                              @CallContextBinder final CallContext context);
+                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     void updatePaymentAttemptStatus(@Bind("id") final String attemptId,
                                     @Bind("processingStatus") final String processingStatus,
                                     @Bind("gatewayErrorCode") final String gatewayErrorCode,
-                                    @Bind("gatewayErrorMsg") final String gatewayErrorMsg);
+                                    @Bind("gatewayErrorMsg") final String gatewayErrorMsg,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    PaymentAttemptModelDao getPaymentAttempt(@Bind("id") final String attemptId);
+    PaymentAttemptModelDao getPaymentAttempt(@Bind("id") final String attemptId,
+                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentAttemptModelDao> getPaymentAttempts(@Bind("paymentId") final String paymentId);
-
+    List<PaymentAttemptModelDao> getPaymentAttempts(@Bind("paymentId") final String paymentId,
+                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
     void insertHistoryFromTransaction(@PaymentAttemptHistoryBinder final EntityHistory<PaymentAttemptModelDao> payment,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     public static final class PaymentAttemptModelDaoBinder extends BinderBase implements Binder<Bind, PaymentAttemptModelDao> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentAttemptModelDao attempt) {
             stmt.bind("id", attempt.getId().toString());
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
index 326389e..baa6c9a 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.util.List;
@@ -20,50 +21,53 @@ import java.util.UUID;
 
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface PaymentDao {
 
     // STEPH do we need object returned?
-    public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt, final CallContext context);
+    public PaymentModelDao insertPaymentWithAttempt(PaymentModelDao paymentInfo, PaymentAttemptModelDao attempt, InternalCallContext context);
 
-    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final CallContext context);
+    public PaymentAttemptModelDao insertNewAttemptForPayment(UUID paymentId, PaymentAttemptModelDao attempt, InternalCallContext context);
 
-    public void updateStatusForPaymentWithAttempt(final UUID paymentId, final PaymentStatus paymentStatus, final String gatewayErrorCode, final String gatewayErrorMsg, final String extFirstPaymentRefId, final String extSecondPaymentRefId, final UUID attemptId, final CallContext context);
+    public void updateStatusForPaymentWithAttempt(UUID paymentId, PaymentStatus paymentStatus, String gatewayErrorCode,
+                                                  String gatewayErrorMsg, String extFirstPaymentRefId, String extSecondPaymentRefId,
+                                                  UUID attemptId, InternalCallContext context);
 
-    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId);
+    public PaymentAttemptModelDao getPaymentAttempt(UUID attemptId, InternalTenantContext context);
 
-    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId);
+    public List<PaymentModelDao> getPaymentsForInvoice(UUID invoiceId, InternalTenantContext context);
 
-    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId);
+    public List<PaymentModelDao> getPaymentsForAccount(UUID accountId, InternalTenantContext context);
 
-    public PaymentModelDao getLastPaymentForPaymentMethod(final UUID accountId, final UUID paymentMethodId);
+    public PaymentModelDao getLastPaymentForPaymentMethod(UUID accountId, UUID paymentMethodId, InternalTenantContext context);
 
-    public PaymentModelDao getPayment(final UUID paymentId);
+    public PaymentModelDao getPayment(UUID paymentId, InternalTenantContext context);
 
-    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId);
+    public List<PaymentAttemptModelDao> getAttemptsForPayment(UUID paymentId, InternalTenantContext context);
 
-    public RefundModelDao insertRefund(RefundModelDao refundInfo, final CallContext context);
+    public RefundModelDao insertRefund(RefundModelDao refundInfo, InternalCallContext context);
 
-    public void updateRefundStatus(UUID refundId, RefundStatus status, final CallContext context);
+    public void updateRefundStatus(UUID refundId, RefundStatus status, InternalCallContext context);
 
-    public RefundModelDao getRefund(UUID refundId);
+    public RefundModelDao getRefund(UUID refundId, InternalTenantContext context);
 
-    public List<RefundModelDao> getRefundsForPayment(final UUID paymentId);
+    public List<RefundModelDao> getRefundsForPayment(UUID paymentId, InternalTenantContext context);
 
-    public List<RefundModelDao> getRefundsForAccount(final UUID accountId);
+    public List<RefundModelDao> getRefundsForAccount(UUID accountId, InternalTenantContext context);
 
-    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context);
+    public PaymentMethodModelDao insertPaymentMethod(PaymentMethodModelDao paymentMethod, InternalCallContext context);
 
-    public List<PaymentMethodModelDao> refreshPaymentMethods(final UUID accountId, final List<PaymentMethodModelDao> paymentMethods, final CallContext context);
+    public List<PaymentMethodModelDao> refreshPaymentMethods(UUID accountId, List<PaymentMethodModelDao> paymentMethods, InternalCallContext context);
 
-    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId);
+    public PaymentMethodModelDao getPaymentMethod(UUID paymentMethodId, InternalTenantContext context);
 
-    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId);
+    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(UUID paymentMethodId, InternalTenantContext context);
 
-    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId);
+    public List<PaymentMethodModelDao> getPaymentMethods(UUID accountId, InternalTenantContext context);
 
-    public void deletedPaymentMethod(final UUID paymentMethodId);
+    public void deletedPaymentMethod(UUID paymentMethodId, InternalCallContext context);
 
-    public void undeletedPaymentMethod(final UUID paymentMethodId);
+    public void undeletedPaymentMethod(UUID paymentMethodId, InternalCallContext context);
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
index 33b101e..8ad616c 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.sql.ResultSet;
@@ -33,8 +34,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.MapperBase;
@@ -44,34 +46,37 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 @RegisterMapper(PaymentMethodSqlDao.PaymentMethodDaoMapper.class)
 public interface PaymentMethodSqlDao extends Transactional<PaymentMethodSqlDao>, UpdatableEntitySqlDao<PaymentMethodModelDao>, Transmogrifier, CloseMe {
 
-
     @SqlUpdate
     void insertPaymentMethod(@Bind(binder = PaymentMethodModelDaoBinder.class) final PaymentMethodModelDao paymentMethod,
-                             @CallContextBinder final CallContext context);
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void markPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId);
+    void markPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void unmarkPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId);
+    void unmarkPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    PaymentMethodModelDao getPaymentMethod(@Bind("id") final String paymentMethodId);
+    PaymentMethodModelDao getPaymentMethod(@Bind("id") final String paymentMethodId,
+                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    PaymentMethodModelDao getPaymentMethodIncludedDelete(@Bind("id") final String paymentMethodId);
+    PaymentMethodModelDao getPaymentMethodIncludedDelete(@Bind("id") final String paymentMethodId,
+                                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentMethodModelDao> getPaymentMethods(@Bind("accountId") final String accountId);
-
+    List<PaymentMethodModelDao> getPaymentMethods(@Bind("accountId") final String accountId,
+                                                  @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
     public void insertHistoryFromTransaction(@PaymentMethodHistoryBinder final EntityHistory<PaymentMethodModelDao> payment,
-                                             @CallContextBinder final CallContext context);
-
+                                             @InternalTenantContextBinder final InternalCallContext context);
 
     public static final class PaymentMethodModelDaoBinder extends BinderBase implements Binder<Bind, PaymentMethodModelDao> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentMethodModelDao method) {
             stmt.bind("id", method.getId().toString());
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index 1cfe4cb..a615a39 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
@@ -37,8 +38,9 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.payment.api.PaymentStatus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.MapperBase;
@@ -50,37 +52,44 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, UpdatableEn
 
     @SqlUpdate
     void insertPayment(@Bind(binder = PaymentModelDaoBinder.class) final PaymentModelDao paymentInfo,
-                       @CallContextBinder final CallContext context);
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void updatePaymentStatusAndExtRef(@Bind("id") final String paymentId, @Bind("paymentStatus") final String paymentStatus,
-            @Bind("extFirstPaymentRefId") final String extFirstPaymentRefId,  @Bind("extSecondPaymentRefId") final String extSecondPaymentRefId,
-            @CallContextBinder final CallContext context);
+    void updatePaymentStatusAndExtRef(@Bind("id") final String paymentId,
+                                      @Bind("paymentStatus") final String paymentStatus,
+                                      @Bind("extFirstPaymentRefId") final String extFirstPaymentRefId,
+                                      @Bind("extSecondPaymentRefId") final String extSecondPaymentRefId,
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void updatePaymentAmount(@Bind("id") final String paymentId, @Bind("amount") final BigDecimal amount,
-                             @CallContextBinder final CallContext context);
+    void updatePaymentAmount(@Bind("id") final String paymentId,
+                             @Bind("amount") final BigDecimal amount,
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    PaymentModelDao getPayment(@Bind("id") final String paymentId);
+    PaymentModelDao getPayment(@Bind("id") final String paymentId,
+                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    PaymentModelDao getLastPaymentForAccountAndPaymentMethod(@Bind("accountId") final String accountId, @Bind("paymentMethodId") final String paymentMethodId);
+    PaymentModelDao getLastPaymentForAccountAndPaymentMethod(@Bind("accountId") final String accountId,
+                                                             @Bind("paymentMethodId") final String paymentMethodId,
+                                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentModelDao> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId);
+    List<PaymentModelDao> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId,
+                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentModelDao> getPaymentsForAccount(@Bind("accountId") final String accountId);
-
+    List<PaymentModelDao> getPaymentsForAccount(@Bind("accountId") final String accountId,
+                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
     void insertHistoryFromTransaction(@PaymentHistoryBinder final EntityHistory<PaymentModelDao> payment,
-                                      @CallContextBinder final CallContext context);
-
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     public static final class PaymentModelDaoBinder extends BinderBase implements Binder<Bind, PaymentModelDao> {
+
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentModelDao payment) {
             stmt.bind("id", payment.getId().toString());
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
index 7d1ff1a..2d21d2e 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
@@ -38,8 +38,9 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.MapperBase;
@@ -51,24 +52,29 @@ public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEnti
 
     @SqlUpdate
     void insertRefund(@Bind(binder = RefundModelDaoBinder.class) final RefundModelDao refundInfo,
-                      @CallContextBinder final CallContext context);
+                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void updateStatus(@Bind("id") final String refundId, @Bind("refundStatus") final String status);
+    void updateStatus(@Bind("id") final String refundId,
+                      @Bind("refundStatus") final String status,
+                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    RefundModelDao getRefund(@Bind("id") final String refundId);
+    RefundModelDao getRefund(@Bind("id") final String refundId,
+                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<RefundModelDao> getRefundsForPayment(@Bind("paymentId") final String paymentId);
+    List<RefundModelDao> getRefundsForPayment(@Bind("paymentId") final String paymentId,
+                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<RefundModelDao> getRefundsForAccount(@Bind("accountId") final String accountId);
+    List<RefundModelDao> getRefundsForAccount(@Bind("accountId") final String accountId,
+                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @Override
     @SqlUpdate
     public void insertHistoryFromTransaction(@RefundHistoryBinder final EntityHistory<RefundModelDao> payment,
-                                             @CallContextBinder final CallContext context);
+                                             @InternalTenantContextBinder final InternalCallContext context);
 
     public static final class RefundModelDaoBinder extends BinderBase implements Binder<Bind, RefundModelDao> {
 
@@ -81,7 +87,7 @@ public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEnti
             stmt.bind("currency", refund.getCurrency().toString());
             stmt.bind("isAdjusted", refund.isAdjsuted());
             stmt.bind("refundStatus", refund.getRefundStatus().toString());
-            // createdDate and updatedDate are populated by the @CallContextBinder
+            // createdDate and updatedDate are populated by the @InternalTenantContextBinder
         }
     }
 
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
index 2db4092..189efdd 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
@@ -31,6 +31,8 @@ import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
 import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
 import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.plugin.api.PaymentProviderAccount;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.common.collect.LinkedListMultimap;
@@ -87,7 +89,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public PaymentInfoPlugin processPayment(final String externalKey, final UUID paymentId, final BigDecimal amount) throws PaymentPluginApiException {
+    public PaymentInfoPlugin processPayment(final String externalKey, final UUID paymentId, final BigDecimal amount, final CallContext context) throws PaymentPluginApiException {
         if (makeNextInvoiceFailWithException.getAndSet(false)) {
             throw new PaymentPluginApiException("", "test error");
         }
@@ -99,7 +101,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public PaymentInfoPlugin getPaymentInfo(final UUID paymentId) throws PaymentPluginApiException {
+    public PaymentInfoPlugin getPaymentInfo(final UUID paymentId, final TenantContext context) throws PaymentPluginApiException {
         final PaymentInfoPlugin payment = payments.get(paymentId);
         if (payment == null) {
             throw new PaymentPluginApiException("", "No payment found for id " + paymentId);
@@ -108,7 +110,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public String createPaymentProviderAccount(final Account account) throws PaymentPluginApiException {
+    public String createPaymentProviderAccount(final Account account, final CallContext context) throws PaymentPluginApiException {
         if (account != null) {
             final String id = UUID.randomUUID().toString();
             final String paymentMethodId = UUID.randomUUID().toString();
@@ -124,7 +126,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public String addPaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault) throws PaymentPluginApiException {
+    public String addPaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault, final CallContext context) throws PaymentPluginApiException {
         final PaymentMethodPlugin realWithID = new DefaultNoOpPaymentMethodPlugin(paymentMethodProps);
         List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
         if (pms == null) {
@@ -137,7 +139,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public void updatePaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps)
+    public void updatePaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps, final CallContext context)
             throws PaymentPluginApiException {
         final DefaultNoOpPaymentMethodPlugin e = getPaymentMethod(accountKey, paymentMethodProps.getExternalPaymentMethodId());
         if (e != null) {
@@ -146,7 +148,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public void deletePaymentMethod(final String accountKey, final String paymentMethodId) throws PaymentPluginApiException {
+    public void deletePaymentMethod(final String accountKey, final String paymentMethodId, final CallContext context) throws PaymentPluginApiException {
         PaymentMethodPlugin toBeDeleted = null;
         final List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
         if (pms != null) {
@@ -164,24 +166,24 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public List<PaymentMethodPlugin> getPaymentMethodDetails(final String accountKey)
+    public List<PaymentMethodPlugin> getPaymentMethodDetails(final String accountKey, final TenantContext context)
             throws PaymentPluginApiException {
         return paymentMethods.get(accountKey);
     }
 
     @Override
-    public PaymentMethodPlugin getPaymentMethodDetail(final String accountKey, final String externalPaymentId)
+    public PaymentMethodPlugin getPaymentMethodDetail(final String accountKey, final String externalPaymentId, final TenantContext context)
             throws PaymentPluginApiException {
         return getPaymentMethod(accountKey, externalPaymentId);
     }
 
     @Override
-    public void setDefaultPaymentMethod(final String accountKey, final String externalPaymentId) throws PaymentPluginApiException {
+    public void setDefaultPaymentMethod(final String accountKey, final String externalPaymentId, final CallContext context) throws PaymentPluginApiException {
     }
 
     @Override
-    public void processRefund(final Account account, final UUID paymentId, final BigDecimal refundAmount) throws PaymentPluginApiException {
-        final PaymentInfoPlugin paymentInfoPlugin = getPaymentInfo(paymentId);
+    public void processRefund(final Account account, final UUID paymentId, final BigDecimal refundAmount, final CallContext context) throws PaymentPluginApiException {
+        final PaymentInfoPlugin paymentInfoPlugin = getPaymentInfo(paymentId, context);
         if (paymentInfoPlugin == null) {
             throw new PaymentPluginApiException("", String.format("No payment found for paymentId %s (plugin %s)", paymentId, getName()));
         }
@@ -199,7 +201,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public int getNbRefundForPaymentAmount(final Account account, final UUID paymentId, final BigDecimal refundAmount) throws PaymentPluginApiException {
+    public int getNbRefundForPaymentAmount(final Account account, final UUID paymentId, final BigDecimal refundAmount, final TenantContext context) throws PaymentPluginApiException {
         int nbRefunds = 0;
         for (final BigDecimal amount : refunds.get(paymentId)) {
             if (amount.compareTo(refundAmount) == 0) {
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/AutoPayRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/AutoPayRetryService.java
index 1ebb798..da55316 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/AutoPayRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/AutoPayRetryService.java
@@ -13,56 +13,52 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.retry;
 
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.core.PaymentProcessor;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.Inject;
 
 public class AutoPayRetryService extends BaseRetryService implements RetryService {
 
-
-    private static final Logger log = LoggerFactory.getLogger(FailedPaymentRetryService.class);
-
     public static final String QUEUE_NAME = "autopayoff";
 
     private final PaymentProcessor paymentProcessor;
 
     @Inject
     public AutoPayRetryService(final NotificationQueueService notificationQueueService,
-            final Clock clock,
-            final PaymentConfig config,
-            final PaymentProcessor paymentProcessor) {
-        super(notificationQueueService, clock, config);
+                               final PaymentConfig config,
+                               final PaymentProcessor paymentProcessor,
+                               final InternalCallContextFactory internalCallContextFactory) {
+        super(notificationQueueService, config, internalCallContextFactory);
         this.paymentProcessor = paymentProcessor;
     }
 
-
     @Override
     public String getQueueName() {
         return QUEUE_NAME;
     }
 
     @Override
-    public void retry(final UUID paymentId) {
-        paymentProcessor.retryAutoPayOff(paymentId);
+    public void retry(final UUID paymentId, final InternalCallContext context) {
+        paymentProcessor.retryAutoPayOff(paymentId, context);
     }
 
     public static class AutoPayRetryServiceScheduler extends RetryServiceScheduler {
 
-
         @Inject
-        public AutoPayRetryServiceScheduler(final NotificationQueueService notificationQueueService) {
-            super(notificationQueueService);
+        public AutoPayRetryServiceScheduler(final NotificationQueueService notificationQueueService,
+                                            final InternalCallContextFactory internalCallContextFactory) {
+            super(notificationQueueService, internalCallContextFactory);
         }
 
         @Override
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
index cd48c67..86a271e 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.retry;
 
 import java.io.IOException;
@@ -23,10 +24,12 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.glue.DefaultPaymentService;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -34,37 +37,44 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 
+import com.google.inject.Inject;
+
 public abstract class BaseRetryService implements RetryService {
 
     private static final Logger log = LoggerFactory.getLogger(BaseRetryService.class);
+    private static final String PAYMENT_RETRY_SERVICE = "PaymentRetryService";
 
     private final NotificationQueueService notificationQueueService;
     private final PaymentConfig config;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private NotificationQueue retryQueue;
 
     public BaseRetryService(final NotificationQueueService notificationQueueService,
-            final Clock clock, final PaymentConfig config) {
+                            final PaymentConfig config,
+                            final InternalCallContextFactory internalCallContextFactory) {
         this.notificationQueueService = notificationQueueService;
-        final Clock clock1 = clock;
         this.config = config;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
-
     @Override
     public void initialize(final String svcName) throws NotificationQueueAlreadyExists {
-        retryQueue = notificationQueueService.createNotificationQueue(svcName, getQueueName(), new NotificationQueueHandler() {
-            @Override
-            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
-                if (! (notificationKey instanceof PaymentRetryNotificationKey)) {
-                    log.error("Payment service got an unexpected notification type {}", notificationKey.getClass().getName());
-                    return;
-                }
-                final PaymentRetryNotificationKey key = (PaymentRetryNotificationKey) notificationKey;
-                retry(key.getUuidKey());
-            }
-        },
-        config);
+        retryQueue = notificationQueueService.createNotificationQueue(svcName,
+                                                                      getQueueName(),
+                                                                      new NotificationQueueHandler() {
+                                                                          @Override
+                                                                          public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
+                                                                              if (!(notificationKey instanceof PaymentRetryNotificationKey)) {
+                                                                                  log.error("Payment service got an unexpected notification type {}", notificationKey.getClass().getName());
+                                                                                  return;
+                                                                              }
+                                                                              final PaymentRetryNotificationKey key = (PaymentRetryNotificationKey) notificationKey;
+                                                                              final InternalCallContext callContext =  internalCallContextFactory.createInternalCallContext(PAYMENT_RETRY_SERVICE, CallOrigin.INTERNAL, UserType.SYSTEM, null);
+                                                                              retry(key.getUuidKey(), callContext);
+                                                                          }
+                                                                      },
+                                                                      config);
     }
 
     @Override
@@ -83,14 +93,16 @@ public abstract class BaseRetryService implements RetryService {
     @Override
     public abstract String getQueueName();
 
-
     public abstract static class RetryServiceScheduler {
 
         private final NotificationQueueService notificationQueueService;
+        private final InternalCallContextFactory internalCallContextFactory;
 
         @Inject
-        public RetryServiceScheduler(final NotificationQueueService notificationQueueService) {
+        public RetryServiceScheduler(final NotificationQueueService notificationQueueService,
+                                     final InternalCallContextFactory internalCallContextFactory) {
             this.notificationQueueService = notificationQueueService;
+            this.internalCallContextFactory = internalCallContextFactory;
         }
 
         public boolean scheduleRetryFromTransaction(final UUID paymentId, final DateTime timeOfRetry, final Transmogrifier transactionalDao) {
@@ -120,15 +132,16 @@ public abstract class BaseRetryService implements RetryService {
         }
 
         private boolean scheduleRetryInternal(final UUID paymentId, final DateTime timeOfRetry, final Transmogrifier transactionalDao) {
+            final InternalCallContext context = createCallContext();
 
             try {
                 final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, getQueueName());
                 final NotificationKey key = new PaymentRetryNotificationKey(paymentId);
                 if (retryQueue != null) {
                     if (transactionalDao == null) {
-                        retryQueue.recordFutureNotification(timeOfRetry, null, key);
+                        retryQueue.recordFutureNotification(timeOfRetry, null, key, context);
                     } else {
-                        retryQueue.recordFutureNotificationFromTransaction(transactionalDao, timeOfRetry, null, key);
+                        retryQueue.recordFutureNotificationFromTransaction(transactionalDao, timeOfRetry, null, key, context);
                     }
                 }
             } catch (NoSuchNotificationQueue e) {
@@ -141,6 +154,10 @@ public abstract class BaseRetryService implements RetryService {
             return true;
         }
 
+        protected InternalCallContext createCallContext() {
+            return internalCallContextFactory.createInternalCallContext(PAYMENT_RETRY_SERVICE, CallOrigin.INTERNAL, UserType.SYSTEM, null);
+        }
+
         public abstract String getQueueName();
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
index 9fd3231..15e87c4 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
@@ -23,14 +23,14 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
-import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.core.PaymentProcessor;
-import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.Inject;
 
 public class FailedPaymentRetryService extends BaseRetryService implements RetryService {
 
@@ -40,25 +40,20 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
 
     private final PaymentProcessor paymentProcessor;
 
-
     @Inject
-    public FailedPaymentRetryService(final AccountUserApi accountUserApi,
-                                     final Clock clock,
-                                     final NotificationQueueService notificationQueueService,
+    public FailedPaymentRetryService(final NotificationQueueService notificationQueueService,
                                      final PaymentConfig config,
                                      final PaymentProcessor paymentProcessor,
-                                     final PaymentDao paymentDao) {
-        super(notificationQueueService, clock, config);
+                                     final InternalCallContextFactory internalCallContextFactory) {
+        super(notificationQueueService, config, internalCallContextFactory);
         this.paymentProcessor = paymentProcessor;
     }
 
-
     @Override
-    public void retry(final UUID paymentId) {
-        paymentProcessor.retryFailedPayment(paymentId);
+    public void retry(final UUID paymentId, final InternalCallContext context) {
+        paymentProcessor.retryFailedPayment(paymentId, context);
     }
 
-
     public static class FailedPaymentRetryServiceScheduler extends RetryServiceScheduler {
 
         private final PaymentConfig config;
@@ -66,8 +61,10 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
 
         @Inject
         public FailedPaymentRetryServiceScheduler(final NotificationQueueService notificationQueueService,
-                                                  final Clock clock, final PaymentConfig config) {
-            super(notificationQueueService);
+                                                  final InternalCallContextFactory internalCallContextFactory,
+                                                  final Clock clock,
+                                                  final PaymentConfig config) {
+            super(notificationQueueService, internalCallContextFactory);
             this.config = config;
             this.clock = clock;
         }
@@ -80,7 +77,6 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
             return super.scheduleRetry(paymentId, timeOfRetry);
         }
 
-
         private DateTime getNextRetryDate(final int retryAttempt) {
 
             DateTime result = null;
@@ -99,7 +95,6 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
             return result;
         }
 
-
         @Override
         public String getQueueName() {
             return QUEUE_NAME;
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
index 6ea381c..587249a 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.retry;
 
 import java.util.UUID;
@@ -22,13 +23,15 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
-import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.core.PaymentProcessor;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.Inject;
+
 public class PluginFailureRetryService extends BaseRetryService implements RetryService {
 
     private static final Logger log = LoggerFactory.getLogger(PluginFailureRetryService.class);
@@ -37,24 +40,20 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
 
     private final PaymentProcessor paymentProcessor;
 
-
     @Inject
-    public PluginFailureRetryService(final AccountUserApi accountUserApi,
-                                     final Clock clock,
-                                     final NotificationQueueService notificationQueueService,
+    public PluginFailureRetryService(final NotificationQueueService notificationQueueService,
                                      final PaymentConfig config,
-                                     final PaymentProcessor paymentProcessor) {
-        super(notificationQueueService, clock, config);
+                                     final PaymentProcessor paymentProcessor,
+                                     final InternalCallContextFactory internalCallContextFactory) {
+        super(notificationQueueService, config, internalCallContextFactory);
         this.paymentProcessor = paymentProcessor;
     }
 
-
     @Override
-    public void retry(final UUID paymentId) {
-        paymentProcessor.retryPluginFailure(paymentId);
+    public void retry(final UUID paymentId, final InternalCallContext context) {
+        paymentProcessor.retryPluginFailure(paymentId, context);
     }
 
-
     public static class PluginFailureRetryServiceScheduler extends RetryServiceScheduler {
 
         private final Clock clock;
@@ -62,8 +61,10 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
 
         @Inject
         public PluginFailureRetryServiceScheduler(final NotificationQueueService notificationQueueService,
-                                                  final Clock clock, final PaymentConfig config) {
-            super(notificationQueueService);
+                                                  final InternalCallContextFactory internalCallContextFactory,
+                                                  final Clock clock,
+                                                  final PaymentConfig config) {
+            super(notificationQueueService, internalCallContextFactory);
             this.clock = clock;
             this.config = config;
         }
@@ -91,7 +92,6 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
 
         private DateTime getNextRetryDate(final int retryAttempt) {
 
-
             if (retryAttempt > config.getPluginFailureRetryMaxAttempts()) {
                 return null;
             }
@@ -102,7 +102,6 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
             }
             return clock.getUTCNow().plusSeconds(nbSec);
         }
-
     }
 
     @Override
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
index b4be707..3df95c8 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
@@ -17,6 +17,7 @@ package com.ning.billing.payment.retry;
 
 import java.util.UUID;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 
@@ -32,6 +33,6 @@ public interface RetryService {
 
     public String getQueueName();
 
-    public void retry(UUID paymentId);
+    public void retry(UUID paymentId, final InternalCallContext context);
 
 }
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
index aa3201a..c6edf85 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group PaymentAttemptSqlDao;
 
+CHECK_TENANT(prefix) ::= "<prefix>tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT(prefix) ::= "AND <CHECK_TENANT(prefix)>"
+
 paymentAttemptFields(prefix) ::= <<
     <prefix>id,
     <prefix>payment_id,    
@@ -10,12 +13,15 @@ paymentAttemptFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertPaymentAttempt() ::= <<
     INSERT INTO payment_attempts (<paymentAttemptFields()>)
-    VALUES (:id, :paymentId, :gatewayErrorCode, :gatewayErrorMsg, :processingStatus, :requestedAmount, :userName, :createdDate, :userName, :createdDate);
+    VALUES (:id, :paymentId, :gatewayErrorCode, :gatewayErrorMsg, :processingStatus, :requestedAmount, :userName,
+            :createdDate, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getPaymentAttempt() ::= <<
@@ -25,7 +31,10 @@ getPaymentAttempt() ::= <<
     , p.invoice_id as invoice_id
       FROM payment_attempts pa join payments p
      WHERE pa.id = :id 
-     AND pa.payment_id = p.id;
+     AND pa.payment_id = p.id
+     <AND_CHECK_TENANT("pa.")>
+     <AND_CHECK_TENANT("p.")>
+     ;
 >>
 
 getPaymentAttempts() ::= <<
@@ -36,6 +45,8 @@ getPaymentAttempts() ::= <<
       FROM payment_attempts pa join payments p
      WHERE pa.payment_id = :paymentId
      AND p.id = :paymentId
+     <AND_CHECK_TENANT("pa.")>
+     <AND_CHECK_TENANT("p.")>
      ORDER BY effective_date ASC;
 >>
 
@@ -44,20 +55,25 @@ updatePaymentAttemptStatus() ::= <<
     SET processing_status = :processingStatus,
         gateway_error_code = :gatewayErrorCode,
         gateway_error_msg = :gatewayErrorMsg        
-    WHERE  id = :id;
+    WHERE  id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
-
 getRecordId() ::= <<
     SELECT record_id
     FROM payment_attempts
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getPaymentAttemptIdFromPaymentId() ::= <<
     SELECT id
     FROM payment_attempts
-    WHERE payment_id = :paymentId;
+    WHERE payment_id = :paymentId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 historyFields(prefix) ::= <<
@@ -71,18 +87,23 @@ historyFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertHistoryFromTransaction() ::= <<
     INSERT INTO payment_attempt_history (<historyFields()>)
-    VALUES (:recordId, :id, :paymentId, :gatewayErrorCode, :gatewayErrorMsg, :processingStatus, :requestedAmount, :userName, :createdDate, :userName, :updatedDate);
+    VALUES (:recordId, :id, :paymentId, :gatewayErrorCode, :gatewayErrorMsg, :processingStatus, :requestedAmount,
+            :userName, :createdDate, :userName, :updatedDate, :accountRecordId, :tenantRecordId);
 >>
 
 getHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
     FROM payment_attempt_history
-    WHERE record_id = :recordId;
+    WHERE record_id = :recordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -93,12 +114,14 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentMethodSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentMethodSqlDao.sql.stg
index bff218a..f7fcd4a 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentMethodSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentMethodSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group PaymentMethodSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 paymentMethodFields(prefix) ::= <<
     <prefix>id,
     <prefix>account_id,
@@ -9,30 +12,38 @@ paymentMethodFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertPaymentMethod() ::= <<
     INSERT INTO payment_methods (<paymentMethodFields()>)
-    VALUES (:id, :accountId, :pluginName , :isActive, :externalId, :userName, :createdDate, :userName, :createdDate);
+    VALUES (:id, :accountId, :pluginName , :isActive, :externalId, :userName, :createdDate, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 markPaymentMethodAsDeleted() ::= <<
     UPDATE payment_methods 
     SET is_active = 0
-    WHERE  id = :id;
+    WHERE  id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 unmarkPaymentMethodAsDeleted() ::= <<
     UPDATE payment_methods
     SET is_active = 1
-    WHERE  id = :id;
+    WHERE  id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getPaymentMethod() ::= <<
     SELECT <paymentMethodFields()>
       FROM payment_methods
-    WHERE id = :id AND is_active = 1;
+    WHERE id = :id AND is_active = 1
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getPaymentMethodIncludedDelete() ::= <<
@@ -44,13 +55,17 @@ getPaymentMethodIncludedDelete() ::= <<
 getPaymentMethods() ::= <<
     SELECT <paymentMethodFields()>
       FROM payment_methods
-    WHERE account_id = :accountId AND is_active = 1;
+    WHERE account_id = :accountId AND is_active = 1
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM payment_methods
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 historyFields(prefix) ::= <<
@@ -63,18 +78,22 @@ historyFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertHistoryFromTransaction() ::= <<
     INSERT INTO payment_method_history (<historyFields()>)
-    VALUES (:recordId, :id, :accountId, :pluginName , :isActive, :externalId ,:userName, :createdDate, :userName, :createdDate);
+    VALUES (:recordId, :id, :accountId, :pluginName , :isActive, :externalId ,:userName, :createdDate, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
     FROM payment_method_history
-    WHERE record_id = :recordId;
+    WHERE record_id = :recordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -85,12 +104,14 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
index a5f84b0..f2170b3 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group PaymentSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 paymentFields(prefix) ::= <<
     <prefix>id,
     <prefix>account_id,
@@ -14,19 +17,24 @@ paymentFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertPayment() ::= <<
     INSERT INTO payments (<paymentFields()>)
-    VALUES (:id, :accountId, :invoiceId, :paymentMethodId, :amount, :effectiveDate, :currency, :paymentStatus, :extFirstPaymentRefId, :extSecondPaymentRefId, :userName, :createdDate, :userName, :createdDate);
+    VALUES (:id, :accountId, :invoiceId, :paymentMethodId, :amount, :effectiveDate, :currency, :paymentStatus,
+            :extFirstPaymentRefId, :extSecondPaymentRefId, :userName, :createdDate, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getPayment() ::= <<
     SELECT <paymentFields()>
     , record_id as payment_number
       FROM payments
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getLastPaymentForAccountAndPaymentMethod() ::= <<
@@ -34,6 +42,7 @@ getLastPaymentForAccountAndPaymentMethod() ::= <<
     , record_id as payment_number
       FROM payments
     WHERE account_id = :accountId AND payment_method_id = :paymentMethodId
+    <AND_CHECK_TENANT()>
     ORDER BY effective_date desc limit 1;
 >> 
 
@@ -41,14 +50,18 @@ getPaymentsForInvoice() ::= <<
     SELECT <paymentFields()>
     , record_id as payment_number
       FROM payments
-    WHERE invoice_id = :invoiceId;
+    WHERE invoice_id = :invoiceId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getPaymentsForAccount() ::= <<
     SELECT <paymentFields()>
     , record_id as payment_number
       FROM payments
-    WHERE account_id = :accountId;
+    WHERE account_id = :accountId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 
@@ -57,19 +70,25 @@ updatePaymentStatusAndExtRef() ::= <<
     SET payment_status = :paymentStatus,
         ext_first_payment_ref_id = :extFirstPaymentRefId,
         ext_second_payment_ref_id = :extSecondPaymentRefId
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 updatePaymentAmount() ::= <<
     UPDATE payments
     SET amount = :amount
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordId() ::= <<
     SELECT record_id
     FROM payments
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 
@@ -88,19 +107,24 @@ historyFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date 
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertHistoryFromTransaction() ::= <<
     INSERT INTO payment_history (<historyFields()>)
-    VALUES (:recordId, :id, :accountId, :invoiceId, :paymentMethodId, :amount, :effectiveDate, :currency, :paymentStatus, :extFirstPaymentRefId, :extSecondPaymentRefId, :userName, :createdDate, :userName, :updatedDate);
+    VALUES (:recordId, :id, :accountId, :invoiceId, :paymentMethodId, :amount, :effectiveDate, :currency, :paymentStatus,
+            :extFirstPaymentRefId, :extSecondPaymentRefId, :userName, :createdDate, :userName, :updatedDate, :accountRecordId, :tenantRecordId);
 >>
 
 
 getHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
     FROM payment_history
-    WHERE record_id = :recordId;
+    WHERE record_id = :recordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -111,11 +135,13 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/RefundSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/RefundSqlDao.sql.stg
index d1e8719..e277a4e 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/RefundSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/RefundSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group RefundSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 refundFields(prefix) ::= <<
 <prefix>id,
 <prefix>account_id,
@@ -11,42 +14,55 @@ refundFields(prefix) ::= <<
 <prefix>created_by,
 <prefix>created_date,
 <prefix>updated_by,
-<prefix>updated_date
+<prefix>updated_date,
+<prefix>account_record_id,
+<prefix>tenant_record_id
 >>
 
 insertRefund() ::= <<
     INSERT INTO refunds (<refundFields()>)
-    VALUES (:id, :accountId, :paymentId, :amount, :currency, :isAdjusted, :refundStatus, :userName, :createdDate, :userName, :createdDate);
+    VALUES (:id, :accountId, :paymentId, :amount, :currency, :isAdjusted, :refundStatus, :userName, :createdDate,
+            :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 updateStatus() ::= <<
     UPDATE refunds
     SET refund_status = :refundStatus
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRefund() ::= <<
     SELECT <refundFields()>
     FROM refunds
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRefundsForPayment()  ::= <<
     SELECT <refundFields()>
     FROM refunds
-    WHERE payment_id = :paymentId;
+    WHERE payment_id = :paymentId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRefundsForAccount()  ::= <<
     SELECT <refundFields()>
     FROM refunds
-    WHERE account_id = :accountId;
+    WHERE account_id = :accountId
+    <AND_CHECK_TENANT()>
+    ;
 >> 
 
 getRecordId() ::= <<
     SELECT record_id
     FROM refunds
-    WHERE id = :id;
+    WHERE id = :id
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 historyFields(prefix) ::= <<
@@ -61,18 +77,23 @@ historyFields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertHistoryFromTransaction() ::= <<
     INSERT INTO refund_history (<historyFields()>)
-    VALUES (:recordId, :id, :accountId, :paymentId, :amount, :currency,  :isAdjusted, :refundStatus, :userName, :createdDate, :userName, :createdDate);
+    VALUES (:recordId, :id, :accountId, :paymentId, :amount, :currency,  :isAdjusted, :refundStatus, :userName,
+            :createdDate, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 getHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
     FROM payment_method_history
-    WHERE record_id = :recordId;
+    WHERE record_id = :recordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -83,10 +104,12 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index f3a57e3..690305d 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -21,8 +21,6 @@ import java.math.RoundingMode;
 import java.util.List;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.mockito.Mockito;
 import org.slf4j.Logger;
@@ -33,7 +31,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
@@ -50,13 +47,11 @@ import com.ning.billing.payment.glue.PaymentTestModuleWithMocks;
 import com.ning.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.glue.CallContextModule;
 
+import com.google.inject.Inject;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
@@ -79,15 +74,8 @@ public class TestPaymentApi extends PaymentTestSuite {
     @Inject
     protected Clock clock;
 
-    protected CallContext context;
-
     private Account account;
 
-    @Inject
-    public TestPaymentApi(final Clock clock) {
-        context = new DefaultCallContext("Payment Tests", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
-    }
-
     @BeforeClass(groups = "fast")
     public void setupClass() throws Exception {
         account = testHelper.createTestAccount("yoyo.yahoo.com", false);
@@ -143,7 +131,7 @@ public class TestPaymentApi extends PaymentTestSuite {
 
     private void testSimplePayment(final BigDecimal invoiceAmount, final BigDecimal requestedAmount, final BigDecimal expectedAmount) throws Exception {
         final LocalDate now = clock.getUTCToday();
-        final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
+        final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD, callContext);
 
         final UUID subscriptionId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
@@ -159,7 +147,7 @@ public class TestPaymentApi extends PaymentTestSuite {
                                                             Currency.USD));
 
         try {
-            final Payment paymentInfo = paymentApi.createPayment(account, invoice.getId(), requestedAmount, context);
+            final Payment paymentInfo = paymentApi.createPayment(account, invoice.getId(), requestedAmount, callContext);
             if (expectedAmount == null) {
                 fail("Expected to fail because requested amount > invoice amount");
             }
@@ -186,41 +174,37 @@ public class TestPaymentApi extends PaymentTestSuite {
 
     @Test(groups = "fast")
     public void testPaymentMethods() throws Exception {
-        List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, false);
+        List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, false, callContext);
         assertEquals(methods.size(), 1);
 
         final PaymentMethod initDefaultMethod = methods.get(0);
         assertEquals(initDefaultMethod.getId(), account.getPaymentMethodId());
 
         final PaymentMethodPlugin newPaymenrMethod = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
-        final UUID newPaymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, newPaymenrMethod, context);
+        final UUID newPaymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, newPaymenrMethod, callContext);
         Mockito.when(account.getPaymentMethodId()).thenReturn(newPaymentMethodId);
 
-        methods = paymentApi.getPaymentMethods(account, false);
+        methods = paymentApi.getPaymentMethods(account, false, callContext);
         assertEquals(methods.size(), 2);
 
         assertEquals(newPaymentMethodId, account.getPaymentMethodId());
 
         boolean failed = false;
         try {
-            paymentApi.deletedPaymentMethod(account, newPaymentMethodId, false, context);
+            paymentApi.deletedPaymentMethod(account, newPaymentMethodId, false, callContext);
         } catch (PaymentApiException e) {
             failed = true;
         }
         assertTrue(failed);
 
-        paymentApi.deletedPaymentMethod(account, initDefaultMethod.getId(), true,  context);
-        methods = paymentApi.getPaymentMethods(account, false);
+        paymentApi.deletedPaymentMethod(account, initDefaultMethod.getId(), true,  callContext);
+        methods = paymentApi.getPaymentMethods(account, false, callContext);
         assertEquals(methods.size(), 1);
 
         // NOW retry with default payment method with special flag
-        paymentApi.deletedPaymentMethod(account, newPaymentMethodId, true, context);
+        paymentApi.deletedPaymentMethod(account, newPaymentMethodId, true, callContext);
 
-        methods = paymentApi.getPaymentMethods(account, false);
+        methods = paymentApi.getPaymentMethods(account, false, callContext);
         assertEquals(methods.size(), 0);
-
-
-
     }
-
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/core/TestPaymentMethodProcessor.java b/payment/src/test/java/com/ning/billing/payment/core/TestPaymentMethodProcessor.java
index 68f95b9..2c36433 100644
--- a/payment/src/test/java/com/ning/billing/payment/core/TestPaymentMethodProcessor.java
+++ b/payment/src/test/java/com/ning/billing/payment/core/TestPaymentMethodProcessor.java
@@ -35,10 +35,7 @@ import com.ning.billing.payment.provider.DefaultPaymentProviderPluginRegistry;
 import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.clock.DefaultClock;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
 public class TestPaymentMethodProcessor extends PaymentTestSuite {
@@ -50,14 +47,13 @@ public class TestPaymentMethodProcessor extends PaymentTestSuite {
         final DefaultPaymentProviderPluginRegistry pluginRegistry = new DefaultPaymentProviderPluginRegistry(Mockito.mock(PaymentConfig.class));
         pluginRegistry.register(new ExternalPaymentProviderPlugin(new ClockMock()), ExternalPaymentProviderPlugin.PLUGIN_NAME);
 
-        final Clock clock = new DefaultClock();
         final AccountUserApi accountUserApi = Mockito.mock(AccountUserApi.class);
         final Bus bus = Mockito.mock(Bus.class);
         final MockPaymentDao paymentDao = new MockPaymentDao();
         final GlobalLocker globalLocker = Mockito.mock(GlobalLocker.class);
         final ExecutorService executorService = Mockito.mock(ExecutorService.class);
         final TagUserApi tagUserApi =  Mockito.mock(TagUserApi.class);
-        processor = new PaymentMethodProcessor(pluginRegistry, accountUserApi, bus, paymentDao, tagUserApi, clock, globalLocker, executorService);
+        processor = new PaymentMethodProcessor(pluginRegistry, accountUserApi, bus, paymentDao, tagUserApi, globalLocker, executorService);
     }
 
     @Test(groups = "fast")
@@ -66,14 +62,13 @@ public class TestPaymentMethodProcessor extends PaymentTestSuite {
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getId()).thenReturn(accountId);
         Mockito.when(account.getExternalKey()).thenReturn(accountId.toString());
-        final CallContext context = Mockito.mock(CallContext.class);
 
-        Assert.assertEquals(processor.getPaymentMethods(account, false).size(), 0);
+        Assert.assertEquals(processor.getPaymentMethods(account, false, internalCallContext).size(), 0);
 
         // The first call should create the payment method
-        final ExternalPaymentProviderPlugin providerPlugin = processor.getExternalPaymentProviderPlugin(account, context);
+        final ExternalPaymentProviderPlugin providerPlugin = processor.getExternalPaymentProviderPlugin(account, internalCallContext);
         Assert.assertEquals(providerPlugin.getName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
-        final List<PaymentMethod> paymentMethods = processor.getPaymentMethods(account, false);
+        final List<PaymentMethod> paymentMethods = processor.getPaymentMethods(account, false, internalCallContext);
         Assert.assertEquals(paymentMethods.size(), 1);
         Assert.assertEquals(paymentMethods.get(0).getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
         Assert.assertEquals(paymentMethods.get(0).getAccountId(), account.getId());
@@ -81,10 +76,10 @@ public class TestPaymentMethodProcessor extends PaymentTestSuite {
         // The succeeding calls should not create any other payment method
         final UUID externalPaymentMethodId = paymentMethods.get(0).getId();
         for (int i = 0; i < 50; i++) {
-            final ExternalPaymentProviderPlugin foundProviderPlugin = processor.getExternalPaymentProviderPlugin(account, context);
+            final ExternalPaymentProviderPlugin foundProviderPlugin = processor.getExternalPaymentProviderPlugin(account, internalCallContext);
             Assert.assertEquals(foundProviderPlugin.getName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
 
-            final List<PaymentMethod> foundPaymentMethods = processor.getPaymentMethods(account, false);
+            final List<PaymentMethod> foundPaymentMethods = processor.getPaymentMethods(account, false, internalCallContext);
             Assert.assertEquals(foundPaymentMethods.size(), 1);
             Assert.assertEquals(foundPaymentMethods.get(0).getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
             Assert.assertEquals(foundPaymentMethods.get(0).getAccountId(), account.getId());
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
index 0c08df9..0903b39 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.util.ArrayList;
@@ -26,7 +27,8 @@ import java.util.UUID;
 
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public class MockPaymentDao implements PaymentDao {
 
@@ -35,7 +37,7 @@ public class MockPaymentDao implements PaymentDao {
 
     @Override
     public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt,
-                                                    final CallContext context) {
+                                                    final InternalCallContext context) {
         synchronized (this) {
             payments.put(paymentInfo.getId(), paymentInfo);
             attempts.put(attempt.getId(), attempt);
@@ -44,20 +46,17 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId,
-                                                             final PaymentAttemptModelDao attempt, final CallContext context) {
+    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
         synchronized (this) {
             attempts.put(attempt.getId(), attempt);
         }
         return attempt;
     }
 
-
     @Override
-    public void updateStatusForPaymentWithAttempt(UUID paymentId,
-            PaymentStatus paymentStatus, String gatewayErrorCode, String gatewayErrorMsg,
-            String extFirstPaymentRefId, String extSecondPaymentRefId,
-            UUID attemptId, CallContext context) {
+    public void updateStatusForPaymentWithAttempt(final UUID paymentId, final PaymentStatus paymentStatus, final String gatewayErrorCode,
+                                                  final String gatewayErrorMsg, final String extFirstPaymentRefId, final String extSecondPaymentRefId,
+                                                  final UUID attemptId, final InternalCallContext context) {
         synchronized (this) {
             final PaymentModelDao entry = payments.remove(paymentId);
             if (entry != null) {
@@ -71,12 +70,12 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId) {
+    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId, final InternalTenantContext context) {
         return attempts.get(attemptId);
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId) {
+    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId, final InternalTenantContext context) {
         final List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
         synchronized (this) {
             for (final PaymentModelDao cur : payments.values()) {
@@ -89,7 +88,7 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId) {
+    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId, final InternalTenantContext context) {
         final List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
         synchronized (this) {
             for (final PaymentModelDao cur : payments.values()) {
@@ -102,12 +101,12 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentModelDao getPayment(final UUID paymentId) {
+    public PaymentModelDao getPayment(final UUID paymentId, final InternalTenantContext context) {
         return payments.get(paymentId);
     }
 
     @Override
-    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId) {
+    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId, final InternalTenantContext context) {
         final List<PaymentAttemptModelDao> result = new ArrayList<PaymentAttemptModelDao>();
         synchronized (this) {
             for (final PaymentAttemptModelDao cur : attempts.values()) {
@@ -122,18 +121,18 @@ public class MockPaymentDao implements PaymentDao {
     private final List<PaymentMethodModelDao> paymentMethods = new LinkedList<PaymentMethodModelDao>();
 
     @Override
-    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context) {
+    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final InternalCallContext context) {
         paymentMethods.add(paymentMethod);
         return paymentMethod;
     }
 
     @Override
-    public List<PaymentMethodModelDao> refreshPaymentMethods(final UUID accountId, final List<PaymentMethodModelDao> newPaymentMethods, final CallContext context) {
+    public List<PaymentMethodModelDao> refreshPaymentMethods(final UUID accountId, final List<PaymentMethodModelDao> newPaymentMethods, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId) {
+    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId, final InternalTenantContext context) {
         for (final PaymentMethodModelDao cur : paymentMethods) {
             if (cur.getId().equals(paymentMethodId)) {
                 return cur;
@@ -143,7 +142,7 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId) {
+    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId, final InternalTenantContext context) {
         final List<PaymentMethodModelDao> result = new ArrayList<PaymentMethodModelDao>();
         for (final PaymentMethodModelDao cur : paymentMethods) {
             if (cur.getAccountId().equals(accountId)) {
@@ -154,7 +153,7 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public void deletedPaymentMethod(final UUID paymentMethodId) {
+    public void deletedPaymentMethod(final UUID paymentMethodId, final InternalCallContext context) {
         final Iterator<PaymentMethodModelDao> it = paymentMethods.iterator();
         while (it.hasNext()) {
             final PaymentMethodModelDao cur = it.next();
@@ -166,45 +165,41 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public void undeletedPaymentMethod(final UUID paymentMethodId) {
+    public void undeletedPaymentMethod(final UUID paymentMethodId, final InternalCallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public RefundModelDao insertRefund(RefundModelDao refundInfo,
-            CallContext context) {
+    public RefundModelDao insertRefund(final RefundModelDao refundInfo, final InternalCallContext context) {
         return null;
     }
 
     @Override
-    public void updateRefundStatus(UUID refundId, RefundStatus status,
-            CallContext context) {
+    public void updateRefundStatus(final UUID refundId, final RefundStatus status, final InternalCallContext context) {
     }
 
     @Override
-    public RefundModelDao getRefund(UUID refundId) {
+    public RefundModelDao getRefund(final UUID refundId, final InternalTenantContext context) {
         return null;
     }
 
     @Override
-    public List<RefundModelDao> getRefundsForPayment(UUID paymentId) {
+    public List<RefundModelDao> getRefundsForPayment(final UUID paymentId, final InternalTenantContext context) {
         return Collections.emptyList();
     }
 
     @Override
-    public List<RefundModelDao> getRefundsForAccount(UUID accountId) {
+    public List<RefundModelDao> getRefundsForAccount(final UUID accountId, final InternalTenantContext context) {
         return Collections.emptyList();
     }
 
     @Override
-    public PaymentModelDao getLastPaymentForPaymentMethod(UUID accountId,
-            UUID paymentMethodId) {
+    public PaymentModelDao getLastPaymentForPaymentMethod(final UUID accountId, final UUID paymentMethodId, final InternalTenantContext context) {
         return null;
     }
 
     @Override
-    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(
-            UUID paymentMethodId) {
-        return getPaymentMethod(paymentMethodId);
+    public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId, final InternalTenantContext context) {
+        return getPaymentMethod(paymentMethodId, context);
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index 5f3951b..8190f77 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -25,9 +25,7 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
-import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
@@ -38,8 +36,6 @@ import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.payment.PaymentTestSuiteWithEmbeddedDB;
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TestCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
@@ -49,7 +45,6 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.fail;
 
 public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
-    private static final CallContext context = new TestCallContext("PaymentTests");
 
     private PaymentDao paymentDao;
     private MysqlTestingHelper helper;
@@ -83,10 +78,10 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         final BigDecimal amount1 = new BigDecimal(13);
         final Currency currency = Currency.USD;
 
-        RefundModelDao refund1 = new RefundModelDao(accountId, paymentId1, amount1, currency, true);
+        final RefundModelDao refund1 = new RefundModelDao(accountId, paymentId1, amount1, currency, true);
 
-        paymentDao.insertRefund(refund1, context);
-        RefundModelDao refundCheck = paymentDao.getRefund(refund1.getId());
+        paymentDao.insertRefund(refund1, internalCallContext);
+        final RefundModelDao refundCheck = paymentDao.getRefund(refund1.getId(), internalCallContext);
         assertNotNull(refundCheck);
         assertEquals(refundCheck.getAccountId(), accountId);
         assertEquals(refundCheck.getPaymentId(), paymentId1);
@@ -99,16 +94,16 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         final UUID paymentId2 = UUID.randomUUID();
 
         RefundModelDao refund2 = new RefundModelDao(accountId, paymentId2, amount2, currency, true);
-        paymentDao.insertRefund(refund2, context);
-        paymentDao.updateRefundStatus(refund2.getId(), RefundStatus.COMPLETED, context);
+        paymentDao.insertRefund(refund2, internalCallContext);
+        paymentDao.updateRefundStatus(refund2.getId(), RefundStatus.COMPLETED, internalCallContext);
 
-        List<RefundModelDao> refundChecks = paymentDao.getRefundsForPayment(paymentId1);
+        List<RefundModelDao> refundChecks = paymentDao.getRefundsForPayment(paymentId1, internalCallContext);
         assertEquals(refundChecks.size(), 1);
 
-        refundChecks = paymentDao.getRefundsForPayment(paymentId2);
+        refundChecks = paymentDao.getRefundsForPayment(paymentId2, internalCallContext);
         assertEquals(refundChecks.size(), 1);
 
-        refundChecks = paymentDao.getRefundsForAccount(accountId);
+        refundChecks = paymentDao.getRefundsForAccount(accountId, internalCallContext);
         assertEquals(refundChecks.size(), 2);
         for (RefundModelDao cur : refundChecks) {
             if (cur.getPaymentId().equals(paymentId1)) {
@@ -134,14 +129,14 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
 
         final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
+        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, internalCallContext);
 
         final PaymentStatus paymentStatus = PaymentStatus.SUCCESS;
         final String gatewayErrorCode = "OK";
 
-        paymentDao.updateStatusForPaymentWithAttempt(payment.getId(), paymentStatus, gatewayErrorCode, null, null, null, attempt.getId(), context);
+        paymentDao.updateStatusForPaymentWithAttempt(payment.getId(), paymentStatus, gatewayErrorCode, null, null, null, attempt.getId(), internalCallContext);
 
-        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId, internalCallContext);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
@@ -153,7 +148,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
         assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.SUCCESS);
 
-        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId(), internalCallContext);
         assertEquals(attempts.size(), 1);
         final PaymentAttemptModelDao savedAttempt = attempts.get(0);
         assertEquals(savedAttempt.getId(), attempt.getId());
@@ -177,7 +172,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
 
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
+        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, internalCallContext);
         assertEquals(savedPayment.getId(), payment.getId());
         assertEquals(savedPayment.getAccountId(), accountId);
         assertEquals(savedPayment.getInvoiceId(), invoiceId);
@@ -187,14 +182,14 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
         assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-        PaymentAttemptModelDao savedAttempt = paymentDao.getPaymentAttempt(attempt.getId());
+        PaymentAttemptModelDao savedAttempt = paymentDao.getPaymentAttempt(attempt.getId(), internalCallContext);
         assertEquals(savedAttempt.getId(), attempt.getId());
         assertEquals(savedAttempt.getPaymentId(), payment.getId());
         assertEquals(savedAttempt.getAccountId(), accountId);
         assertEquals(savedAttempt.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId, internalCallContext);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
@@ -206,7 +201,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
         assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId(), internalCallContext);
         assertEquals(attempts.size(), 1);
         savedAttempt = attempts.get(0);
         assertEquals(savedAttempt.getId(), attempt.getId());
@@ -228,10 +223,9 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
 
         final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
         final PaymentAttemptModelDao firstAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, firstAttempt, context);
+        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, firstAttempt, internalCallContext);
 
-
-        final PaymentModelDao lastPayment = paymentDao.getLastPaymentForPaymentMethod(accountId, paymentMethodId);
+        final PaymentModelDao lastPayment = paymentDao.getLastPaymentForPaymentMethod(accountId, paymentMethodId, internalCallContext);
         assertNotNull(lastPayment);
         assertEquals(lastPayment.getId(), payment.getId());
         assertEquals(lastPayment.getAccountId(), accountId);
@@ -242,12 +236,11 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(lastPayment.getEffectiveDate().compareTo(effectiveDate), 0);
         assertEquals(lastPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-
         final BigDecimal newAmount = new BigDecimal(15.23).setScale(2, RoundingMode.HALF_EVEN);
         final PaymentAttemptModelDao secondAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), newAmount);
-        paymentDao.insertNewAttemptForPayment(payment.getId(), secondAttempt, context);
+        paymentDao.insertNewAttemptForPayment(payment.getId(), secondAttempt, internalCallContext);
 
-        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId, internalCallContext);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
@@ -259,7 +252,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
         assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId(), internalCallContext);
         assertEquals(attempts.size(), 2);
         final PaymentAttemptModelDao savedAttempt1 = attempts.get(0);
         assertEquals(savedAttempt1.getPaymentId(), payment.getId());
@@ -291,13 +284,13 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
 
         final PaymentMethodModelDao method = new PaymentMethodModelDao(paymentMethodId, accountId, pluginName, isActive, externalPaymentId);
 
-        PaymentMethodModelDao savedMethod = paymentDao.insertPaymentMethod(method, context);
+        PaymentMethodModelDao savedMethod = paymentDao.insertPaymentMethod(method, internalCallContext);
         assertEquals(savedMethod.getId(), paymentMethodId);
         assertEquals(savedMethod.getAccountId(), accountId);
         assertEquals(savedMethod.getPluginName(), pluginName);
         assertEquals(savedMethod.isActive(), isActive);
 
-        final List<PaymentMethodModelDao> result = paymentDao.getPaymentMethods(accountId);
+        final List<PaymentMethodModelDao> result = paymentDao.getPaymentMethods(accountId, internalCallContext);
         assertEquals(result.size(), 1);
         savedMethod = result.get(0);
         assertEquals(savedMethod.getId(), paymentMethodId);
@@ -306,9 +299,9 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedMethod.isActive(), isActive);
         assertEquals(savedMethod.getExternalId(), externalPaymentId);
 
-        paymentDao.deletedPaymentMethod(paymentMethodId);
+        paymentDao.deletedPaymentMethod(paymentMethodId, internalCallContext);
 
-        final PaymentMethodModelDao deletedPaymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
+        final PaymentMethodModelDao deletedPaymentMethod = paymentDao.getPaymentMethod(paymentMethodId, internalCallContext);
         assertNull(deletedPaymentMethod);
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
index c253ff3..936f7c0 100644
--- a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
+++ b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
@@ -18,15 +18,13 @@ package com.ning.billing.payment.glue;
 
 import java.io.IOException;
 import java.net.URL;
-import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 
 import org.mockito.Mockito;
-import org.skife.config.ConfigSource;
 import org.skife.config.SimplePropertyConfigSource;
+import org.skife.jdbi.v2.IDBI;
 
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.mock.glue.MockInvoiceModule;
 import com.ning.billing.mock.glue.MockNotificationQueueModule;
@@ -34,6 +32,9 @@ import com.ning.billing.payment.dao.MockPaymentDao;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContextSqlDao;
+import com.ning.billing.util.callcontext.MockCallContextSqlDao;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MockGlobalLocker;
@@ -41,6 +42,8 @@ import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
 import com.ning.billing.util.tag.Tag;
 
+import com.google.common.collect.ImmutableMap;
+
 import static org.testng.Assert.assertNotNull;
 
 public class PaymentTestModuleWithMocks extends PaymentModule {
@@ -63,21 +66,11 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
         }
     }
 
-    private static final class MapConfigSource implements ConfigSource {
-        private final Map<String, String> map;
-
-        private MapConfigSource(final Map<String, String> map) {
-            this.map = map;
-        }
-
-        @Override
-        public String getString(final String propertyName) {
-            return map.get(propertyName);
-        }
-    }
-
     @Override
     protected void installPaymentDao() {
+        final IDBI idbi = Mockito.mock(IDBI.class);
+        Mockito.when(idbi.onDemand(CallContextSqlDao.class)).thenReturn(new MockCallContextSqlDao());
+        bind(IDBI.class).toInstance(idbi);
         bind(PaymentDao.class).to(MockPaymentDao.class).asEagerSingleton();
     }
 
@@ -96,7 +89,7 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
 
         final TagUserApi tagUserApi = Mockito.mock(TagUserApi.class);
         bind(TagUserApi.class).toInstance(tagUserApi);
-        Mockito.when(tagUserApi.getTags(Mockito.<UUID>any(), Mockito.<ObjectType>any())).thenReturn(ImmutableMap.<String, Tag>of());
+        Mockito.when(tagUserApi.getTags(Mockito.<UUID>any(), Mockito.<ObjectType>any(), Mockito.<TenantContext>any())).thenReturn(ImmutableMap.<String, Tag>of());
 
         bind(GlobalLocker.class).to(MockGlobalLocker.class).asEagerSingleton();
     }
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
index ff07534..9c8a2c8 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
@@ -53,7 +53,7 @@ public class TestExternalPaymentProviderPlugin extends PaymentTestSuite {
         final String externalKey = UUID.randomUUID().toString();
         final UUID paymentId = UUID.randomUUID();
         final BigDecimal amount = BigDecimal.TEN;
-        final PaymentInfoPlugin paymentInfoPlugin = plugin.processPayment(externalKey, paymentId, amount);
+        final PaymentInfoPlugin paymentInfoPlugin = plugin.processPayment(externalKey, paymentId, amount, callContext);
 
         Assert.assertEquals(paymentInfoPlugin.getAmount(), amount);
         Assert.assertEquals(Seconds.secondsBetween(paymentInfoPlugin.getCreatedDate(), clock.getUTCNow()).getSeconds(), 0);
@@ -64,35 +64,35 @@ public class TestExternalPaymentProviderPlugin extends PaymentTestSuite {
         Assert.assertNull(paymentInfoPlugin.getGatewayErrorCode());
         Assert.assertEquals(paymentInfoPlugin.getStatus(), PaymentPluginStatus.PROCESSED);
 
-        final PaymentInfoPlugin retrievedPaymentInfoPlugin = plugin.getPaymentInfo(paymentId);
+        final PaymentInfoPlugin retrievedPaymentInfoPlugin = plugin.getPaymentInfo(paymentId, callContext);
         Assert.assertEquals(retrievedPaymentInfoPlugin, paymentInfoPlugin);
     }
 
     @Test(groups = "fast", expectedExceptions = PaymentPluginApiException.class)
     public void testRefundForNonExistingPayment() throws Exception {
-        plugin.processRefund(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE);
+        plugin.processRefund(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE, callContext);
     }
 
     @Test(groups = "fast", expectedExceptions = PaymentPluginApiException.class)
     public void testRefundTooLarge() throws Exception {
         final UUID paymentId = UUID.randomUUID();
-        plugin.processPayment(UUID.randomUUID().toString(), paymentId, BigDecimal.ZERO);
+        plugin.processPayment(UUID.randomUUID().toString(), paymentId, BigDecimal.ZERO, callContext);
 
-        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE);
+        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext);
     }
 
     @Test(groups = "fast")
     public void testRefundTooLargeMultipleTimes() throws Exception {
         final UUID paymentId = UUID.randomUUID();
-        plugin.processPayment(UUID.randomUUID().toString(), paymentId, BigDecimal.TEN);
+        plugin.processPayment(UUID.randomUUID().toString(), paymentId, BigDecimal.TEN, callContext);
 
         final Account account = Mockito.mock(Account.class);
         for (int i = 0; i < 10; i++) {
-            plugin.processRefund(account, paymentId, BigDecimal.ONE);
+            plugin.processRefund(account, paymentId, BigDecimal.ONE, callContext);
         }
 
         try {
-            plugin.processRefund(account, paymentId, BigDecimal.ONE);
+            plugin.processRefund(account, paymentId, BigDecimal.ONE, callContext);
             Assert.fail("Shouldn't have been able to refund");
         } catch (PaymentPluginApiException e) {
             Assert.assertTrue(true);
@@ -105,32 +105,32 @@ public class TestExternalPaymentProviderPlugin extends PaymentTestSuite {
         final String externalKey = UUID.randomUUID().toString();
         final UUID paymentId = UUID.randomUUID();
         final BigDecimal amount = BigDecimal.TEN;
-        plugin.processPayment(externalKey, paymentId, amount);
+        plugin.processPayment(externalKey, paymentId, amount, callContext);
 
-        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE), 1);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5")), 0);
+        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext), 1);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5"), callContext), 0);
 
         // Try multiple refunds
 
-        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE), 2);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5")), 0);
-
-        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE), 3);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5")), 0);
-
-        plugin.processRefund(Mockito.mock(Account.class), paymentId, new BigDecimal("5"));
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN), 0);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE), 3);
-        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5")), 1);
+        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext), 2);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5"), callContext), 0);
+
+        plugin.processRefund(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext), 3);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5"), callContext), 0);
+
+        plugin.processRefund(Mockito.mock(Account.class), paymentId, new BigDecimal("5"), callContext);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), UUID.randomUUID(), BigDecimal.ONE, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.TEN, callContext), 0);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, BigDecimal.ONE, callContext), 3);
+        Assert.assertEquals(plugin.getNbRefundForPaymentAmount(Mockito.mock(Account.class), paymentId, new BigDecimal("5"), callContext), 1);
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index 568e45d..a57697f 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -21,7 +21,6 @@ import java.util.UUID;
 import org.joda.time.LocalDate;
 import org.mockito.Mockito;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.api.Currency;
@@ -40,9 +39,12 @@ import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class TestHelper {
     protected final AccountUserApi accountUserApi;
     protected final InvoicePaymentApi invoicePaymentApi;
@@ -59,12 +61,13 @@ public class TestHelper {
         this.invoicePaymentApi = invoicePaymentApi;
         this.paymentApi = paymentApi;
         this.clock = clock;
-        context = factory.createCallContext("Princess Buttercup", CallOrigin.TEST, UserType.TEST);
+        context = factory.createCallContext(null, "Princess Buttercup", CallOrigin.TEST, UserType.TEST);
     }
 
     public Invoice createTestInvoice(final Account account,
                                      final LocalDate targetDate,
                                      final Currency currency,
+                                     final CallContext context,
                                      final InvoiceItem... items) throws EventBusException, InvoiceApiException {
         final Invoice invoice = new MockInvoice(account.getId(), clock.getUTCToday(), targetDate, currency);
 
@@ -85,7 +88,7 @@ public class TestHelper {
             }
         }
 
-        Mockito.when(invoicePaymentApi.getInvoice(invoice.getId())).thenReturn(invoice);
+        Mockito.when(invoicePaymentApi.getInvoice(Mockito.eq(invoice.getId()), Mockito.<TenantContext>any())).thenReturn(invoice);
         final InvoiceCreationEvent event = new MockInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
                                                                         invoice.getBalance(), invoice.getCurrency(),
                                                                         invoice.getInvoiceDate(),
@@ -111,8 +114,8 @@ public class TestHelper {
         Mockito.when(account.isMigrated()).thenReturn(false);
         Mockito.when(account.isNotifiedForInvoices()).thenReturn(false);
 
-        Mockito.when(accountUserApi.getAccountById(Mockito.<UUID>any())).thenReturn(account);
-        Mockito.when(accountUserApi.getAccountByKey(Mockito.anyString())).thenReturn(account);
+        Mockito.when(accountUserApi.getAccountById(Mockito.<UUID>any(), Mockito.<TenantContext>any())).thenReturn(account);
+        Mockito.when(accountUserApi.getAccountByKey(Mockito.anyString(), Mockito.<TenantContext>any())).thenReturn(account);
 
         if (addPaymentMethod) {
             final PaymentMethodPlugin pm = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index 9deb279..a57a177 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -24,14 +24,12 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
-import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.config.PaymentConfig;
@@ -51,13 +49,11 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.payment.retry.FailedPaymentRetryService;
 import com.ning.billing.payment.retry.PluginFailureRetryService;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.CallContextModule;
 
+import com.google.inject.Inject;
+
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.testng.Assert.assertEquals;
@@ -87,7 +83,6 @@ public class TestRetryService extends PaymentTestSuite {
     private ClockMock clock;
 
     private MockPaymentProviderPlugin mockPaymentProviderPlugin;
-    private CallContext context;
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
@@ -100,8 +95,6 @@ public class TestRetryService extends PaymentTestSuite {
 
         mockPaymentProviderPlugin = (MockPaymentProviderPlugin) registry.getPlugin(null);
         mockPaymentProviderPlugin.clear();
-
-        context = new DefaultCallContext("RetryServiceTests", CallOrigin.INTERNAL, UserType.TEST, clock);
     }
 
     @AfterMethod(groups = "fast")
@@ -112,7 +105,7 @@ public class TestRetryService extends PaymentTestSuite {
     }
 
     private Payment getPaymentForInvoice(final UUID invoiceId) throws PaymentApiException {
-        final List<Payment> payments = paymentProcessor.getInvoicePayments(invoiceId);
+        final List<Payment> payments = paymentProcessor.getInvoicePayments(invoiceId, internalCallContext);
         assertEquals(payments.size(), 1);
         final Payment payment = payments.get(0);
         assertEquals(payment.getInvoiceId(), invoiceId);
@@ -152,7 +145,7 @@ public class TestRetryService extends PaymentTestSuite {
     private void testSchedulesRetryInternal(final int maxTries, final FailureType failureType) throws Exception {
 
         final Account account = testHelper.createTestAccount("yiyi.gmail.com", true);
-        final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCToday(), Currency.USD);
+        final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCToday(), Currency.USD, callContext);
         final BigDecimal amount = new BigDecimal("10.00");
         final UUID subscriptionId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
@@ -172,7 +165,7 @@ public class TestRetryService extends PaymentTestSuite {
         setPaymentFailure(failureType);
         boolean failed = false;
         try {
-            paymentProcessor.createPayment(account, invoice.getId(), amount, context, false, false);
+            paymentProcessor.createPayment(account, invoice.getId(), amount, internalCallContext, false, false);
         } catch (PaymentApiException e) {
             failed = true;
         }
@@ -197,7 +190,7 @@ public class TestRetryService extends PaymentTestSuite {
                     });
                 } catch (TimeoutException e) {
                     if (curFailure == maxTries - 1) {
-                        fail("Failed to find succesful payment for attempt " + (curFailure + 1) + "/" + maxTries);
+                        fail("Failed to find successful payment for attempt " + (curFailure + 1) + "/" + maxTries);
                     }
                 }
             }

pom.xml 21(+21 -0)

diff --git a/pom.xml b/pom.xml
index 9d36b5f..365c45d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,7 @@
         <module>util</module>
         <module>jaxrs</module>
         <module>server</module>
+        <module>tenant</module>
     </modules>
     <dependencyManagement>
         <dependencies>
@@ -61,6 +62,11 @@
                 <version>1.1.1</version>
             </dependency>
             <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>3.0.1</version>
+            </dependency>
+            <dependency>
                 <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-beatrix</artifactId>
                 <version>${project.version}</version>
@@ -101,6 +107,11 @@
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-tenant</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-account</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -282,6 +293,16 @@
                 <version>1.2</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-core</artifactId>
+                <version>1.2.1</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-web</artifactId>
+                <version>1.2.1</version>
+            </dependency>
+            <dependency>
                 <groupId>joda-time</groupId>
                 <artifactId>joda-time</artifactId>
                 <version>2.0</version>

README.md 61(+61 -0)

diff --git a/README.md b/README.md
index 314b6f4..63294ff 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,63 @@
 Killbill is an open source subscription management/billing system.
 You can find the documentation [here](http://ning.github.com/killbill/).
+
+Setting up your own tenant
+--------------------------
+
+Killbill supports multiple tenants running on the same server. Each tenant needs to identify itself when using the /1.0
+API via HTTP Basic authentication.
+
+For example, trying to access all tag definitions without being authenticated would throw a 400 error:
+
+    ~> curl -v http://127.0.0.1:8080/1.0/kb/tagDefinitions
+    * About to connect() to 127.0.0.1 port 8080 (#0)
+    *   Trying 127.0.0.1... connected
+    * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
+    > GET /1.0/kb/tagDefinitions HTTP/1.1
+    > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
+    > Host: 127.0.0.1:8080
+    > Accept: */*
+    >
+    < HTTP/1.1 401 Unauthorized
+    < WWW-Authenticate: BASIC realm="application"
+    < Content-Length: 0
+    < Server: Jetty(8.1.2.v20120308)
+    <
+    * Connection #0 to host 127.0.0.1 left intact
+    * Closing connection #0
+
+
+Before you can use the /1.0 API, you need to create your own tenant. To do so, post your username (`apiKey`) and password
+(`apiSecret`) to the `/1.0/kb/tenants` endpoint (the header `X-Killbill-CreatedBy` is used for auditing purposes).
+For example, to create the a tenant with the credentials bob/lazar:
+
+    ~> curl -v -XPOST \
+               -H'Content-Type: application/json' \
+               -H'X-Killbill-CreatedBy: admin' \
+               -d'{"apiKey": "bob", "apiSecret": "lazar"}' \
+               http://127.0.0.1:8080/1.0/kb/tenants
+    * About to connect() to 127.0.0.1 port 8080 (#0)
+    *   Trying 127.0.0.1... connected
+    * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
+    > POST /1.0/kb/tenants HTTP/1.1
+    > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
+    > Host: 127.0.0.1:8080
+    > Accept: */*
+    > Content-Type: application/json
+    > X-Killbill-CreatedBy: admin
+    > Content-Length: 39
+    >
+    < HTTP/1.1 201 Created
+    < Location: http://127.0.0.1:8080/1.0/kb/tenants/f07bc7d5-00e8-48bd-8b43-ef8537219171
+    < Content-Type: application/json
+    < Transfer-Encoding: chunked
+    < Server: Jetty(8.1.2.v20120308)
+    <
+    * Connection #0 to host 127.0.0.1 left intact
+    * Closing connection #0
+    {"uri":"/1.0/kb/tenants/f07bc7d5-00e8-48bd-8b43-ef8537219171"}
+
+
+You can now access the API using basic auth, e.g.:
+
+    ~> curl -v http://127.0.0.1:8080/1.0/kb/tagDefinitions -ubob:lazar

server/pom.xml 14(+13 -1)

diff --git a/server/pom.xml b/server/pom.xml
index 3c57dd3..8944d04 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -110,7 +110,6 @@
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
-            <version>3.0.1</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -196,6 +195,10 @@
             <artifactId>killbill-overdue</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-tenant</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <version>11.0.2</version>
@@ -234,6 +237,10 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.ning</groupId>
             <artifactId>async-http-client</artifactId>
             <version>${async-http-client.version}</version>
@@ -272,6 +279,11 @@
             <artifactId>mysql-connector-mxj-db-files</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <resources>
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index e20dc8e..c230b33 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -13,43 +13,44 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.server.listeners;
 
+package com.ning.billing.server.listeners;
 
 import javax.servlet.ServletContextEvent;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Injector;
-import com.google.inject.Module;
 import com.ning.billing.beatrix.lifecycle.DefaultLifecycle;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.server.config.KillbillServerConfig;
 import com.ning.billing.server.healthchecks.KillbillHealthcheck;
 import com.ning.billing.server.modules.KillbillServerModule;
+import com.ning.billing.server.security.TenantFilter;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusService;
 import com.ning.jetty.base.modules.ServerModuleBuilder;
 import com.ning.jetty.core.listeners.SetupServer;
 
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
 public class KillbillGuiceListener extends SetupServer {
+
     public static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
+    public static final String KILLBILL_MULTITENANT_PROPERTY = "killbill.server.multitenant";
 
     private DefaultLifecycle killbillLifecycle;
     private BusService killbillBusService;
     private KillbillEventHandler killbilleventHandler;
 
-
     protected Module getModule() {
         return new KillbillServerModule();
     }
 
-    
-   
     @Override
     public void contextInitialized(final ServletContextEvent event) {
-
+        final boolean multitenant = Boolean.parseBoolean(System.getProperty(KILLBILL_MULTITENANT_PROPERTY, "false"));
 
         final ServerModuleBuilder builder = new ServerModuleBuilder()
                 .addConfig(KillbillServerConfig.class)
@@ -59,6 +60,9 @@ public class KillbillGuiceListener extends SetupServer {
                 .addJerseyResource("com.ning.billing.jaxrs.mappers")
                 .addJerseyResource("com.ning.billing.jaxrs.resources");
 
+        if (multitenant) {
+            builder.addFilter("/*", TenantFilter.class);
+        }
 
         guiceModule = builder.build();
 
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index 16ab8a6..7a60582 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -36,10 +36,12 @@ import com.ning.billing.jaxrs.resources.PaymentResource;
 import com.ning.billing.jaxrs.resources.RefundResource;
 import com.ning.billing.jaxrs.resources.SubscriptionResource;
 import com.ning.billing.jaxrs.resources.TagResource;
+import com.ning.billing.jaxrs.resources.TenantResource;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.junction.glue.DefaultJunctionModule;
 import com.ning.billing.overdue.glue.DefaultOverdueModule;
 import com.ning.billing.payment.glue.PaymentModule;
+import com.ning.billing.tenant.glue.TenantModule;
 import com.ning.billing.util.email.EmailModule;
 import com.ning.billing.util.email.templates.TemplateModule;
 import com.ning.billing.util.glue.AuditModule;
@@ -81,6 +83,7 @@ public class KillbillServerModule extends AbstractModule {
         bind(PaymentMethodResource.class).asEagerSingleton();
         bind(PaymentResource.class).asEagerSingleton();
         bind(RefundResource.class).asEagerSingleton();
+        bind(TenantResource.class).asEagerSingleton();
         bind(KillbillEventHandler.class).asEagerSingleton();
     }
 
@@ -107,6 +110,7 @@ public class KillbillServerModule extends AbstractModule {
         install(new BeatrixModule());
         install(new DefaultJunctionModule());
         install(new DefaultOverdueModule());
+        install(new TenantModule());
         installClock();
     }
 }
diff --git a/server/src/main/java/com/ning/billing/server/security/KillbillJdbcRealm.java b/server/src/main/java/com/ning/billing/server/security/KillbillJdbcRealm.java
new file mode 100644
index 0000000..9e713f8
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/security/KillbillJdbcRealm.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.server.security;
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.codec.Base64;
+import org.apache.shiro.realm.jdbc.JdbcRealm;
+import org.apache.shiro.util.ByteSource;
+import org.skife.config.ConfigurationObjectFactory;
+
+import com.ning.billing.tenant.security.KillbillCredentialsMatcher;
+import com.ning.jetty.jdbi.config.DaoConfig;
+
+import com.jolbox.bonecp.BoneCPConfig;
+import com.jolbox.bonecp.BoneCPDataSource;
+
+/**
+ * @see {shiro.ini}
+ */
+public class KillbillJdbcRealm extends JdbcRealm {
+
+    private static final String KILLBILL_AUTHENTICATION_QUERY = "select api_secret, api_salt from tenants where api_key = ?";
+
+    public KillbillJdbcRealm() {
+        super();
+        configureSecurity();
+        configureQueries();
+        configureDataSource();
+    }
+
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) throws AuthenticationException {
+        final SimpleAuthenticationInfo authenticationInfo = (SimpleAuthenticationInfo) super.doGetAuthenticationInfo(token);
+
+        // We store the salt bytes in Base64 (because the JdbcRealm retrieves it as a String)
+        final ByteSource base64Salt = authenticationInfo.getCredentialsSalt();
+        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(Base64.decode(base64Salt.getBytes())));
+
+        return authenticationInfo;
+    }
+
+    private void configureSecurity() {
+        setSaltStyle(SaltStyle.COLUMN);
+        setCredentialsMatcher(KillbillCredentialsMatcher.getCredentialsMatcher());
+    }
+
+    private void configureQueries() {
+        setAuthenticationQuery(KILLBILL_AUTHENTICATION_QUERY);
+    }
+
+    private void configureDataSource() {
+        // This class is initialized by Shiro, not Guice - we need to retrieve the config manually
+        final DaoConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DaoConfig.class);
+
+        final BoneCPConfig dbConfig = new BoneCPConfig();
+        dbConfig.setJdbcUrl(config.getJdbcUrl());
+        dbConfig.setUsername(config.getUsername());
+        dbConfig.setPassword(config.getPassword());
+        dbConfig.setMinConnectionsPerPartition(config.getMinIdle());
+        dbConfig.setMaxConnectionsPerPartition(config.getMaxActive());
+        dbConfig.setConnectionTimeout(config.getConnectionTimeout().getPeriod(), config.getConnectionTimeout().getUnit());
+        dbConfig.setIdleMaxAge(config.getIdleMaxAge().getPeriod(), config.getIdleMaxAge().getUnit());
+        dbConfig.setMaxConnectionAge(config.getMaxConnectionAge().getPeriod(), config.getMaxConnectionAge().getUnit());
+        dbConfig.setIdleConnectionTestPeriod(config.getIdleConnectionTestPeriod().getPeriod(), config.getIdleConnectionTestPeriod().getUnit());
+        dbConfig.setPartitionCount(1);
+        dbConfig.setDefaultTransactionIsolation("READ_COMMITTED");
+        dbConfig.setDisableJMX(false);
+
+        setDataSource(new BoneCPDataSource(dbConfig));
+    }
+}
diff --git a/server/src/main/java/com/ning/billing/server/security/TenantFilter.java b/server/src/main/java/com/ning/billing/server/security/TenantFilter.java
new file mode 100644
index 0000000..b24e2b5
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/security/TenantFilter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.server.security;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.tenant.api.TenantApiException;
+import com.ning.billing.tenant.api.TenantUserApi;
+
+@Singleton
+public class TenantFilter implements Filter {
+
+    public static final String SUBJECT = "killbill_subject";
+    public static final String TENANT = "killbill_tenant";
+
+    private static final Logger log = LoggerFactory.getLogger(TenantFilter.class);
+
+    @Inject
+    private TenantUserApi tenantUserApi;
+
+    @Override
+    public void init(final FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+        final Subject subject = SecurityUtils.getSubject();
+        request.setAttribute(SUBJECT, subject);
+
+        final String apiKey = (String) subject.getPrincipal();
+        if (apiKey == null) {
+            // Resource not protected by Shiro?
+            chain.doFilter(request, response);
+            return;
+        }
+
+        try {
+            final Tenant tenant = tenantUserApi.getTenantByApiKey(apiKey);
+            request.setAttribute(TENANT, tenant);
+
+            chain.doFilter(request, response);
+        } catch (TenantApiException e) {
+            // Should never happen since Shiro validated the credentials?
+            log.warn("Couldn't find the tenant?", e);
+        }
+    }
+
+    @Override
+    public void destroy() {
+    }
+}
diff --git a/server/src/main/webapp/WEB-INF/shiro.ini b/server/src/main/webapp/WEB-INF/shiro.ini
new file mode 100644
index 0000000..21defe1
--- /dev/null
+++ b/server/src/main/webapp/WEB-INF/shiro.ini
@@ -0,0 +1,36 @@
+###################################################################################
+#                                                                                 #
+#                   Copyright 2010-2012 Ning, Inc.                                #
+#                                                                                 #
+#      Ning licenses this file to you under the Apache License, version 2.0       #
+#      (the "License"); you may not use this file except in compliance with the   #
+#      License.  You may obtain a copy of the License at:                         #
+#                                                                                 #
+#          http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                                 #
+#      Unless required by applicable law or agreed to in writing, software        #
+#      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+#      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the  #
+#      License for the specific language governing permissions and limitations    #
+#      under the License.                                                         #
+#                                                                                 #
+###################################################################################
+
+[main]
+# Bypass the servlet container completely for session management and delegate
+# it to Shiro (to be portable across servlet containers)
+# The default session timeout is 30 minutes.
+sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
+# Use the configured native session manager
+securityManager.sessionManager = $sessionManager
+
+jdbcRealm=com.ning.billing.server.security.KillbillJdbcRealm
+
+[urls]
+# Special endpoints: healthcheck, tenant API.
+# TODO: don't secure them for now - eventually require admin privileges
+/1.0/healthcheck = anon
+/1.0/kb/tenants/** = anon
+# For all other resources, require basic auth
+# TODO: ssl, authcBasic
+/1.0/kb/** = authcBasic
diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml
index 9891d30..23a2813 100644
--- a/server/src/main/webapp/WEB-INF/web.xml
+++ b/server/src/main/webapp/WEB-INF/web.xml
@@ -6,6 +6,25 @@
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
     <display-name>irs</display-name>
+    <listener>
+        <!-- Initialize Shiro WebEnvironment and put it into the ServletContext -->
+        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
+    </listener>
+    <filter>
+        <!-- Filter all requests through Shiro -->
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <!-- The Shitor filter-mapping should come first -->
+        <filter-name>ShiroFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+        <dispatcher>FORWARD</dispatcher>
+        <dispatcher>INCLUDE</dispatcher>
+        <dispatcher>ERROR</dispatcher>
+    </filter-mapping>
+
     <filter>
         <!-- Guice emulates Servlet API with DI -->
         <filter-name>guiceFilter</filter-name>
@@ -23,6 +42,7 @@
         <!-- Context listener: called at startup time and creates the injector -->
         <listener-class>com.ning.billing.server.listeners.KillbillGuiceListener</listener-class>
     </listener>
+
     <!-- ServletHandler#handle requires a backend servlet, it won't be used though (handled by Guice) -->
     <servlet>
         <servlet-name>log-invalid-resources</servlet-name>
diff --git a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
new file mode 100644
index 0000000..53bb288
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+import javax.ws.rs.core.Response.Status;
+
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.jaxrs.json.AccountEmailJson;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.AccountTimelineJson;
+import com.ning.billing.jaxrs.json.BillCycleDayJson;
+import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
+import com.ning.billing.jaxrs.json.ChargebackJson;
+import com.ning.billing.jaxrs.json.CreditJson;
+import com.ning.billing.jaxrs.json.InvoiceItemJsonSimple;
+import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.InvoiceJsonWithItems;
+import com.ning.billing.jaxrs.json.OverdueStateJson;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonWithBundleKeys;
+import com.ning.billing.jaxrs.json.PaymentMethodJson;
+import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
+import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
+import com.ning.billing.jaxrs.json.RefundJson;
+import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.json.TenantJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.server.ServerTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.api.AuditLevel;
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.http.client.AsyncCompletionHandler;
+import com.ning.http.client.AsyncHttpClient;
+import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
+import com.ning.http.client.ListenableFuture;
+import com.ning.http.client.Response;
+import com.ning.jetty.core.CoreConfig;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap;
+
+import static com.ning.billing.jaxrs.resources.JaxrsResource.ACCOUNTS;
+import static com.ning.billing.jaxrs.resources.JaxrsResource.BUNDLES;
+import static com.ning.billing.jaxrs.resources.JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_INFO;
+import static com.ning.billing.jaxrs.resources.JaxrsResource.SUBSCRIPTIONS;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public abstract class KillbillClient extends ServerTestSuiteWithEmbeddedDB {
+
+    protected static final String PLUGIN_NAME = "noop";
+
+    // STEPH
+    protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 6000; // 5;
+
+    protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
+
+    private static final Logger log = LoggerFactory.getLogger(TestJaxrsBase.class);
+
+    public static final String HEADER_CONTENT_TYPE = "Content-type";
+    public static final String CONTENT_TYPE = "application/json";
+
+    protected static final String DEFAULT_CURRENCY = "USD";
+
+    protected CoreConfig config;
+    protected AsyncHttpClient httpClient;
+    protected ObjectMapper mapper;
+    protected ClockMock clock;
+
+    // Context information to be passed around
+    protected static final String createdBy = "Toto";
+    protected static final String reason = "i am god";
+    protected static final String comment = "no comment";
+
+    protected List<PaymentMethodProperties> getPaymentMethodCCProperties() {
+        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodProperties>();
+        properties.add(new PaymentMethodProperties("type", "CreditCard", false));
+        properties.add(new PaymentMethodProperties("cardType", "Visa", false));
+        properties.add(new PaymentMethodProperties("cardHolderName", "Mr Sniff", false));
+        properties.add(new PaymentMethodProperties("expirationDate", "2015-08", false));
+        properties.add(new PaymentMethodProperties("maskNumber", "3451", false));
+        properties.add(new PaymentMethodProperties("address1", "23, rue des cerisiers", false));
+        properties.add(new PaymentMethodProperties("address2", "", false));
+        properties.add(new PaymentMethodProperties("city", "Toulouse", false));
+        properties.add(new PaymentMethodProperties("country", "France", false));
+        properties.add(new PaymentMethodProperties("postalCode", "31320", false));
+        properties.add(new PaymentMethodProperties("state", "Midi-Pyrenees", false));
+        return properties;
+    }
+
+    protected List<PaymentMethodProperties> getPaymentMethodPaypalProperties() {
+        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
+        properties.add(new PaymentMethodProperties("type", "CreditCard", false));
+        properties.add(new PaymentMethodProperties("email", "zouzou@laposte.fr", false));
+        properties.add(new PaymentMethodProperties("baid", "23-8787d-R", false));
+        return properties;
+    }
+
+    protected PaymentMethodJson getPaymentMethodJson(final String accountId, final List<PaymentMethodProperties> properties) {
+        final PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, properties);
+        return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
+    }
+
+    //
+    // TENANT UTILITIES
+    //
+
+    protected void createTenant(final String apiKey, final String apiSecret) throws Exception {
+        final String baseJson = mapper.writeValueAsString(new TenantJson(null, null, apiKey, apiSecret));
+        final Response response = doPost(JaxrsResource.TENANTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+    }
+
+    //
+    // ACCOUNT UTILITIES
+    //
+
+    protected AccountJson getAccountByExternalKey(final String externalKey) throws Exception {
+        final Response response = getAccountByExternalKeyNoValidation(externalKey);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        final String baseJson = response.getResponseBody();
+        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertNotNull(objFromJson);
+
+        return objFromJson;
+    }
+
+    protected Response getAccountByExternalKeyNoValidation(final String externalKey) {
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, externalKey);
+        return doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+    }
+
+    protected AccountTimelineJson getAccountTimeline(final String accountId) throws Exception {
+        return doGetAccountTimeline(accountId, AuditLevel.NONE);
+    }
+
+    protected AccountTimelineJson getAccountTimelineWithAudits(final String accountId, final AuditLevel auditLevel) throws Exception {
+        return doGetAccountTimeline(accountId, auditLevel);
+    }
+
+    private AccountTimelineJson doGetAccountTimeline(final String accountId, final AuditLevel auditLevel) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TIMELINE;
+
+        final Response response = doGet(uri, ImmutableMap.<String, String>of(JaxrsResource.QUERY_AUDIT, auditLevel.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        final String baseJson = response.getResponseBody();
+        final AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
+        assertNotNull(objFromJson);
+
+        return objFromJson;
+    }
+
+    protected AccountJson createAccountWithDefaultPaymentMethod() throws Exception {
+        final AccountJson input = createAccount();
+        return doCreateAccountWithDefaultPaymentMethod(input);
+    }
+
+    protected AccountJson createAccountWithDefaultPaymentMethod(final String name, final String key, final String email) throws Exception {
+        final AccountJson input = createAccount(name, key, email);
+        return doCreateAccountWithDefaultPaymentMethod(input);
+    }
+
+    protected AccountJson doCreateAccountWithDefaultPaymentMethod(final AccountJson input) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
+        final PaymentMethodJson paymentMethodJson = getPaymentMethodJson(input.getAccountId(), null);
+        String baseJson = mapper.writeValueAsString(paymentMethodJson);
+        Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
+
+        Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, input.getExternalKey());
+        response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        baseJson = response.getResponseBody();
+        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertNotNull(objFromJson);
+        Assert.assertNotNull(objFromJson.getPaymentMethodId());
+        return objFromJson;
+    }
+
+    protected AccountJson createAccount() throws Exception {
+        return createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
+    }
+
+    protected AccountJson createAccount(final String name, final String key, final String email) throws Exception {
+        Response response = createAccountNoValidation(name, key, email);
+        final String baseJson;
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+
+        // Retrieves by Id based on Location returned
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        baseJson = response.getResponseBody();
+        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertNotNull(objFromJson);
+        return objFromJson;
+    }
+
+    protected Response createAccountNoValidation() throws IOException {
+        return createAccountNoValidation(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
+    }
+
+    protected Response createAccountNoValidation(final String name, final String key, final String email) throws IOException {
+        final AccountJson input = getAccountJson(name, key, email);
+        final String baseJson = mapper.writeValueAsString(input);
+        return doPost(JaxrsResource.ACCOUNTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+    }
+
+    protected AccountJson updateAccount(final String accountId, final AccountJson newInput) throws Exception {
+        final String baseJson = mapper.writeValueAsString(newInput);
+
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId;
+        final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        final String retrievedJson = response.getResponseBody();
+        final AccountJson objFromJson = mapper.readValue(retrievedJson, AccountJson.class);
+        assertNotNull(objFromJson);
+
+        return objFromJson;
+    }
+
+    protected List<AccountEmailJson> getEmailsForAccount(final String accountId) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        return mapper.readValue(response.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+    }
+
+    protected void addEmailToAccount(final String accountId, final AccountEmailJson email) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final String emailString = mapper.writeValueAsString(email);
+        final Response response = doPost(uri, emailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+    }
+
+    protected void removeEmailFromAccount(final String accountId, final String email) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final Response fifthResponse = doDelete(uri + "/" + email, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+    }
+
+    protected BundleJsonNoSubscriptions createBundle(final String accountId, final String key) throws Exception {
+        final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, null, null);
+        String baseJson = mapper.writeValueAsString(input);
+        Response response = doPost(JaxrsResource.BUNDLES_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+
+        // Retrieves by Id based on Location returned
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        baseJson = response.getResponseBody();
+        final BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
+        Assert.assertTrue(objFromJson.equalsNoId(input));
+        return objFromJson;
+    }
+
+    protected SubscriptionJsonNoEvents createSubscription(final String bundleId, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
+
+        final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory,
+                                                                            billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME,
+                                                                            null, null, null);
+        String baseJson = mapper.writeValueAsString(input);
+
+        final Map<String, String> queryParams = waitCompletion ? getQueryParamsForCallCompletion("5") : DEFAULT_EMPTY_QUERY;
+        Response response = doPost(JaxrsResource.SUBSCRIPTIONS_PATH, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+
+        // Retrieves by Id based on Location returned
+
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        baseJson = response.getResponseBody();
+        final SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
+        Assert.assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(input));
+        return objFromJson;
+    }
+
+    //
+    // INVOICE UTILITIES
+    //
+
+    protected AccountJson createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod();
+        assertNotNull(accountJson);
+
+        // Add a bundle, subscription and move the clock to get the first invoice
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
+        assertNotNull(bundleJson);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+        clock.addDays(32);
+        crappyWaitForLackOfProperSynchonization();
+
+        return accountJson;
+    }
+
+    protected AccountJson createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+        // Create an account with no payment method
+        final AccountJson accountJson = createAccount();
+        assertNotNull(accountJson);
+
+        // Add a bundle, subscription and move the clock to get the first invoice
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
+        assertNotNull(bundleJson);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+        clock.addMonths(1);
+        crappyWaitForLackOfProperSynchonization();
+
+        // No payment will be triggered as the account doesn't have a payment method
+
+        return accountJson;
+    }
+
+    protected InvoiceJsonSimple getInvoice(final String invoiceId) throws IOException {
+        return doGetInvoice(invoiceId, Boolean.FALSE, InvoiceJsonSimple.class);
+    }
+
+    protected InvoiceJsonWithItems getInvoiceWithItems(final String invoiceId) throws IOException {
+        return doGetInvoice(invoiceId, Boolean.TRUE, InvoiceJsonWithItems.class);
+    }
+
+    private <T> T doGetInvoice(final String invoiceId, final Boolean withItems, final Class<T> clazz) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
+
+        final Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+
+        final T firstInvoiceJson = mapper.readValue(baseJson, clazz);
+        assertNotNull(firstInvoiceJson);
+
+        return firstInvoiceJson;
+    }
+
+    protected List<InvoiceJsonSimple> getInvoicesForAccount(final String accountId) throws IOException {
+        return doGetInvoicesForAccount(accountId, Boolean.FALSE, new TypeReference<List<InvoiceJsonSimple>>() {});
+    }
+
+    protected List<InvoiceJsonWithItems> getInvoicesWithItemsForAccount(final String accountId) throws IOException {
+        return doGetInvoicesForAccount(accountId, Boolean.TRUE, new TypeReference<List<InvoiceJsonWithItems>>() {});
+    }
+
+    private <T> List<T> doGetInvoicesForAccount(final String accountId, final Boolean withItems, final TypeReference<List<T>> clazz) throws IOException {
+        final String invoicesURI = JaxrsResource.INVOICES_PATH;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
+
+        final Response invoicesResponse = doGet(invoicesURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(invoicesResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final String invoicesBaseJson = invoicesResponse.getResponseBody();
+        final List<T> invoices = mapper.readValue(invoicesBaseJson, clazz);
+        assertNotNull(invoices);
+
+        return invoices;
+    }
+
+    protected InvoiceJsonSimple createDryRunInvoice(final String accountId, final DateTime futureDate) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
+        queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
+
+        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        final String baseJson = response.getResponseBody();
+        final InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
+        assertNotNull(futureInvoice);
+
+        return futureInvoice;
+    }
+
+    protected void createInvoice(final String accountId, final DateTime futureDate) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
+
+        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+    }
+
+    protected void adjustInvoiceItem(final String accountId, final String invoiceId, final String invoiceItemId,
+                                     @Nullable final DateTime requestedDate, @Nullable final BigDecimal amount, @Nullable final Currency currency) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        if (requestedDate != null) {
+            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
+        }
+
+        final InvoiceItemJsonSimple adjustment = new InvoiceItemJsonSimple(invoiceItemId, null, null, accountId, null, null, null, null,
+                                                                           null, null, null, amount, currency, null);
+        final String adjustmentJson = mapper.writeValueAsString(adjustment);
+        final Response response = doPost(uri, adjustmentJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+    }
+
+    protected InvoiceJsonWithItems createExternalCharge(final String accountId, final BigDecimal amount, @Nullable final String bundleId,
+                                                        @Nullable final Currency currency, @Nullable final DateTime requestedDate) throws Exception {
+        return doCreateExternalCharge(accountId, null, bundleId, amount, currency, requestedDate, JaxrsResource.CHARGES_PATH);
+    }
+
+    protected InvoiceJsonWithItems createExternalChargeForInvoice(final String accountId, final String invoiceId, @Nullable final String bundleId, final BigDecimal amount,
+                                                                  @Nullable final Currency currency, @Nullable final DateTime requestedDate) throws Exception {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.CHARGES;
+        return doCreateExternalCharge(accountId, invoiceId, bundleId, amount, currency, requestedDate, uri);
+    }
+
+    private InvoiceJsonWithItems doCreateExternalCharge(final String accountId, @Nullable final String invoiceId, @Nullable final String bundleId, @Nullable final BigDecimal amount,
+                                                        @Nullable final Currency currency, final DateTime requestedDate, final String uri) throws IOException {
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        if (requestedDate != null) {
+            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
+        }
+
+        final InvoiceItemJsonSimple externalCharge = new InvoiceItemJsonSimple(null, invoiceId, null, accountId, bundleId, null, null, null,
+                                                                               null, null, null, amount, currency, null);
+        final String externalChargeJson = mapper.writeValueAsString(externalCharge);
+        final Response response = doPost(uri, externalChargeJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+
+        final Map<String, String> queryParamsForInvoice = new HashMap<String, String>();
+        queryParamsForInvoice.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParamsForInvoice.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, "true");
+        final Response invoiceResponse = doGetWithUrl(location, queryParamsForInvoice, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(invoiceResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final String invoicesBaseJson = invoiceResponse.getResponseBody();
+        final InvoiceJsonWithItems invoice = mapper.readValue(invoicesBaseJson, new TypeReference<InvoiceJsonWithItems>() {});
+        assertNotNull(invoice);
+
+        return invoice;
+    }
+
+    //
+    // PAYMENT UTILITIES
+    //
+
+    protected PaymentJsonSimple getPayment(final String paymentId) throws IOException {
+        return doGetPayment(paymentId, DEFAULT_EMPTY_QUERY, PaymentJsonSimple.class);
+    }
+
+    protected PaymentJsonWithBundleKeys getPaymentWithRefundsAndChargebacks(final String paymentId) throws IOException {
+        return doGetPayment(paymentId, ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_WITH_REFUNDS_AND_CHARGEBACKS, "true"), PaymentJsonWithBundleKeys.class);
+    }
+
+    protected <T extends PaymentJsonSimple> T doGetPayment(final String paymentId, final Map<String, String> queryParams, final Class<T> clazz) throws IOException {
+        final String paymentURI = JaxrsResource.PAYMENTS_PATH + "/" + paymentId;
+
+        final Response paymentResponse = doGet(paymentURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final T paymentJsonSimple = mapper.readValue(paymentResponse.getResponseBody(), clazz);
+        assertNotNull(paymentJsonSimple);
+
+        return paymentJsonSimple;
+    }
+
+    protected PaymentMethodJson getPaymentMethod(final String paymentMethodId) throws IOException {
+        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
+        final Response paymentMethodResponse = doGet(paymentMethodURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
+        assertNotNull(paymentMethodJson);
+
+        return paymentMethodJson;
+    }
+
+    protected PaymentMethodJson getPaymentMethodWithPluginInfo(final String paymentMethodId) throws IOException {
+        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
+
+        final Map<String, String> queryPaymentMethods = new HashMap<String, String>();
+        queryPaymentMethods.put(QUERY_PAYMENT_METHOD_PLUGIN_INFO, "true");
+        final Response paymentMethodResponse = doGet(paymentMethodURI, queryPaymentMethods, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
+        assertNotNull(paymentMethodJson);
+
+        return paymentMethodJson;
+    }
+
+    protected List<PaymentJsonSimple> getPaymentsForAccount(final String accountId) throws IOException {
+        final String paymentsURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.PAYMENTS;
+        final Response paymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentsResponse.getStatusCode(), Status.OK.getStatusCode());
+        final String paymentsBaseJson = paymentsResponse.getResponseBody();
+
+        final List<PaymentJsonSimple> paymentJsonSimples = mapper.readValue(paymentsBaseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        assertNotNull(paymentJsonSimples);
+
+        return paymentJsonSimples;
+    }
+
+    protected List<PaymentJsonSimple> getPaymentsForInvoice(final String invoiceId) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        assertNotNull(objFromJson);
+
+        return objFromJson;
+    }
+
+    protected void payAllInvoices(final AccountJson accountJson, final Boolean externalPayment) throws IOException {
+        final PaymentJsonSimple payment = new PaymentJsonSimple(null, null, accountJson.getAccountId(), null, null, null, null,
+                                                                null, 0, null, null, null, null, null, null, null);
+        final String postJson = mapper.writeValueAsString(payment);
+
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + JaxrsResource.PAYMENTS;
+        doPost(uri, postJson, ImmutableMap.<String, String>of("externalPayment", externalPayment.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
+    }
+
+    protected List<PaymentJsonSimple> createInstaPayment(final AccountJson accountJson, final InvoiceJsonSimple invoice) throws IOException {
+        final PaymentJsonSimple payment = new PaymentJsonSimple(invoice.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
+                                                                invoice.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null, null);
+        final String postJson = mapper.writeValueAsString(payment);
+
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
+        doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        return getPaymentsForInvoice(invoice.getInvoiceId());
+    }
+
+    protected List<PaymentJsonSimple> createExternalPayment(final AccountJson accountJson, final String invoiceId, final BigDecimal paidAmount) throws IOException {
+        final PaymentJsonSimple payment = new PaymentJsonSimple(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
+                                                                invoiceId, null, null, null, null, 0,
+                                                                null, null, null, null, null, null, null);
+        final String postJson = mapper.writeValueAsString(payment);
+
+        final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
+        final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentResponse.getStatusCode(), Status.CREATED.getStatusCode());
+
+        return getPaymentsForInvoice(invoiceId);
+    }
+
+    //
+    // CHARGEBACKS
+    //
+
+    protected ChargebackJson createChargeBack(final String paymentId, final BigDecimal chargebackAmount) throws IOException {
+        final ChargebackJson input = new ChargebackJson(null, null, chargebackAmount, paymentId, null, null);
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Create the chargeback
+        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
+
+        // Find the chargeback by location
+        final String location = response.getHeader("Location");
+        assertNotNull(location);
+        final Response responseByLocation = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(responseByLocation.getStatusCode(), Status.OK.getStatusCode());
+
+        return mapper.readValue(responseByLocation.getResponseBody(), ChargebackJson.class);
+    }
+
+    //
+    // REFUNDS
+    //
+
+    protected List<RefundJson> getRefundsForAccount(final String accountId) throws IOException {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.REFUNDS;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
+        assertNotNull(refunds);
+
+        return refunds;
+    }
+
+    protected List<RefundJson> getRefundsForPayment(final String paymentId) throws IOException {
+        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
+        assertNotNull(refunds);
+
+        return refunds;
+    }
+
+    protected RefundJson createRefund(final String paymentId, final BigDecimal amount) throws IOException {
+        return doCreateRefund(paymentId, amount, false, ImmutableMap.<String, BigDecimal>of());
+    }
+
+    protected RefundJson createRefundWithInvoiceAdjustment(final String paymentId, final BigDecimal amount) throws IOException {
+        return doCreateRefund(paymentId, amount, true, ImmutableMap.<String, BigDecimal>of());
+    }
+
+    protected RefundJson createRefundWithInvoiceItemAdjustment(final String paymentId, final String invoiceItemId, final BigDecimal amount) throws IOException {
+        final Map<String, BigDecimal> adjustments = new HashMap<String, BigDecimal>();
+        adjustments.put(invoiceItemId, amount);
+        return doCreateRefund(paymentId, amount, true, adjustments);
+    }
+
+    private RefundJson doCreateRefund(final String paymentId, final BigDecimal amount, final boolean adjusted, final Map<String, BigDecimal> itemAdjustments) throws IOException {
+        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
+
+        final List<InvoiceItemJsonSimple> adjustments = new ArrayList<InvoiceItemJsonSimple>();
+        for (final String itemId : itemAdjustments.keySet()) {
+            adjustments.add(new InvoiceItemJsonSimple(itemId, null, null, null, null, null, null, null, null, null, null,
+                                                      itemAdjustments.get(itemId), null, null));
+        }
+        final RefundJson refundJson = new RefundJson(null, paymentId, amount, DEFAULT_CURRENCY, adjusted, null, null, adjustments, null);
+        final String baseJson = mapper.writeValueAsString(refundJson);
+        final Response response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String locationCC = response.getHeader("Location");
+        Assert.assertNotNull(locationCC);
+
+        // Retrieves by Id based on Location returned
+        final Response retrievedResponse = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(retrievedResponse.getStatusCode(), Status.OK.getStatusCode());
+        final String retrievedBaseJson = retrievedResponse.getResponseBody();
+        final RefundJson retrievedRefundJson = mapper.readValue(retrievedBaseJson, RefundJson.class);
+        assertNotNull(retrievedRefundJson);
+        // Verify we have the adjusted items
+        if (retrievedRefundJson.getAdjustments() != null) {
+            final Set<String> allLinkedItemIds = new HashSet<String>(Collections2.transform(retrievedRefundJson.getAdjustments(), new Function<InvoiceItemJsonSimple, String>() {
+                @Override
+                public String apply(@Nullable final InvoiceItemJsonSimple input) {
+                    if (input != null) {
+                        return input.getLinkedInvoiceItemId();
+                    } else {
+                        return null;
+                    }
+                }
+            }));
+            assertEquals(allLinkedItemIds, itemAdjustments.keySet());
+        }
+
+        return retrievedRefundJson;
+    }
+
+    protected Map<String, String> getQueryParamsForCallCompletion(final String timeoutSec) {
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_CALL_COMPLETION, "true");
+        queryParams.put(JaxrsResource.QUERY_CALL_TIMEOUT, timeoutSec);
+        return queryParams;
+    }
+
+    //
+    // CREDITS
+    //
+
+    protected CreditJson createCreditForAccount(final String accountId, final BigDecimal creditAmount,
+                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
+        return createCreditForInvoice(accountId, null, creditAmount, requestedDate, effectiveDate);
+    }
+
+    protected CreditJson createCreditForInvoice(final String accountId, final String invoiceId, final BigDecimal creditAmount,
+                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
+        final CreditJson input = new CreditJson(creditAmount, invoiceId, UUID.randomUUID().toString(),
+                                                requestedDate, effectiveDate,
+                                                UUID.randomUUID().toString(), accountId,
+                                                null);
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Create the credit
+        Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
+
+        final String location = response.getHeader("Location");
+        assertNotNull(location);
+
+        // Retrieves by Id based on Location returned
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        return mapper.readValue(response.getResponseBody(), CreditJson.class);
+    }
+
+    //
+    // OVERDUE
+    //
+
+    protected OverdueStateJson getOverdueStateForAccount(final String accountId) throws Exception {
+        return doGetOverdueState(accountId, ACCOUNTS);
+    }
+
+    protected OverdueStateJson getOverdueStateForBundle(final String bundleId) throws Exception {
+        return doGetOverdueState(bundleId, BUNDLES);
+    }
+
+    protected OverdueStateJson getOverdueStateForSubscription(final String subscriptionId) throws Exception {
+        return doGetOverdueState(subscriptionId, SUBSCRIPTIONS);
+    }
+
+    protected OverdueStateJson doGetOverdueState(final String id, final String resourceType) throws Exception {
+        final String overdueURI = JaxrsResource.OVERDUE_PATH + "/" + resourceType + "/" + id;
+        final Response overdueResponse = doGet(overdueURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(overdueResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final OverdueStateJson overdueStateJson = mapper.readValue(overdueResponse.getResponseBody(), OverdueStateJson.class);
+        assertNotNull(overdueStateJson);
+
+        return overdueStateJson;
+    }
+
+    //
+    // HTTP CLIENT HELPERS
+    //
+    protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
+        if (body != null) {
+            builder.setBody(body);
+        } else {
+            builder.setBody("{}");
+        }
+        return executeAndWait(builder, timeoutSec, true);
+    }
+
+    protected Response doPut(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
+        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
+        if (body != null) {
+            builder.setBody(body);
+        } else {
+            builder.setBody("{}");
+        }
+        return executeAndWait(builder, timeoutSec, true);
+    }
+
+    protected Response doDelete(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
+        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
+        return executeAndWait(builder, timeoutSec, true);
+    }
+
+    protected Response doGet(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
+        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+        return doGetWithUrl(url, queryParams, timeoutSec);
+    }
+
+    protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
+        return executeAndWait(builder, timeoutSec, false);
+    }
+
+    private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
+
+        if (addContextHeader) {
+            builder.addHeader(JaxrsResource.HDR_CREATED_BY, createdBy);
+            builder.addHeader(JaxrsResource.HDR_REASON, reason);
+            builder.addHeader(JaxrsResource.HDR_COMMENT, comment);
+        }
+
+        Response response = null;
+        try {
+            final ListenableFuture<Response> futureStatus =
+                    builder.execute(new AsyncCompletionHandler<Response>() {
+                        @Override
+                        public Response onCompleted(final Response response) throws Exception {
+                            return response;
+                        }
+                    });
+            response = futureStatus.get(timeoutSec, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            Assert.fail(e.getMessage());
+        }
+        Assert.assertNotNull(response);
+        return response;
+    }
+
+    protected String getUrlFromUri(final String uri) {
+        return String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+    }
+
+    private BoundRequestBuilder getBuilderWithHeaderAndQuery(final String verb, final String url, final Map<String, String> queryParams) {
+        BoundRequestBuilder builder = null;
+        if (verb.equals("GET")) {
+            builder = httpClient.prepareGet(url);
+        } else if (verb.equals("POST")) {
+            builder = httpClient.preparePost(url);
+        } else if (verb.equals("PUT")) {
+            builder = httpClient.preparePut(url);
+        } else if (verb.equals("DELETE")) {
+            builder = httpClient.prepareDelete(url);
+        } else {
+            Assert.fail("Unknown verb " + verb);
+        }
+
+        builder.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE);
+        for (final Entry<String, String> q : queryParams.entrySet()) {
+            builder.addQueryParameter(q.getKey(), q.getValue());
+        }
+
+        return builder;
+    }
+
+    protected AccountJson getAccountJson() {
+        return getAccountJson(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
+    }
+
+    public AccountJson getAccountJson(final String name, final String externalKey, final String email) {
+        final String accountId = UUID.randomUUID().toString();
+        final int length = 4;
+        // Let junction figure it out
+        final BillCycleDayJson billCycleDay = null;
+        final String currency = DEFAULT_CURRENCY;
+        final String timeZone = "UTC";
+        final String address1 = "12 rue des ecoles";
+        final String address2 = "Poitier";
+        final String postalCode = "44 567";
+        final String company = "Renault";
+        final String city = "Quelque part";
+        final String state = "Poitou";
+        final String country = "France";
+        final String locale = "fr";
+        final String phone = "81 53 26 56";
+
+        // Note: the accountId payload is ignored on account creation
+        return new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, null, timeZone,
+                               address1, address2, postalCode, company, city, state, country, locale, phone, false, false);
+    }
+
+    /**
+     * We could implement a ClockResource in jaxrs with the ability to sync on user token
+     * but until we have a strong need for it, this is in the TODO list...
+     */
+    protected void crappyWaitForLackOfProperSynchonization() throws Exception {
+        Thread.sleep(5000);
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index ab631f2..b3e6037 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -18,31 +18,16 @@ package com.ning.billing.jaxrs;
 
 import java.io.IOException;
 import java.lang.reflect.Method;
-import java.math.BigDecimal;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.EventListener;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-import javax.ws.rs.core.Response.Status;
 
 import org.eclipse.jetty.servlet.FilterHolder;
-import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
 import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
@@ -53,10 +38,6 @@ import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.analytics.setup.AnalyticsModule;
 import com.ning.billing.api.TestApiListener;
 import com.ning.billing.beatrix.glue.BeatrixModule;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.PriceListSet;
-import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.dbi.DBIProvider;
@@ -66,33 +47,13 @@ import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
 import com.ning.billing.invoice.notification.NullInvoiceNotifier;
-import com.ning.billing.jaxrs.json.AccountEmailJson;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.AccountTimelineJson;
-import com.ning.billing.jaxrs.json.BillCycleDayJson;
-import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
-import com.ning.billing.jaxrs.json.ChargebackJson;
-import com.ning.billing.jaxrs.json.CreditJson;
-import com.ning.billing.jaxrs.json.InvoiceItemJsonSimple;
-import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
-import com.ning.billing.jaxrs.json.InvoiceJsonWithItems;
-import com.ning.billing.jaxrs.json.OverdueStateJson;
-import com.ning.billing.jaxrs.json.PaymentJsonSimple;
-import com.ning.billing.jaxrs.json.PaymentJsonWithBundleKeys;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
-import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.billing.junction.glue.DefaultJunctionModule;
 import com.ning.billing.overdue.glue.DefaultOverdueModule;
 import com.ning.billing.payment.glue.PaymentModule;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
-import com.ning.billing.server.ServerTestSuiteWithEmbeddedDB;
 import com.ning.billing.server.listeners.KillbillGuiceListener;
 import com.ning.billing.server.modules.KillbillServerModule;
-import com.ning.billing.util.api.AuditLevel;
+import com.ning.billing.tenant.glue.TenantModule;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.email.EmailModule;
@@ -104,63 +65,32 @@ import com.ning.billing.util.glue.CustomFieldModule;
 import com.ning.billing.util.glue.GlobalLockerModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.TagStoreModule;
-import com.ning.http.client.AsyncCompletionHandler;
 import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
 import com.ning.http.client.AsyncHttpClientConfig;
-import com.ning.http.client.ListenableFuture;
-import com.ning.http.client.Response;
 import com.ning.jetty.core.CoreConfig;
 import com.ning.jetty.core.server.HttpServer;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.datatype.joda.JodaModule;
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Module;
 
-import static com.ning.billing.jaxrs.resources.JaxrsResource.ACCOUNTS;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.BUNDLES;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_INFO;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.SUBSCRIPTIONS;
-import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
-public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
+public class TestJaxrsBase extends KillbillClient {
 
     protected static final String PLUGIN_NAME = "noop";
 
-    // STEPH
     protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 6000; // 5;
 
-    protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
-
-    private static final Logger log = LoggerFactory.getLogger(TestJaxrsBase.class);
-
-    public static final String HEADER_CONTENT_TYPE = "Content-type";
-    public static final String CONTENT_TYPE = "application/json";
-
-    protected static final String DEFAULT_CURRENCY = "USD";
-
-    private static TestKillbillGuiceListener listener;
+    protected static TestKillbillGuiceListener listener;
 
     private final MysqlTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getMysqlTestingHelper();
-    private HttpServer server;
 
-    protected CoreConfig config;
-    protected AsyncHttpClient httpClient;
-    protected ObjectMapper mapper;
-    protected ClockMock clock;
+    private HttpServer server;
     protected TestApiListener busHandler;
 
-    // Context information to be passed around
-    protected static final String createdBy = "Toto";
-    protected static final String reason = "i am god";
-    protected static final String comment = "no comment";
-
     public static void loadSystemPropertiesFromClasspath(final String resource) {
         final URL url = TestJaxrsBase.class.getResource(resource);
         assertNotNull(url);
@@ -187,15 +117,6 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
             return new TestKillbillServerModule(helper, clock);
         }
 
-        //
-        // Listener is created once before Suite and keeps pointer to helper and clock so they can get
-        // reset for each test Class-- needed in order to ONLY start Jetty once across all the test classes
-        // while still being able to start mysql before Jetty is started
-        //
-        public MysqlTestingHelper getMysqlTestingHelper() {
-            return helper;
-        }
-
         public Clock getClock() {
             return clock;
         }
@@ -260,6 +181,7 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
             install(new BeatrixModule());
             install(new DefaultJunctionModule());
             install(new DefaultOverdueModule());
+            install(new TenantModule());
             installClock();
         }
 
@@ -298,10 +220,15 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         this.clock = (ClockMock) listener.getClock();
     }
 
-    private void loadConfig() {
+    protected void loadConfig() {
         if (config == null) {
             config = new ConfigurationObjectFactory(System.getProperties()).build(CoreConfig.class);
         }
+
+        // For shiro (outside of Guice control)
+        System.setProperty("com.ning.jetty.jdbi.url", helper.getJdbcConnectionString());
+        System.setProperty("com.ning.jetty.jdbi.user", MysqlTestingHelper.USERNAME);
+        System.setProperty("com.ning.jetty.jdbi.password", MysqlTestingHelper.PASSWORD);
     }
 
     @BeforeSuite(groups = "slow")
@@ -313,17 +240,22 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         listener = new TestKillbillGuiceListener(helper, clock);
         server = new HttpServer();
 
-        final Iterable<EventListener> eventListeners = new Iterable<EventListener>() {
+        server.configure(config, getListeners(), getFilters());
+
+        server.start();
+    }
+
+    protected Iterable<EventListener> getListeners() {
+        return new Iterable<EventListener>() {
             @Override
             public Iterator<EventListener> iterator() {
-                final ArrayList<EventListener> array = new ArrayList<EventListener>();
-                array.add(listener);
-                return array.iterator();
+                return ImmutableList.<EventListener>of(listener).iterator();
             }
         };
-        server.configure(config, eventListeners, new HashMap<FilterHolder, String>());
+    }
 
-        server.start();
+    protected Map<FilterHolder, String> getFilters() {
+        return new HashMap<FilterHolder, String>();
     }
 
     @AfterSuite(groups = "slow")
@@ -333,780 +265,4 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         } catch (Exception ignored) {
         }
     }
-
-    protected List<PaymentMethodProperties> getPaymentMethodCCProperties() {
-        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
-        properties.add(new PaymentMethodProperties("type", "CreditCard", false));
-        properties.add(new PaymentMethodProperties("cardType", "Visa", false));
-        properties.add(new PaymentMethodProperties("cardHolderName", "Mr Sniff", false));
-        properties.add(new PaymentMethodProperties("expirationDate", "2015-08", false));
-        properties.add(new PaymentMethodProperties("maskNumber", "3451", false));
-        properties.add(new PaymentMethodProperties("address1", "23, rue des cerisiers", false));
-        properties.add(new PaymentMethodProperties("address2", "", false));
-        properties.add(new PaymentMethodProperties("city", "Toulouse", false));
-        properties.add(new PaymentMethodProperties("country", "France", false));
-        properties.add(new PaymentMethodProperties("postalCode", "31320", false));
-        properties.add(new PaymentMethodProperties("state", "Midi-Pyrenees", false));
-        return properties;
-    }
-
-    protected List<PaymentMethodProperties> getPaymentMethodPaypalProperties() {
-        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
-        properties.add(new PaymentMethodProperties("type", "CreditCard", false));
-        properties.add(new PaymentMethodProperties("email", "zouzou@laposte.fr", false));
-        properties.add(new PaymentMethodProperties("baid", "23-8787d-R", false));
-        return properties;
-    }
-
-    protected PaymentMethodJson getPaymentMethodJson(final String accountId, final List<PaymentMethodProperties> properties) {
-        final PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, properties);
-        return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
-    }
-
-    //
-    // ACCOUNT UTILITIES
-    //
-
-    protected AccountJson getAccountByExternalKey(final String externalKey) throws Exception {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, externalKey);
-        final Response response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected AccountTimelineJson getAccountTimeline(final String accountId) throws Exception {
-        return doGetAccountTimeline(accountId, AuditLevel.NONE);
-    }
-
-    protected AccountTimelineJson getAccountTimelineWithAudits(final String accountId, final AuditLevel auditLevel) throws Exception {
-        return doGetAccountTimeline(accountId, auditLevel);
-    }
-
-    private AccountTimelineJson doGetAccountTimeline(final String accountId, final AuditLevel auditLevel) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TIMELINE;
-
-        final Response response = doGet(uri, ImmutableMap.<String, String>of(JaxrsResource.QUERY_AUDIT, auditLevel.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected AccountJson createAccountWithDefaultPaymentMethod() throws Exception {
-        final AccountJson input = createAccount();
-        return doCreateAccountWithDefaultPaymentMethod(input);
-    }
-
-    protected AccountJson createAccountWithDefaultPaymentMethod(final String name, final String key, final String email) throws Exception {
-        final AccountJson input = createAccount(name, key, email);
-        return doCreateAccountWithDefaultPaymentMethod(input);
-    }
-
-    protected AccountJson doCreateAccountWithDefaultPaymentMethod(final AccountJson input) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        final PaymentMethodJson paymentMethodJson = getPaymentMethodJson(input.getAccountId(), null);
-        String baseJson = mapper.writeValueAsString(paymentMethodJson);
-        Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
-
-        Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, input.getExternalKey());
-        response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-        Assert.assertNotNull(objFromJson.getPaymentMethodId());
-        return objFromJson;
-    }
-
-    protected AccountJson createAccount() throws Exception {
-        return createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
-    }
-
-    protected AccountJson createAccount(final String name, final String key, final String email) throws Exception {
-        final AccountJson input = getAccountJson(name, key, email);
-        String baseJson = mapper.writeValueAsString(input);
-        Response response = doPost(JaxrsResource.ACCOUNTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-        return objFromJson;
-    }
-
-    protected AccountJson updateAccount(final String accountId, final AccountJson newInput) throws Exception {
-        final String baseJson = mapper.writeValueAsString(newInput);
-
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId;
-        final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String retrievedJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(retrievedJson, AccountJson.class);
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected List<AccountEmailJson> getEmailsForAccount(final String accountId) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(response.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
-    }
-
-    protected void addEmailToAccount(final String accountId, final AccountEmailJson email) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final String emailString = mapper.writeValueAsString(email);
-        final Response response = doPost(uri, emailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-    }
-
-    protected void removeEmailFromAccount(final String accountId, final String email) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final Response fifthResponse = doDelete(uri + "/" + email, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-    }
-
-    protected BundleJsonNoSubscriptions createBundle(final String accountId, final String key) throws Exception {
-        final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, null, null);
-        String baseJson = mapper.writeValueAsString(input);
-        Response response = doPost(JaxrsResource.BUNDLES_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        final BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
-        Assert.assertTrue(objFromJson.equalsNoId(input));
-        return objFromJson;
-    }
-
-    protected SubscriptionJsonNoEvents createSubscription(final String bundleId, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
-
-        final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory,
-                                                                            billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME,
-                                                                            null, null, null);
-        String baseJson = mapper.writeValueAsString(input);
-
-        final Map<String, String> queryParams = waitCompletion ? getQueryParamsForCallCompletion("5") : DEFAULT_EMPTY_QUERY;
-        Response response = doPost(JaxrsResource.SUBSCRIPTIONS_PATH, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        final SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
-        Assert.assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(input));
-        return objFromJson;
-    }
-
-    //
-    // INVOICE UTILITIES
-    //
-
-    protected AccountJson createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod();
-        assertNotNull(accountJson);
-
-        // Add a bundle, subscription and move the clock to get the first invoice
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
-        assertNotNull(bundleJson);
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-        clock.addDays(32);
-        crappyWaitForLackOfProperSynchonization();
-
-        return accountJson;
-    }
-
-    protected AccountJson createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
-        // Create an account with no payment method
-        final AccountJson accountJson = createAccount();
-        assertNotNull(accountJson);
-
-        // Add a bundle, subscription and move the clock to get the first invoice
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
-        assertNotNull(bundleJson);
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-        clock.addMonths(1);
-        crappyWaitForLackOfProperSynchonization();
-
-        // No payment will be triggered as the account doesn't have a payment method
-
-        return accountJson;
-    }
-
-    protected InvoiceJsonSimple getInvoice(final String invoiceId) throws IOException {
-        return doGetInvoice(invoiceId, Boolean.FALSE, InvoiceJsonSimple.class);
-    }
-
-    protected InvoiceJsonWithItems getInvoiceWithItems(final String invoiceId) throws IOException {
-        return doGetInvoice(invoiceId, Boolean.TRUE, InvoiceJsonWithItems.class);
-    }
-
-    private <T> T doGetInvoice(final String invoiceId, final Boolean withItems, final Class<T> clazz) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
-
-        final Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-
-        final T firstInvoiceJson = mapper.readValue(baseJson, clazz);
-        assertNotNull(firstInvoiceJson);
-
-        return firstInvoiceJson;
-    }
-
-    protected List<InvoiceJsonSimple> getInvoicesForAccount(final String accountId) throws IOException {
-        return doGetInvoicesForAccount(accountId, Boolean.FALSE, new TypeReference<List<InvoiceJsonSimple>>() {});
-    }
-
-    protected List<InvoiceJsonWithItems> getInvoicesWithItemsForAccount(final String accountId) throws IOException {
-        return doGetInvoicesForAccount(accountId, Boolean.TRUE, new TypeReference<List<InvoiceJsonWithItems>>() {});
-    }
-
-    private <T> List<T> doGetInvoicesForAccount(final String accountId, final Boolean withItems, final TypeReference<List<T>> clazz) throws IOException {
-        final String invoicesURI = JaxrsResource.INVOICES_PATH;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
-
-        final Response invoicesResponse = doGet(invoicesURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(invoicesResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final String invoicesBaseJson = invoicesResponse.getResponseBody();
-        final List<T> invoices = mapper.readValue(invoicesBaseJson, clazz);
-        assertNotNull(invoices);
-
-        return invoices;
-    }
-
-    protected InvoiceJsonSimple createDryRunInvoice(final String accountId, final DateTime futureDate) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
-        queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
-
-        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
-        assertNotNull(futureInvoice);
-
-        return futureInvoice;
-    }
-
-    protected void createInvoice(final String accountId, final DateTime futureDate) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
-
-        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-    }
-
-    protected void adjustInvoiceItem(final String accountId, final String invoiceId, final String invoiceItemId,
-                                     @Nullable final DateTime requestedDate, @Nullable final BigDecimal amount, @Nullable final Currency currency) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        if (requestedDate != null) {
-            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
-        }
-
-        final InvoiceItemJsonSimple adjustment = new InvoiceItemJsonSimple(invoiceItemId, null, null, accountId, null, null, null, null,
-                                                                           null, null, null, amount, currency, null);
-        final String adjustmentJson = mapper.writeValueAsString(adjustment);
-        final Response response = doPost(uri, adjustmentJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-    }
-
-    protected InvoiceJsonWithItems createExternalCharge(final String accountId, final BigDecimal amount, @Nullable final String bundleId,
-                                                        @Nullable final Currency currency, @Nullable final DateTime requestedDate) throws Exception {
-        return doCreateExternalCharge(accountId, null, bundleId, amount, currency, requestedDate, JaxrsResource.CHARGES_PATH);
-    }
-
-    protected InvoiceJsonWithItems createExternalChargeForInvoice(final String accountId, final String invoiceId, @Nullable final String bundleId, final BigDecimal amount,
-                                                                  @Nullable final Currency currency, @Nullable final DateTime requestedDate) throws Exception {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.CHARGES;
-        return doCreateExternalCharge(accountId, invoiceId, bundleId, amount, currency, requestedDate, uri);
-    }
-
-    private InvoiceJsonWithItems doCreateExternalCharge(final String accountId, @Nullable final String invoiceId, @Nullable final String bundleId, @Nullable final BigDecimal amount,
-                                                        @Nullable final Currency currency, final DateTime requestedDate, final String uri) throws IOException {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        if (requestedDate != null) {
-            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
-        }
-
-        final InvoiceItemJsonSimple externalCharge = new InvoiceItemJsonSimple(null, invoiceId, null, accountId, bundleId, null, null, null,
-                                                                               null, null, null, amount, currency, null);
-        final String externalChargeJson = mapper.writeValueAsString(externalCharge);
-        final Response response = doPost(uri, externalChargeJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        final Map<String, String> queryParamsForInvoice = new HashMap<String, String>();
-        queryParamsForInvoice.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParamsForInvoice.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, "true");
-        final Response invoiceResponse = doGetWithUrl(location, queryParamsForInvoice, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(invoiceResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final String invoicesBaseJson = invoiceResponse.getResponseBody();
-        final InvoiceJsonWithItems invoice = mapper.readValue(invoicesBaseJson, new TypeReference<InvoiceJsonWithItems>() {});
-        assertNotNull(invoice);
-
-        return invoice;
-    }
-
-    //
-    // PAYMENT UTILITIES
-    //
-
-    protected PaymentJsonSimple getPayment(final String paymentId) throws IOException {
-        return doGetPayment(paymentId, DEFAULT_EMPTY_QUERY, PaymentJsonSimple.class);
-    }
-
-    protected PaymentJsonWithBundleKeys getPaymentWithRefundsAndChargebacks(final String paymentId) throws IOException {
-        return doGetPayment(paymentId, ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_WITH_REFUNDS_AND_CHARGEBACKS, "true"), PaymentJsonWithBundleKeys.class);
-    }
-
-    protected <T extends PaymentJsonSimple> T doGetPayment(final String paymentId, final Map<String, String> queryParams, final Class<T> clazz) throws IOException {
-        final String paymentURI = JaxrsResource.PAYMENTS_PATH + "/" + paymentId;
-
-        final Response paymentResponse = doGet(paymentURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final T paymentJsonSimple = mapper.readValue(paymentResponse.getResponseBody(), clazz);
-        assertNotNull(paymentJsonSimple);
-
-        return paymentJsonSimple;
-    }
-
-    protected PaymentMethodJson getPaymentMethod(final String paymentMethodId) throws IOException {
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-        final Response paymentMethodResponse = doGet(paymentMethodURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
-        assertNotNull(paymentMethodJson);
-
-        return paymentMethodJson;
-    }
-
-    protected PaymentMethodJson getPaymentMethodWithPluginInfo(final String paymentMethodId) throws IOException {
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-
-        final Map<String, String> queryPaymentMethods = new HashMap<String, String>();
-        queryPaymentMethods.put(QUERY_PAYMENT_METHOD_PLUGIN_INFO, "true");
-        final Response paymentMethodResponse = doGet(paymentMethodURI, queryPaymentMethods, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
-        assertNotNull(paymentMethodJson);
-
-        return paymentMethodJson;
-    }
-
-    protected List<PaymentJsonSimple> getPaymentsForAccount(final String accountId) throws IOException {
-        final String paymentsURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.PAYMENTS;
-        final Response paymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentsResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String paymentsBaseJson = paymentsResponse.getResponseBody();
-
-        final List<PaymentJsonSimple> paymentJsonSimples = mapper.readValue(paymentsBaseJson, new TypeReference<List<PaymentJsonSimple>>() {});
-        assertNotNull(paymentJsonSimples);
-
-        return paymentJsonSimples;
-    }
-
-    protected List<PaymentJsonSimple> getPaymentsForInvoice(final String invoiceId) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected void payAllInvoices(final AccountJson accountJson, final Boolean externalPayment) throws IOException {
-        final PaymentJsonSimple payment = new PaymentJsonSimple(null, null, accountJson.getAccountId(), null, null, null, null,
-                                                                null, 0, null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + JaxrsResource.PAYMENTS;
-        doPost(uri, postJson, ImmutableMap.<String, String>of("externalPayment", externalPayment.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected List<PaymentJsonSimple> createInstaPayment(final AccountJson accountJson, final InvoiceJsonSimple invoice) throws IOException {
-        final PaymentJsonSimple payment = new PaymentJsonSimple(invoice.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
-                                                                invoice.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
-        doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        return getPaymentsForInvoice(invoice.getInvoiceId());
-    }
-
-    protected List<PaymentJsonSimple> createExternalPayment(final AccountJson accountJson, final String invoiceId, final BigDecimal paidAmount) throws IOException {
-        final PaymentJsonSimple payment = new PaymentJsonSimple(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
-                                                                invoiceId, null, null, null, null, 0,
-                                                                null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
-        final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentResponse.getStatusCode(), Status.CREATED.getStatusCode());
-
-        return getPaymentsForInvoice(invoiceId);
-    }
-
-    //
-    // CHARGEBACKS
-    //
-
-    protected ChargebackJson createChargeBack(final String paymentId, final BigDecimal chargebackAmount) throws IOException {
-        final ChargebackJson input = new ChargebackJson(null, null, chargebackAmount, paymentId, null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
-        // Create the chargeback
-        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
-
-        // Find the chargeback by location
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-        final Response responseByLocation = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(responseByLocation.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(responseByLocation.getResponseBody(), ChargebackJson.class);
-    }
-
-    //
-    // REFUNDS
-    //
-
-    protected List<RefundJson> getRefundsForAccount(final String accountId) throws IOException {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.REFUNDS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
-        assertNotNull(refunds);
-
-        return refunds;
-    }
-
-    protected List<RefundJson> getRefundsForPayment(final String paymentId) throws IOException {
-        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
-        assertNotNull(refunds);
-
-        return refunds;
-    }
-
-    protected RefundJson createRefund(final String paymentId, final BigDecimal amount) throws IOException {
-        return doCreateRefund(paymentId, amount, false, ImmutableMap.<String, BigDecimal>of());
-    }
-
-    protected RefundJson createRefundWithInvoiceAdjustment(final String paymentId, final BigDecimal amount) throws IOException {
-        return doCreateRefund(paymentId, amount, true, ImmutableMap.<String, BigDecimal>of());
-    }
-
-    protected RefundJson createRefundWithInvoiceItemAdjustment(final String paymentId, final String invoiceItemId, final BigDecimal amount) throws IOException {
-        final Map<String, BigDecimal> adjustments = new HashMap<String, BigDecimal>();
-        adjustments.put(invoiceItemId, amount);
-        return doCreateRefund(paymentId, amount, true, adjustments);
-    }
-
-    private RefundJson doCreateRefund(final String paymentId, final BigDecimal amount, final boolean adjusted, final Map<String, BigDecimal> itemAdjustments) throws IOException {
-        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
-
-        final List<InvoiceItemJsonSimple> adjustments = new ArrayList<InvoiceItemJsonSimple>();
-        for (final String itemId : itemAdjustments.keySet()) {
-            adjustments.add(new InvoiceItemJsonSimple(itemId, null, null, null, null, null, null, null, null, null, null,
-                                                      itemAdjustments.get(itemId), null, null));
-        }
-        final RefundJson refundJson = new RefundJson(null, paymentId, amount, DEFAULT_CURRENCY, adjusted, null, null, adjustments, null);
-        final String baseJson = mapper.writeValueAsString(refundJson);
-        final Response response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String locationCC = response.getHeader("Location");
-        Assert.assertNotNull(locationCC);
-
-        // Retrieves by Id based on Location returned
-        final Response retrievedResponse = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(retrievedResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String retrievedBaseJson = retrievedResponse.getResponseBody();
-        final RefundJson retrievedRefundJson = mapper.readValue(retrievedBaseJson, RefundJson.class);
-        assertNotNull(retrievedRefundJson);
-        // Verify we have the adjusted items
-        if (retrievedRefundJson.getAdjustments() != null) {
-            final Set<String> allLinkedItemIds = new HashSet<String>(Collections2.transform(retrievedRefundJson.getAdjustments(), new Function<InvoiceItemJsonSimple, String>() {
-                @Override
-                public String apply(@Nullable final InvoiceItemJsonSimple input) {
-                    if (input != null) {
-                        return input.getLinkedInvoiceItemId();
-                    } else {
-                        return null;
-                    }
-                }
-            }));
-            assertEquals(allLinkedItemIds, itemAdjustments.keySet());
-        }
-
-        return retrievedRefundJson;
-    }
-
-    protected Map<String, String> getQueryParamsForCallCompletion(final String timeoutSec) {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_CALL_COMPLETION, "true");
-        queryParams.put(JaxrsResource.QUERY_CALL_TIMEOUT, timeoutSec);
-        return queryParams;
-    }
-
-    //
-    // CREDITS
-    //
-
-    protected CreditJson createCreditForAccount(final String accountId, final BigDecimal creditAmount,
-                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
-        return createCreditForInvoice(accountId, null, creditAmount, requestedDate, effectiveDate);
-    }
-
-    protected CreditJson createCreditForInvoice(final String accountId, final String invoiceId, final BigDecimal creditAmount,
-                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
-        final CreditJson input = new CreditJson(creditAmount, invoiceId, UUID.randomUUID().toString(),
-                                                requestedDate, effectiveDate,
-                                                UUID.randomUUID().toString(), accountId,
-                                                null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
-        // Create the credit
-        Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
-
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(response.getResponseBody(), CreditJson.class);
-    }
-
-    //
-    // OVERDUE
-    //
-
-    protected OverdueStateJson getOverdueStateForAccount(final String accountId) throws Exception {
-        return doGetOverdueState(accountId, ACCOUNTS);
-    }
-
-    protected OverdueStateJson getOverdueStateForBundle(final String bundleId) throws Exception {
-        return doGetOverdueState(bundleId, BUNDLES);
-    }
-
-    protected OverdueStateJson getOverdueStateForSubscription(final String subscriptionId) throws Exception {
-        return doGetOverdueState(subscriptionId, SUBSCRIPTIONS);
-    }
-
-    protected OverdueStateJson doGetOverdueState(final String id, final String resourceType) throws Exception {
-        final String overdueURI = JaxrsResource.OVERDUE_PATH + "/" + resourceType + "/" + id;
-        final Response overdueResponse = doGet(overdueURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(overdueResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final OverdueStateJson overdueStateJson = mapper.readValue(overdueResponse.getResponseBody(), OverdueStateJson.class);
-        assertNotNull(overdueStateJson);
-
-        return overdueStateJson;
-    }
-
-    //
-    // HTTP CLIENT HELPERS
-    //
-    protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
-        if (body != null) {
-            builder.setBody(body);
-        } else {
-            builder.setBody("{}");
-        }
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doPut(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
-        if (body != null) {
-            builder.setBody(body);
-        } else {
-            builder.setBody("{}");
-        }
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doDelete(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doGet(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        return doGetWithUrl(url, queryParams, timeoutSec);
-    }
-
-    protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
-        return executeAndWait(builder, timeoutSec, false);
-    }
-
-    private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
-
-        if (addContextHeader) {
-            builder.addHeader(JaxrsResource.HDR_CREATED_BY, createdBy);
-            builder.addHeader(JaxrsResource.HDR_REASON, reason);
-            builder.addHeader(JaxrsResource.HDR_COMMENT, comment);
-        }
-
-        Response response = null;
-        try {
-            final ListenableFuture<Response> futureStatus =
-                    builder.execute(new AsyncCompletionHandler<Response>() {
-                        @Override
-                        public Response onCompleted(final Response response) throws Exception {
-                            return response;
-                        }
-                    });
-            response = futureStatus.get(timeoutSec, TimeUnit.SECONDS);
-        } catch (Exception e) {
-            Assert.fail(e.getMessage());
-        }
-        Assert.assertNotNull(response);
-        return response;
-    }
-
-    protected String getUrlFromUri(final String uri) {
-        return String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-    }
-
-    private BoundRequestBuilder getBuilderWithHeaderAndQuery(final String verb, final String url, final Map<String, String> queryParams) {
-        BoundRequestBuilder builder = null;
-        if (verb.equals("GET")) {
-            builder = httpClient.prepareGet(url);
-        } else if (verb.equals("POST")) {
-            builder = httpClient.preparePost(url);
-        } else if (verb.equals("PUT")) {
-            builder = httpClient.preparePut(url);
-        } else if (verb.equals("DELETE")) {
-            builder = httpClient.prepareDelete(url);
-        } else {
-            Assert.fail("Unknown verb " + verb);
-        }
-
-        builder.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE);
-        for (final Entry<String, String> q : queryParams.entrySet()) {
-            builder.addQueryParameter(q.getKey(), q.getValue());
-        }
-
-        return builder;
-    }
-
-    protected AccountJson getAccountJson() {
-        return getAccountJson(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
-    }
-
-    public AccountJson getAccountJson(final String name, final String externalKey, final String email) {
-        final String accountId = UUID.randomUUID().toString();
-        final int length = 4;
-        // Let junction figure it out
-        final BillCycleDayJson billCycleDay = null;
-        final String currency = DEFAULT_CURRENCY;
-        final String timeZone = "UTC";
-        final String address1 = "12 rue des ecoles";
-        final String address2 = "Poitier";
-        final String postalCode = "44 567";
-        final String company = "Renault";
-        final String city = "Quelque part";
-        final String state = "Poitou";
-        final String country = "France";
-        final String locale = "fr";
-        final String phone = "81 53 26 56";
-
-        // Note: the accountId payload is ignored on account creation
-        return new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, null, timeZone,
-                               address1, address2, postalCode, company, city, state, country, locale, phone, false, false);
-    }
-
-    /**
-     * We could implement a ClockResource in jaxrs with the ability to sync on user token
-     * but until we have a strong need for it, this is in the TODO list...
-     */
-    protected void crappyWaitForLackOfProperSynchonization() throws Exception {
-        Thread.sleep(5000);
-    }
 }
diff --git a/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
new file mode 100644
index 0000000..2ec77e1
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.server.security;
+
+import java.util.UUID;
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.support.DelegatingSubject;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.server.ServerTestSuiteWithEmbeddedDB;
+import com.ning.billing.tenant.api.DefaultTenant;
+import com.ning.billing.tenant.dao.DefaultTenantDao;
+import com.ning.billing.util.bus.Bus;
+
+import com.jolbox.bonecp.BoneCPConfig;
+import com.jolbox.bonecp.BoneCPDataSource;
+
+public class TestKillbillJdbcRealm extends ServerTestSuiteWithEmbeddedDB {
+
+    private SecurityManager securityManager;
+    private DefaultTenant tenant;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        // Create the tenant
+        final DefaultTenantDao tenantDao = new DefaultTenantDao(getMysqlTestingHelper().getDBI(), Mockito.mock(Bus.class));
+        tenant = new DefaultTenant(UUID.randomUUID(), UUID.randomUUID().toString(),
+                                   UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        tenantDao.create(tenant, internalCallContext);
+
+        // Setup the security manager
+        final BoneCPConfig dbConfig = new BoneCPConfig();
+        dbConfig.setJdbcUrl(getMysqlTestingHelper().getJdbcConnectionString());
+        dbConfig.setUsername(MysqlTestingHelper.USERNAME);
+        dbConfig.setPassword(MysqlTestingHelper.PASSWORD);
+
+        final KillbillJdbcRealm jdbcRealm;
+        jdbcRealm = new KillbillJdbcRealm();
+        jdbcRealm.setDataSource(new BoneCPDataSource(dbConfig));
+
+        securityManager = new DefaultSecurityManager(jdbcRealm);
+    }
+
+    @Test(groups = "slow")
+    public void testAuthentication() throws Exception {
+        final DelegatingSubject subject = new DelegatingSubject(securityManager);
+
+        // Good combo
+        final AuthenticationToken goodToken = new UsernamePasswordToken(tenant.getApiKey(), tenant.getApiSecret());
+        try {
+            securityManager.login(subject, goodToken);
+            Assert.assertTrue(true);
+        } catch (AuthenticationException e) {
+            Assert.fail();
+        }
+
+        // Bad login
+        final AuthenticationToken badPasswordToken = new UsernamePasswordToken(tenant.getApiKey(), tenant.getApiSecret() + "T");
+        try {
+            securityManager.login(subject, badPasswordToken);
+            Assert.fail();
+        } catch (AuthenticationException e) {
+            Assert.assertTrue(true);
+        }
+
+        // Bad password
+        final AuthenticationToken badLoginToken = new UsernamePasswordToken(tenant.getApiKey() + "U", tenant.getApiSecret());
+        try {
+            securityManager.login(subject, badLoginToken);
+            Assert.fail();
+        } catch (AuthenticationException e) {
+            Assert.assertTrue(true);
+        }
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
new file mode 100644
index 0000000..c5c5c34
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.server.security;
+
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.shiro.web.env.EnvironmentLoaderListener;
+import org.apache.shiro.web.servlet.ShiroFilter;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.TestJaxrsBase;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.server.listeners.KillbillGuiceListener;
+import com.ning.http.client.AsyncHttpClient;
+import com.ning.http.client.AsyncHttpClientConfig;
+import com.ning.http.client.Realm;
+import com.ning.http.client.Realm.AuthScheme;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class TestTenantFilter extends TestJaxrsBase {
+
+    @Override
+    protected void loadConfig() {
+        System.setProperty(KillbillGuiceListener.KILLBILL_MULTITENANT_PROPERTY, "true");
+        super.loadConfig();
+    }
+
+    @Override
+    protected Iterable<EventListener> getListeners() {
+        return new Iterable<EventListener>() {
+            @Override
+            public Iterator<EventListener> iterator() {
+                return ImmutableList.<EventListener>of(listener, new EnvironmentLoaderListener()).iterator();
+            }
+        };
+    }
+
+    @Override
+    protected Map<FilterHolder, String> getFilters() {
+        return ImmutableMap.<FilterHolder, String>of(new FilterHolder(ShiroFilter.class), "/*");
+    }
+
+    // TODO Need to run by itself for now as the server from the test suite doesn't have the Shiro setup
+    @Test(groups = "slow", enabled = false)
+    public void testTenantShouldOnlySeeOwnAccount() throws Exception {
+        // Try to create an account without being logged-in
+        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+
+        // Create the tenant
+        final String apiKeyTenant1 = "pierre";
+        final String apiSecretTenant1 = "pierreIsFr3nch";
+        createTenant(apiKeyTenant1, apiSecretTenant1);
+
+        // We should still not be able to create an account
+        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+
+        // Now, let's log-in and try again
+        loginTenant(apiKeyTenant1, apiSecretTenant1);
+        final AccountJson account1 = createAccount();
+        Assert.assertEquals(getAccountByExternalKey(account1.getExternalKey()), account1);
+
+        logoutTenant();
+
+        // Create another tenant
+        final String apiKeyTenant2 = "stephane";
+        final String apiSecretTenant2 = "stephane1sAlsoFr3nch";
+        createTenant(apiKeyTenant2, apiSecretTenant2);
+
+        // We should not be able to create an account before being logged-in
+        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+
+        // Now, let's log-in and try again
+        loginTenant(apiKeyTenant2, apiSecretTenant2);
+        final AccountJson account2 = createAccount();
+        Assert.assertEquals(getAccountByExternalKey(account2.getExternalKey()), account2);
+
+        // We should not be able to retrieve the first account as tenant2
+        Assert.assertEquals(getAccountByExternalKeyNoValidation(account1.getExternalKey()).getStatusCode(), Status.NOT_FOUND.getStatusCode());
+
+        // Same for tenant1 and account2
+        loginTenant(apiKeyTenant1, apiSecretTenant1);
+        Assert.assertEquals(getAccountByExternalKeyNoValidation(account2.getExternalKey()).getStatusCode(), Status.NOT_FOUND.getStatusCode());
+    }
+
+    private void loginTenant(final String apiKey, final String apiSecret) {
+        final AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
+        final Realm realm = new Realm.RealmBuilder()
+                .setPrincipal(apiKey)
+                .setPassword(apiSecret)
+                .setUsePreemptiveAuth(true)
+                .setScheme(AuthScheme.BASIC)
+                .build();
+        builder.setRealm(realm).setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build();
+        httpClient = new AsyncHttpClient(builder.build());
+    }
+
+    private void logoutTenant() {
+        httpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build());
+    }
+}
diff --git a/server/src/test/resources/shiro.ini b/server/src/test/resources/shiro.ini
new file mode 100644
index 0000000..21defe1
--- /dev/null
+++ b/server/src/test/resources/shiro.ini
@@ -0,0 +1,36 @@
+###################################################################################
+#                                                                                 #
+#                   Copyright 2010-2012 Ning, Inc.                                #
+#                                                                                 #
+#      Ning licenses this file to you under the Apache License, version 2.0       #
+#      (the "License"); you may not use this file except in compliance with the   #
+#      License.  You may obtain a copy of the License at:                         #
+#                                                                                 #
+#          http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                                 #
+#      Unless required by applicable law or agreed to in writing, software        #
+#      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+#      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the  #
+#      License for the specific language governing permissions and limitations    #
+#      under the License.                                                         #
+#                                                                                 #
+###################################################################################
+
+[main]
+# Bypass the servlet container completely for session management and delegate
+# it to Shiro (to be portable across servlet containers)
+# The default session timeout is 30 minutes.
+sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
+# Use the configured native session manager
+securityManager.sessionManager = $sessionManager
+
+jdbcRealm=com.ning.billing.server.security.KillbillJdbcRealm
+
+[urls]
+# Special endpoints: healthcheck, tenant API.
+# TODO: don't secure them for now - eventually require admin privileges
+/1.0/healthcheck = anon
+/1.0/kb/tenants/** = anon
+# For all other resources, require basic auth
+# TODO: ssl, authcBasic
+/1.0/kb/** = authcBasic

tenant/pom.xml 120(+120 -0)

diff --git a/tenant/pom.xml b/tenant/pom.xml
new file mode 100644
index 0000000..4161ee2
--- /dev/null
+++ b/tenant/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2010-2012 Ning, Inc.
+  ~
+  ~ Ning licenses this file to you under the Apache License, version 2.0
+  ~ (the "License"); you may not use this file except in compliance with the
+  ~ License.  You may obtain a copy of the License at:
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+  ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+  ~ License for the specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ning.billing</groupId>
+        <artifactId>killbill</artifactId>
+        <version>0.1.34-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>killbill-tenant</artifactId>
+    <name>killbill-tenant</name>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.jdbi</groupId>
+            <artifactId>jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>stringtemplate</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj-db-files</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenant.java b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenant.java
new file mode 100644
index 0000000..1f1b250
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenant.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+import java.util.UUID;
+
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultTenant extends EntityBase implements Tenant {
+
+    private final String externalKey;
+    private final String apiKey;
+    // Decrypted (clear) secret
+    private final String apiSecret;
+
+    /**
+     * This call is used to create a tenant
+     *
+     * @param data TenantData new data for the tenant
+     */
+    public DefaultTenant(final TenantData data) {
+        this(UUID.randomUUID(), data);
+    }
+
+    /**
+     * This call is used to update an existing tenant
+     *
+     * @param id   UUID id of the existing tenant to update
+     * @param data TenantData new data for the existing tenant
+     */
+    public DefaultTenant(final UUID id, final TenantData data) {
+        this(id, data.getExternalKey(), data.getApiKey(), data.getApiSecret());
+    }
+
+    public DefaultTenant(final UUID id, final String externalKey, final String apiKey, final String apiSecret) {
+        super(id);
+        this.externalKey = externalKey;
+        this.apiKey = apiKey;
+        this.apiSecret = apiSecret;
+    }
+
+    @Override
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    @Override
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    @Override
+    public String getApiSecret() {
+        return apiSecret;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultTenant");
+        sb.append("{externalKey='").append(externalKey).append('\'');
+        sb.append(", apiKey='").append(apiKey).append('\'');
+        // Don't print the secret
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultTenant that = (DefaultTenant) o;
+
+        if (apiKey != null ? !apiKey.equals(that.apiKey) : that.apiKey != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (apiSecret != null ? !apiSecret.equals(that.apiSecret) : that.apiSecret != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (apiKey != null ? apiKey.hashCode() : 0);
+        result = 31 * result + (apiSecret != null ? apiSecret.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantService.java b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantService.java
new file mode 100644
index 0000000..b5c7a1c
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantService.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api;
+
+public class DefaultTenantService implements TenantService {
+
+    private static final String TENANT_SERVICE_NAME = "tenant-service";
+
+    @Override
+    public String getName() {
+        return TENANT_SERVICE_NAME;
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/api/user/DefaultTenantUserApi.java b/tenant/src/main/java/com/ning/billing/tenant/api/user/DefaultTenantUserApi.java
new file mode 100644
index 0000000..74c33df
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/api/user/DefaultTenantUserApi.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.api.user;
+
+import java.util.UUID;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.tenant.api.DefaultTenant;
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.tenant.api.TenantApiException;
+import com.ning.billing.tenant.api.TenantData;
+import com.ning.billing.tenant.api.TenantUserApi;
+import com.ning.billing.tenant.dao.TenantDao;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+import com.google.inject.Inject;
+
+public class DefaultTenantUserApi implements TenantUserApi {
+
+    private final TenantDao tenantDao;
+    private final InternalCallContextFactory internalCallContextFactory;
+
+    @Inject
+    public DefaultTenantUserApi(final TenantDao tenantDao, final InternalCallContextFactory internalCallContextFactory) {
+        this.tenantDao = tenantDao;
+        this.internalCallContextFactory = internalCallContextFactory;
+    }
+
+    @Override
+    public Tenant createTenant(final TenantData data, final CallContext context) throws TenantApiException {
+        final Tenant tenant = new DefaultTenant(data);
+
+        try {
+            tenantDao.create(tenant, internalCallContextFactory.createInternalCallContext(context));
+        } catch (EntityPersistenceException e) {
+            throw new TenantApiException(e, ErrorCode.TENANT_CREATION_FAILED);
+        }
+
+        return tenant;
+    }
+
+    @Override
+    public Tenant getTenantByApiKey(final String key) throws TenantApiException {
+        final Tenant tenant = tenantDao.getTenantByApiKey(key);
+        if (tenant == null) {
+            throw new TenantApiException(ErrorCode.TENANT_DOES_NOT_EXIST_FOR_API_KEY, key);
+        }
+        return tenant;
+    }
+
+    @Override
+    public Tenant getTenantById(final UUID id) throws TenantApiException {
+        // TODO - API cleanup?
+        final Tenant tenant = tenantDao.getById(id, new InternalTenantContext(null, null));
+        if (tenant == null) {
+            throw new TenantApiException(ErrorCode.TENANT_DOES_NOT_EXIST_FOR_ID, id);
+        }
+        return tenant;
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
new file mode 100644
index 0000000..04d2705
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.crypto.RandomNumberGenerator;
+import org.apache.shiro.crypto.SecureRandomNumberGenerator;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+import org.apache.shiro.util.ByteSource;
+import org.skife.jdbi.v2.IDBI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.inject.Inject;
+
+public class DefaultTenantDao implements TenantDao {
+
+    private static final Logger log = LoggerFactory.getLogger(DefaultTenantDao.class);
+
+    private final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
+
+    private final TenantSqlDao tenantSqlDao;
+    private final Bus eventBus;
+
+    @Inject
+    public DefaultTenantDao(final IDBI dbi, final Bus eventBus) {
+        this.eventBus = eventBus;
+        this.tenantSqlDao = dbi.onDemand(TenantSqlDao.class);
+    }
+
+    @Override
+    public Tenant getTenantByApiKey(final String apiKey) {
+        return tenantSqlDao.getByApiKey(apiKey);
+    }
+
+    @Override
+    public void create(final Tenant entity, final InternalCallContext context) throws EntityPersistenceException {
+        // Create the salt and password
+        final ByteSource salt = rng.nextBytes();
+        // Hash the plain-text password with the random salt and multiple
+        // iterations and then Base64-encode the value (requires less space than Hex):
+        final String hashedPasswordBase64 = new Sha256Hash(entity.getApiSecret(), salt, 1024).toBase64();
+
+        tenantSqlDao.create(entity, hashedPasswordBase64, salt.toBase64(), context);
+    }
+
+    @Override
+    public Long getRecordId(final UUID id, final InternalTenantContext context) {
+        return tenantSqlDao.getRecordId(id.toString(), context);
+    }
+
+    @Override
+    public Tenant getById(final UUID id, final InternalTenantContext context) {
+        return tenantSqlDao.getById(id.toString(), context);
+    }
+
+    @Override
+    public List<Tenant> get(final InternalTenantContext context) {
+        return tenantSqlDao.get(context);
+    }
+
+    @Override
+    public void test(final InternalTenantContext context) {
+        tenantSqlDao.test(context);
+    }
+
+    @VisibleForTesting
+    AuthenticationInfo getAuthenticationInfoForTenant(final UUID id) {
+        return tenantSqlDao.getSecrets(id.toString()).toAuthenticationInfo();
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantDao.java
new file mode 100644
index 0000000..88e956f
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantDao.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.util.entity.dao.EntityDao;
+
+public interface TenantDao extends EntityDao<Tenant> {
+
+    public Tenant getTenantByApiKey(String key);
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantMapper.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantMapper.java
new file mode 100644
index 0000000..8c53237
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantMapper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.tenant.api.DefaultTenant;
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.util.dao.MapperBase;
+
+public class TenantMapper extends MapperBase implements ResultSetMapper<Tenant> {
+
+    @Override
+    public Tenant map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
+        final UUID id = getUUID(result, "id");
+        final String externalKey = result.getString("external_key");
+        final String apiKey = result.getString("api_key");
+
+        return new DefaultTenant(id, externalKey, apiKey, null);
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecrets.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecrets.java
new file mode 100644
index 0000000..9fafb5b
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecrets.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.codec.Base64;
+import org.apache.shiro.util.ByteSource;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.util.dao.MapperBase;
+
+/**
+ * Not exposed in the APIs - mainly for testing
+ */
+public final class TenantSecrets {
+
+    private final String apiKey;
+    // Encrypted secret
+    private final String apiSecret;
+    private final String apiSalt;
+
+   public TenantSecrets(final String apiKey, final String apiSecret, final String apiSalt) {
+        this.apiKey = apiKey;
+        this.apiSecret = apiSecret;
+        this.apiSalt = apiSalt;
+    }
+
+    public AuthenticationInfo toAuthenticationInfo() {
+        final SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(apiKey, apiSecret.toCharArray(), getClass().getSimpleName());
+        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(Base64.decode(apiSalt)));
+        return authenticationInfo;
+    }
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    public String getApiSecret() {
+        return apiSecret;
+    }
+
+    public String getApiSalt() {
+        return apiSalt;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("TenantSecrets");
+        sb.append("{apiKey='").append(apiKey).append('\'');
+        // Don't print the secret nor salt
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final TenantSecrets that = (TenantSecrets) o;
+
+        if (apiKey != null ? !apiKey.equals(that.apiKey) : that.apiKey != null) {
+            return false;
+        }
+        if (apiSalt != null ? !apiSalt.equals(that.apiSalt) : that.apiSalt != null) {
+            return false;
+        }
+        if (apiSecret != null ? !apiSecret.equals(that.apiSecret) : that.apiSecret != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = apiKey != null ? apiKey.hashCode() : 0;
+        result = 31 * result + (apiSecret != null ? apiSecret.hashCode() : 0);
+        result = 31 * result + (apiSalt != null ? apiSalt.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecretsMapper.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecretsMapper.java
new file mode 100644
index 0000000..a6da298
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSecretsMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.util.dao.MapperBase;
+
+public class TenantSecretsMapper extends MapperBase implements ResultSetMapper<TenantSecrets> {
+
+    @Override
+    public TenantSecrets map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new TenantSecrets(r.getString("api_key"), r.getString("api_secret"), r.getString("api_salt"));
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSqlDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSqlDao.java
new file mode 100644
index 0000000..4841707
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantSqlDao.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.tenant.api.Tenant;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
+import com.ning.billing.util.dao.UuidMapper;
+import com.ning.billing.util.entity.dao.EntitySqlDao;
+
+@ExternalizedSqlViaStringTemplate3
+@RegisterMapper({UuidMapper.class, TenantMapper.class})
+public interface TenantSqlDao extends EntitySqlDao<Tenant>, Transactional<TenantSqlDao>, Transmogrifier {
+
+    @SqlQuery
+    public Tenant getByApiKey(@Bind("apiKey") final String apiKey);
+
+    @SqlUpdate
+    public void create(@TenantBinder final Tenant tenant,
+                       @Bind("apiSecret") final String apiSecret,
+                       @Bind("apiSalt") final String apiSalt,
+                       @InternalTenantContextBinder final InternalCallContext context);
+
+    @SqlQuery
+    @Mapper(TenantSecretsMapper.class)
+    public TenantSecrets getSecrets(@Bind("id") final String id);
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/glue/TenantModule.java b/tenant/src/main/java/com/ning/billing/tenant/glue/TenantModule.java
new file mode 100644
index 0000000..d44bc00
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/glue/TenantModule.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.glue;
+
+import com.ning.billing.tenant.api.DefaultTenantService;
+import com.ning.billing.tenant.api.TenantService;
+import com.ning.billing.tenant.api.TenantUserApi;
+import com.ning.billing.tenant.api.user.DefaultTenantUserApi;
+import com.ning.billing.tenant.dao.DefaultTenantDao;
+import com.ning.billing.tenant.dao.TenantDao;
+
+import com.google.inject.AbstractModule;
+
+public class TenantModule extends AbstractModule {
+
+    private void installConfig() {
+    }
+
+    protected void installTenantDao() {
+        bind(TenantDao.class).to(DefaultTenantDao.class).asEagerSingleton();
+    }
+
+    protected void installTenantUserApi() {
+        bind(TenantUserApi.class).to(DefaultTenantUserApi.class).asEagerSingleton();
+    }
+
+    private void installTenantService() {
+        bind(TenantService.class).to(DefaultTenantService.class).asEagerSingleton();
+    }
+
+    @Override
+    protected void configure() {
+        installConfig();
+        installTenantDao();
+        installTenantService();
+        installTenantUserApi();
+    }
+}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java b/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java
new file mode 100644
index 0000000..eb91eec
--- /dev/null
+++ b/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.security;
+
+import org.apache.shiro.authc.credential.CredentialsMatcher;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+
+public class KillbillCredentialsMatcher {
+
+    private KillbillCredentialsMatcher() {
+    }
+
+    public static CredentialsMatcher getCredentialsMatcher() {
+        // This needs to be in sync with DefaultTenantDao
+        final HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME);
+        // base64 encoding, not hex
+        credentialsMatcher.setStoredCredentialsHexEncoded(false);
+        credentialsMatcher.setHashIterations(1024);
+
+        return credentialsMatcher;
+    }
+}
diff --git a/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantSqlDao.sql.stg b/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantSqlDao.sql.stg
new file mode 100644
index 0000000..d48780a
--- /dev/null
+++ b/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantSqlDao.sql.stg
@@ -0,0 +1,63 @@
+group TenantDaoSql;
+
+tenantFields(prefix) ::= <<
+    <prefix>record_id,
+    <prefix>id,
+    <prefix>external_key,
+    <prefix>api_key,
+    <prefix>created_date,
+    <prefix>created_by,
+    <prefix>updated_date,
+    <prefix>updated_by
+>>
+
+create() ::= <<
+    INSERT INTO tenants (
+        id
+      , external_key
+      , api_key
+      , api_secret
+      , api_salt
+      , created_date
+      , created_by
+      , updated_date
+      , updated_by
+    ) VALUES (
+        :id
+      , :externalKey
+      , :apiKey
+      , :apiSecret
+      , :apiSalt
+      , :createdDate
+      , :userName
+      , :updatedDate
+      , :userName
+    );
+>>
+
+get() ::= <<
+    SELECT <tenantFields()>
+    FROM tenants;
+>>
+
+getById() ::= <<
+    SELECT <tenantFields()>
+    FROM tenants
+    WHERE id = :id;
+>>
+
+getByApiKey() ::= <<
+    SELECT <tenantFields()>
+    FROM tenants
+    WHERE api_key = :apiKey;
+>>
+
+getSecrets() ::= <<
+    SELECT api_key, api_secret, api_salt
+    FROM tenants
+    WHERE id = :id;
+>>
+
+test() ::= <<
+    SELECT 1 FROM tenants;
+>>
diff --git a/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql b/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql
new file mode 100644
index 0000000..f4e76e0
--- /dev/null
+++ b/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS tenants;
+CREATE TABLE tenants (
+    record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+    id char(36) NOT NULL,
+    external_key varchar(128) NULL,
+    api_key varchar(128) NULL,
+    api_secret varchar(128) NULL,
+    api_salt varchar(128) NULL,
+    created_date datetime NOT NULL,
+    created_by varchar(50) NOT NULL,
+    updated_date datetime DEFAULT NULL,
+    updated_by varchar(50) DEFAULT NULL,
+    PRIMARY KEY(record_id)
+) ENGINE=innodb;
+CREATE UNIQUE INDEX tenants_id ON tenants(id);
+CREATE UNIQUE INDEX tenants_api_key ON tenants(api_key);
diff --git a/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java b/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java
new file mode 100644
index 0000000..ad51b08
--- /dev/null
+++ b/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant.dao;
+
+import java.util.UUID;
+
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.tenant.TenantTestSuiteWithEmbeddedDb;
+import com.ning.billing.tenant.api.DefaultTenant;
+import com.ning.billing.tenant.security.KillbillCredentialsMatcher;
+import com.ning.billing.util.bus.Bus;
+
+public class TestDefaultTenantDao extends TenantTestSuiteWithEmbeddedDb {
+
+    @Test(groups = "slow")
+    public void testWeCanStoreAndMatchCredentials() throws Exception {
+        final DefaultTenantDao tenantDao = new DefaultTenantDao(getMysqlTestingHelper().getDBI(), Mockito.mock(Bus.class));
+
+        final DefaultTenant tenant = new DefaultTenant(UUID.randomUUID(), UUID.randomUUID().toString(),
+                                                       UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        tenantDao.create(tenant, internalCallContext);
+
+        // Verify we can retrieve it
+        Assert.assertEquals(tenantDao.getTenantByApiKey(tenant.getApiKey()).getId(), tenant.getId());
+
+        // Verify we can authenticate against it
+        final AuthenticationInfo authenticationInfo = tenantDao.getAuthenticationInfoForTenant(tenant.getId());
+
+        // Good combo
+        final AuthenticationToken goodToken = new UsernamePasswordToken(tenant.getApiKey(), tenant.getApiSecret());
+        Assert.assertTrue(KillbillCredentialsMatcher.getCredentialsMatcher().doCredentialsMatch(goodToken, authenticationInfo));
+
+        // Bad combo
+        final AuthenticationToken badToken = new UsernamePasswordToken(tenant.getApiKey(), tenant.getApiSecret() + "T");
+        Assert.assertFalse(KillbillCredentialsMatcher.getCredentialsMatcher().doCredentialsMatch(badToken, authenticationInfo));
+    }
+}
diff --git a/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuite.java b/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuite.java
new file mode 100644
index 0000000..b011d37
--- /dev/null
+++ b/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuite.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant;
+
+import com.ning.billing.KillbillTestSuite;
+
+public class TenantTestSuite extends KillbillTestSuite {
+
+}
diff --git a/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuiteWithEmbeddedDb.java b/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuiteWithEmbeddedDb.java
new file mode 100644
index 0000000..276002d
--- /dev/null
+++ b/tenant/src/test/java/com/ning/billing/tenant/TenantTestSuiteWithEmbeddedDb.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.tenant;
+
+import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
+
+public class TenantTestSuiteWithEmbeddedDb extends KillbillTestSuiteWithEmbeddedDB {
+
+}
diff --git a/usage/src/main/java/com/ning/billing/usage/api/user/DefaultUsageUserApi.java b/usage/src/main/java/com/ning/billing/usage/api/user/DefaultUsageUserApi.java
index 8f1e6a9..639bd9f 100644
--- a/usage/src/main/java/com/ning/billing/usage/api/user/DefaultUsageUserApi.java
+++ b/usage/src/main/java/com/ning/billing/usage/api/user/DefaultUsageUserApi.java
@@ -22,9 +22,15 @@ import javax.inject.Inject;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.usage.api.UsageUserApi;
 import com.ning.billing.usage.dao.RolledUpUsageDao;
 import com.ning.billing.usage.timeline.TimelineEventHandler;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
 import com.google.common.collect.ImmutableMap;
@@ -35,30 +41,46 @@ public class DefaultUsageUserApi implements UsageUserApi {
 
     private final RolledUpUsageDao rolledUpUsageDao;
     private final TimelineEventHandler timelineEventHandler;
+    private final EntitlementUserApi entitlementUserApi;
     private final Clock clock;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultUsageUserApi(final RolledUpUsageDao rolledUpUsageDao, final TimelineEventHandler timelineEventHandler, final Clock clock) {
+    public DefaultUsageUserApi(final RolledUpUsageDao rolledUpUsageDao,
+                               final TimelineEventHandler timelineEventHandler,
+                               final EntitlementUserApi entitlementUserApi,
+                               final Clock clock,
+                               final InternalCallContextFactory internalCallContextFactory) {
         this.rolledUpUsageDao = rolledUpUsageDao;
         this.timelineEventHandler = timelineEventHandler;
+        this.entitlementUserApi = entitlementUserApi;
         this.clock = clock;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public void incrementUsage(final UUID bundleId, final String metricName) {
-        recordUsage(bundleId, metricName, clock.getUTCNow(), 1);
+    public void incrementUsage(final UUID bundleId, final String metricName, final CallContext context) throws EntitlementUserApiException {
+        recordUsage(bundleId, metricName, clock.getUTCNow(), 1, context);
     }
 
     @Override
-    public void recordUsage(final UUID bundleId, final String metricName, final DateTime timestamp, final long value) {
+    public void recordUsage(final UUID bundleId, final String metricName, final DateTime timestamp, final long value, final CallContext context) throws EntitlementUserApiException {
         final String sourceName = getSourceNameFromBundleId(bundleId);
-        timelineEventHandler.record(sourceName, DEFAULT_EVENT_TYPE, timestamp, ImmutableMap.<String, Object>of(metricName, value));
+        timelineEventHandler.record(sourceName, DEFAULT_EVENT_TYPE, timestamp, ImmutableMap.<String, Object>of(metricName, value), createInternalCallContext(bundleId, context));
     }
 
     @Override
-    public void recordRolledUpUsage(final UUID bundleId, final String metricName, final DateTime startDate, final DateTime endDate, final long value) {
+    public void recordRolledUpUsage(final UUID bundleId, final String metricName, final DateTime startDate, final DateTime endDate,
+                                    final long value, final CallContext context) throws EntitlementUserApiException {
         final String sourceName = getSourceNameFromBundleId(bundleId);
-        rolledUpUsageDao.record(sourceName, DEFAULT_EVENT_TYPE, metricName, startDate, endDate, value);
+
+        rolledUpUsageDao.record(sourceName, DEFAULT_EVENT_TYPE, metricName, startDate, endDate, value, createInternalCallContext(bundleId, context));
+    }
+
+    private InternalCallContext createInternalCallContext(final UUID bundleId, final CallContext context) throws EntitlementUserApiException {
+        // Retrieve the bundle to get the account id for the internal call context
+        final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId, context);
+        return internalCallContextFactory.createInternalCallContext(bundle.getAccountId(), context);
     }
 
     private String getSourceNameFromBundleId(final UUID bundleId) {
diff --git a/usage/src/main/java/com/ning/billing/usage/dao/DefaultRolledUpUsageDao.java b/usage/src/main/java/com/ning/billing/usage/dao/DefaultRolledUpUsageDao.java
index 58e3dce..c4bd958 100644
--- a/usage/src/main/java/com/ning/billing/usage/dao/DefaultRolledUpUsageDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/dao/DefaultRolledUpUsageDao.java
@@ -23,6 +23,7 @@ import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 
 import com.ning.billing.usage.timeline.persistent.TimelineSqlDao;
+import com.ning.billing.util.callcontext.InternalCallContext;
 
 public class DefaultRolledUpUsageDao implements RolledUpUsageDao {
 
@@ -34,34 +35,35 @@ public class DefaultRolledUpUsageDao implements RolledUpUsageDao {
     }
 
     @Override
-    public void record(final String source, final String eventType, final String metricName, final DateTime startDate, final DateTime endDate, final long value) {
+    public void record(final String source, final String eventType, final String metricName, final DateTime startDate,
+                       final DateTime endDate, final long value, final InternalCallContext context) {
         rolledUpUsageSqlDao.inTransaction(new Transaction<Void, RolledUpUsageSqlDao>() {
             @Override
             public Void inTransaction(final RolledUpUsageSqlDao transactional, final TransactionStatus status) throws Exception {
                 final TimelineSqlDao timelineSqlDao = transactional.become(TimelineSqlDao.class);
 
                 // Create the source if it doesn't exist
-                Integer sourceId = timelineSqlDao.getSourceId(source);
+                Integer sourceId = timelineSqlDao.getSourceId(source, context);
                 if (sourceId == null) {
-                    timelineSqlDao.addSource(source);
-                    sourceId = timelineSqlDao.getSourceId(source);
+                    timelineSqlDao.addSource(source, context);
+                    sourceId = timelineSqlDao.getSourceId(source, context);
                 }
 
                 // Create the category if it doesn't exist
-                Integer categoryId = timelineSqlDao.getEventCategoryId(eventType);
+                Integer categoryId = timelineSqlDao.getEventCategoryId(eventType, context);
                 if (categoryId == null) {
-                    timelineSqlDao.addEventCategory(eventType);
-                    categoryId = timelineSqlDao.getEventCategoryId(eventType);
+                    timelineSqlDao.addEventCategory(eventType, context);
+                    categoryId = timelineSqlDao.getEventCategoryId(eventType, context);
                 }
 
                 // Create the metric if it doesn't exist
-                Integer metricId = timelineSqlDao.getMetricId(categoryId, metricName);
+                Integer metricId = timelineSqlDao.getMetricId(categoryId, metricName, context);
                 if (metricId == null) {
-                    timelineSqlDao.addMetric(categoryId, metricName);
-                    metricId = timelineSqlDao.getMetricId(categoryId, metricName);
+                    timelineSqlDao.addMetric(categoryId, metricName, context);
+                    metricId = timelineSqlDao.getMetricId(categoryId, metricName, context);
                 }
 
-                transactional.record(sourceId, metricId, startDate.toDate(), endDate.toDate(), value);
+                transactional.record(sourceId, metricId, startDate.toDate(), endDate.toDate(), value, context);
 
                 return null;
             }
diff --git a/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageDao.java b/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageDao.java
index a75a882..25419d4 100644
--- a/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageDao.java
@@ -18,11 +18,14 @@ package com.ning.billing.usage.dao;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
+
 /**
  * Dao to record already rolled-up usage data (rolled-up by the user).
  * For raw tracking of the data, @see TimelineEventHandler.
  */
 public interface RolledUpUsageDao {
 
-    public void record(final String sourceName, final String eventType, final String metricName, final DateTime startDate, final DateTime endDate, final long value);
+    public void record(final String sourceName, final String eventType, final String metricName, final DateTime startDate,
+                       final DateTime endDate, final long value, final InternalCallContext context);
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageSqlDao.java b/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageSqlDao.java
index b495535..52db57c 100644
--- a/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageSqlDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/dao/RolledUpUsageSqlDao.java
@@ -24,11 +24,17 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
+
 @ExternalizedSqlViaStringTemplate3()
 public interface RolledUpUsageSqlDao extends Transactional<RolledUpUsageSqlDao>, Transmogrifier {
 
     @SqlUpdate
-    public void record(@Bind("sourceId") final int sourceId, @Bind("metricId") final int metricId,
-                       @Bind("startTime") final Date startTime, @Bind("endTime") final Date endTime,
-                       @Bind("value") final long value);
+    public void record(@Bind("sourceId") final int sourceId,
+                       @Bind("metricId") final int metricId,
+                       @Bind("startTime") final Date startTime,
+                       @Bind("endTime") final Date endTime,
+                       @Bind("value") final long value,
+                       @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/glue/CachingDefaultTimelineDaoProvider.java b/usage/src/main/java/com/ning/billing/usage/glue/CachingDefaultTimelineDaoProvider.java
index 6e53a63..d95d0af 100644
--- a/usage/src/main/java/com/ning/billing/usage/glue/CachingDefaultTimelineDaoProvider.java
+++ b/usage/src/main/java/com/ning/billing/usage/glue/CachingDefaultTimelineDaoProvider.java
@@ -23,16 +23,19 @@ import org.skife.jdbi.v2.DBI;
 import com.ning.billing.usage.timeline.persistent.CachingTimelineDao;
 import com.ning.billing.usage.timeline.persistent.DefaultTimelineDao;
 import com.ning.billing.usage.timeline.persistent.TimelineDao;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 
 import com.google.inject.Inject;
 
 public class CachingDefaultTimelineDaoProvider implements Provider<TimelineDao> {
 
     private final DBI dbi;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public CachingDefaultTimelineDaoProvider(final DBI dbi) {
+    public CachingDefaultTimelineDaoProvider(final DBI dbi, final InternalCallContextFactory internalCallContextFactory) {
         this.dbi = dbi;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/aggregator/TimelineAggregator.java b/usage/src/main/java/com/ning/billing/usage/timeline/aggregator/TimelineAggregator.java
index ad0b3bc..6d272aa 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/aggregator/TimelineAggregator.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/aggregator/TimelineAggregator.java
@@ -44,6 +44,10 @@ import com.ning.billing.usage.timeline.codec.SampleCoder;
 import com.ning.billing.usage.timeline.consumer.TimelineChunkConsumer;
 import com.ning.billing.usage.timeline.persistent.DefaultTimelineDao;
 import com.ning.billing.usage.timeline.times.TimelineCoder;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 
 import com.google.inject.Inject;
 
@@ -63,6 +67,8 @@ public class TimelineAggregator {
     private final UsageConfig config;
     private final TimelineAggregatorSqlDao aggregatorSqlDao;
     private final TimelineChunkMapper timelineChunkMapper;
+    private final InternalCallContextFactory internalCallContextFactory;
+
     private final ScheduledExecutorService aggregatorThread = Executors.newSingleThreadScheduledExecutor();
 
     private Map<String, AtomicLong> aggregatorCounters = new LinkedHashMap<String, AtomicLong>();
@@ -88,7 +94,8 @@ public class TimelineAggregator {
     private final List<Long> chunkIdsToInvalidateOrDelete = new ArrayList<Long>();
 
     @Inject
-    public TimelineAggregator(final IDBI dbi, final DefaultTimelineDao timelineDao, final TimelineCoder timelineCoder, final SampleCoder sampleCoder, final UsageConfig config) {
+    public TimelineAggregator(final IDBI dbi, final DefaultTimelineDao timelineDao, final TimelineCoder timelineCoder,
+                              final SampleCoder sampleCoder, final UsageConfig config, final InternalCallContextFactory internalCallContextFactory) {
         this.dbi = dbi;
         this.timelineDao = timelineDao;
         this.timelineCoder = timelineCoder;
@@ -96,6 +103,7 @@ public class TimelineAggregator {
         this.config = config;
         this.aggregatorSqlDao = dbi.onDemand(TimelineAggregatorSqlDao.class);
         this.timelineChunkMapper = new TimelineChunkMapper();
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     private int aggregateTimelineCandidates(final List<TimelineChunk> timelineChunkCandidates, final int aggregationLevel, final int chunksToAggregate) {
@@ -181,7 +189,7 @@ public class TimelineAggregator {
         // or invalidate the ones that were aggregated.  This should be very fast.
         final long startWriteTime = System.currentTimeMillis();
         aggregatorSqlDao.begin();
-        timelineDao.bulkInsertTimelineChunks(chunksToWrite);
+        timelineDao.bulkInsertTimelineChunks(chunksToWrite, createCallContext());
         if (config.getDeleteAggregatedChunks()) {
             aggregatorSqlDao.deleteTimelineChunks(chunkIdsToInvalidateOrDelete);
         } else {
@@ -416,4 +424,8 @@ public class TimelineAggregator {
             }
         });
     }
+
+    private InternalCallContext createCallContext() {
+        return internalCallContextFactory.createInternalCallContext("TimelineAggregator", CallOrigin.INTERNAL, UserType.SYSTEM, null);
+    }
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/BackgroundDBChunkWriter.java b/usage/src/main/java/com/ning/billing/usage/timeline/BackgroundDBChunkWriter.java
index a7ab352..3c4a786 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/BackgroundDBChunkWriter.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/BackgroundDBChunkWriter.java
@@ -34,6 +34,10 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.config.UsageConfig;
 import com.ning.billing.usage.timeline.chunks.TimelineChunk;
 import com.ning.billing.usage.timeline.persistent.TimelineDao;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -57,6 +61,7 @@ public class BackgroundDBChunkWriter {
     private final TimelineDao timelineDAO;
     private final UsageConfig config;
     private final boolean performForegroundWrites;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private final AtomicInteger pendingChunkCount = new AtomicInteger();
     private final AtomicBoolean shuttingDown = new AtomicBoolean();
@@ -76,14 +81,16 @@ public class BackgroundDBChunkWriter {
     private final AtomicLong foregroundChunksWritten = new AtomicLong();
 
     @Inject
-    public BackgroundDBChunkWriter(final TimelineDao timelineDAO, final UsageConfig config) {
-        this(timelineDAO, config, config.getPerformForegroundWrites());
+    public BackgroundDBChunkWriter(final TimelineDao timelineDAO, final UsageConfig config, final InternalCallContextFactory internalCallContextFactory) {
+        this(timelineDAO, config, config.getPerformForegroundWrites(), internalCallContextFactory);
     }
 
-    public BackgroundDBChunkWriter(final TimelineDao timelineDAO, @Nullable final UsageConfig config, final boolean performForegroundWrites) {
+    public BackgroundDBChunkWriter(final TimelineDao timelineDAO, @Nullable final UsageConfig config,
+                                   final boolean performForegroundWrites, final InternalCallContextFactory internalCallContextFactory) {
         this.timelineDAO = timelineDAO;
         this.config = config;
         this.performForegroundWrites = performForegroundWrites;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     public synchronized void addPendingChunkMap(final PendingChunkMap chunkMap) {
@@ -94,7 +101,7 @@ public class BackgroundDBChunkWriter {
                 foregroundChunkMapsWritten.incrementAndGet();
                 final List<TimelineChunk> chunksToWrite = new ArrayList<TimelineChunk>(chunkMap.getChunkMap().values());
                 foregroundChunksWritten.addAndGet(chunksToWrite.size());
-                timelineDAO.bulkInsertTimelineChunks(chunksToWrite);
+                timelineDAO.bulkInsertTimelineChunks(chunksToWrite, createCallContext());
                 chunkMap.getAccumulator().markPendingChunkMapConsumed(chunkMap.getPendingChunkMapId());
             } else {
                 pendingChunkMapsAdded.incrementAndGet();
@@ -120,7 +127,7 @@ public class BackgroundDBChunkWriter {
             pendingChunksWritten.addAndGet(map.getChunkMap().size());
             chunks.addAll(map.getChunkMap().values());
         }
-        timelineDAO.bulkInsertTimelineChunks(chunks);
+        timelineDAO.bulkInsertTimelineChunks(chunks, createCallContext());
         for (final PendingChunkMap map : chunkMapsToWrite) {
             pendingChunkMapsMarkedConsumed.incrementAndGet();
             map.getAccumulator().markPendingChunkMapConsumed(map.getPendingChunkMapId());
@@ -214,4 +221,8 @@ public class BackgroundDBChunkWriter {
     public long getForegroundChunksWritten() {
         return foregroundChunksWritten.get();
     }
+
+    private InternalCallContext createCallContext() {
+        return internalCallContextFactory.createInternalCallContext("ChunkWriter", CallOrigin.INTERNAL, UserType.SYSTEM, null);
+    }
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/CachingTimelineDao.java b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/CachingTimelineDao.java
index e6d74d7..67334cb 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/CachingTimelineDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/CachingTimelineDao.java
@@ -35,6 +35,8 @@ import com.ning.billing.usage.timeline.chunks.TimelineChunk;
 import com.ning.billing.usage.timeline.consumer.TimelineChunkConsumer;
 import com.ning.billing.usage.timeline.shutdown.StartTimes;
 import com.ning.billing.usage.timeline.sources.SourceIdAndMetricId;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.common.collect.BiMap;
 import com.google.common.collect.ImmutableList;
@@ -52,11 +54,13 @@ public class CachingTimelineDao implements TimelineDao {
 
     public CachingTimelineDao(final TimelineDao delegate) {
         this.delegate = delegate;
-        sourcesCache = delegate.getSources();
-        metricsCache = delegate.getMetrics();
-        eventCategoriesCache = delegate.getEventCategories();
+        // TODO - rethink priming with tenants
+        final InternalTenantContext context = new InternalTenantContext(null, null);
+        sourcesCache = delegate.getSources(context);
+        metricsCache = delegate.getMetrics(context);
+        eventCategoriesCache = delegate.getEventCategories(context);
         sourceIdsMetricIdsCache = new HashMap<Integer, Set<Integer>>();
-        for (final SourceIdAndMetricId both : delegate.getMetricIdsForAllSources()) {
+        for (final SourceIdAndMetricId both : delegate.getMetricIdsForAllSources(context)) {
             final int sourceId = both.getSourceId();
             final int metricId = both.getMetricId();
             Set<Integer> metricIds = sourceIdsMetricIdsCache.get(sourceId);
@@ -69,25 +73,25 @@ public class CachingTimelineDao implements TimelineDao {
     }
 
     @Override
-    public Integer getSourceId(final String source) throws UnableToObtainConnectionException, CallbackFailedException {
+    public Integer getSourceId(final String source, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         return sourcesCache.inverse().get(source);
     }
 
     @Override
-    public String getSource(final Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException {
+    public String getSource(final Integer sourceId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         return sourcesCache.get(sourceId);
     }
 
     @Override
-    public BiMap<Integer, String> getSources() throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getSources();
+    public BiMap<Integer, String> getSources(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getSources(context);
     }
 
     @Override
-    public synchronized int getOrAddSource(final String source) throws UnableToObtainConnectionException, CallbackFailedException {
+    public synchronized int getOrAddSource(final String source, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         Integer sourceId = sourcesCache.inverse().get(source);
         if (sourceId == null) {
-            sourceId = delegate.getOrAddSource(source);
+            sourceId = delegate.getOrAddSource(source, context);
             sourcesCache.put(sourceId, source);
         }
 
@@ -95,51 +99,51 @@ public class CachingTimelineDao implements TimelineDao {
     }
 
     @Override
-    public Integer getEventCategoryId(final String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException {
+    public Integer getEventCategoryId(final String eventCategory, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         return eventCategoriesCache.inverse().get(eventCategory);
     }
 
     @Override
-    public String getEventCategory(final Integer eventCategoryId) throws UnableToObtainConnectionException {
+    public String getEventCategory(final Integer eventCategoryId, final InternalTenantContext context) throws UnableToObtainConnectionException {
         return eventCategoriesCache.get(eventCategoryId);
     }
 
     @Override
-    public BiMap<Integer, String> getEventCategories() throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getEventCategories();
+    public BiMap<Integer, String> getEventCategories(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getEventCategories(context);
     }
 
     @Override
-    public int getOrAddEventCategory(final String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException {
+    public int getOrAddEventCategory(final String eventCategory, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         Integer eventCategoryId = eventCategoriesCache.inverse().get(eventCategory);
         if (eventCategoryId == null) {
-            eventCategoryId = delegate.getOrAddEventCategory(eventCategory);
+            eventCategoryId = delegate.getOrAddEventCategory(eventCategory, context);
             eventCategoriesCache.put(eventCategoryId, eventCategory);
         }
         return eventCategoryId;
     }
 
     @Override
-    public Integer getMetricId(final int eventCategoryId, final String metric) throws UnableToObtainConnectionException {
+    public Integer getMetricId(final int eventCategoryId, final String metric, final InternalTenantContext context) throws UnableToObtainConnectionException {
         return metricsCache.inverse().get(new CategoryIdAndMetric(eventCategoryId, metric));
     }
 
     @Override
-    public CategoryIdAndMetric getCategoryIdAndMetric(final Integer metricId) throws UnableToObtainConnectionException {
+    public CategoryIdAndMetric getCategoryIdAndMetric(final Integer metricId, final InternalTenantContext context) throws UnableToObtainConnectionException {
         return metricsCache.get(metricId);
     }
 
     @Override
-    public BiMap<Integer, CategoryIdAndMetric> getMetrics() throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getMetrics();
+    public BiMap<Integer, CategoryIdAndMetric> getMetrics(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getMetrics(context);
     }
 
     @Override
-    public synchronized int getOrAddMetric(final Integer sourceId, final Integer eventCategoryId, final String metric) throws UnableToObtainConnectionException, CallbackFailedException {
+    public synchronized int getOrAddMetric(final Integer sourceId, final Integer eventCategoryId, final String metric, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         final CategoryIdAndMetric categoryIdAndMetric = new CategoryIdAndMetric(eventCategoryId, metric);
         Integer metricId = metricsCache.inverse().get(categoryIdAndMetric);
         if (metricId == null) {
-            metricId = delegate.getOrAddMetric(sourceId, eventCategoryId, metric);
+            metricId = delegate.getOrAddMetric(sourceId, eventCategoryId, metric, context);
             metricsCache.put(metricId, categoryIdAndMetric);
         }
         if (sourceId != null) {
@@ -154,64 +158,64 @@ public class CachingTimelineDao implements TimelineDao {
     }
 
     @Override
-    public Iterable<Integer> getMetricIdsBySourceId(final Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException {
+    public Iterable<Integer> getMetricIdsBySourceId(final Integer sourceId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         return ImmutableList.copyOf(sourceIdsMetricIdsCache.get(sourceId));
     }
 
     @Override
-    public Iterable<SourceIdAndMetricId> getMetricIdsForAllSources() throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getMetricIdsForAllSources();
+    public Iterable<SourceIdAndMetricId> getMetricIdsForAllSources(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getMetricIdsForAllSources(context);
     }
 
-
     @Override
-    public Long insertTimelineChunk(final TimelineChunk timelineChunk) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.insertTimelineChunk(timelineChunk);
+    public Long insertTimelineChunk(final TimelineChunk timelineChunk, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.insertTimelineChunk(timelineChunk, context);
     }
 
     @Override
     public void getSamplesBySourceIdsAndMetricIds(final List<Integer> sourceIds, @Nullable final List<Integer> metricIds,
-                                                  final DateTime startTime, final DateTime endTime, final TimelineChunkConsumer chunkConsumer) throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.getSamplesBySourceIdsAndMetricIds(sourceIds, metricIds, startTime, endTime, chunkConsumer);
+                                                  final DateTime startTime, final DateTime endTime,
+                                                  final TimelineChunkConsumer chunkConsumer, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.getSamplesBySourceIdsAndMetricIds(sourceIds, metricIds, startTime, endTime, chunkConsumer, context);
     }
 
     @Override
-    public Integer insertLastStartTimes(final StartTimes startTimes) {
-        return delegate.insertLastStartTimes(startTimes);
+    public Integer insertLastStartTimes(final StartTimes startTimes, final InternalCallContext context) {
+        return delegate.insertLastStartTimes(startTimes, context);
     }
 
     @Override
-    public StartTimes getLastStartTimes() {
-        return delegate.getLastStartTimes();
+    public StartTimes getLastStartTimes(final InternalTenantContext context) {
+        return delegate.getLastStartTimes(context);
     }
 
     @Override
-    public void deleteLastStartTimes() {
-        delegate.deleteLastStartTimes();
+    public void deleteLastStartTimes(final InternalCallContext context) {
+        delegate.deleteLastStartTimes(context);
     }
 
     @Override
-    public void bulkInsertEventCategories(final List<String> categoryNames) throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.bulkInsertEventCategories(categoryNames);
+    public void bulkInsertEventCategories(final List<String> categoryNames, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.bulkInsertEventCategories(categoryNames, context);
     }
 
     @Override
-    public void bulkInsertSources(final List<String> sources) throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.bulkInsertSources(sources);
+    public void bulkInsertSources(final List<String> sources, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.bulkInsertSources(sources, context);
     }
 
     @Override
-    public void bulkInsertMetrics(final List<CategoryIdAndMetric> categoryAndKinds) {
-        delegate.bulkInsertMetrics(categoryAndKinds);
+    public void bulkInsertMetrics(final List<CategoryIdAndMetric> categoryAndKinds, final InternalCallContext context) {
+        delegate.bulkInsertMetrics(categoryAndKinds, context);
     }
 
     @Override
-    public void bulkInsertTimelineChunks(final List<TimelineChunk> timelineChunkList) {
-        delegate.bulkInsertTimelineChunks(timelineChunkList);
+    public void bulkInsertTimelineChunks(final List<TimelineChunk> timelineChunkList, final InternalCallContext context) {
+        delegate.bulkInsertTimelineChunks(timelineChunkList, context);
     }
 
     @Override
-    public void test() throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.test();
+    public void test(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.test(context);
     }
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/DefaultTimelineDao.java b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/DefaultTimelineDao.java
index 37ba9ae..2cbb8d9 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/DefaultTimelineDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/DefaultTimelineDao.java
@@ -40,6 +40,8 @@ import com.ning.billing.usage.timeline.consumer.TimelineChunkConsumer;
 import com.ning.billing.usage.timeline.shutdown.StartTimes;
 import com.ning.billing.usage.timeline.sources.SourceIdAndMetricId;
 import com.ning.billing.usage.timeline.util.DateTimeUtils;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.BiMap;
@@ -63,77 +65,77 @@ public class DefaultTimelineDao implements TimelineDao {
     }
 
     @Override
-    public String getSource(final Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getSource(sourceId);
+    public String getSource(final Integer sourceId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getSource(sourceId, context);
     }
 
     @Override
-    public Integer getSourceId(final String source) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getSourceId(source);
+    public Integer getSourceId(final String source, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getSourceId(source, context);
     }
 
     @Override
-    public BiMap<Integer, String> getSources() throws UnableToObtainConnectionException, CallbackFailedException {
+    public BiMap<Integer, String> getSources(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         final HashBiMap<Integer, String> accumulator = HashBiMap.create();
-        for (final Map<String, Object> metric : delegate.getSources()) {
+        for (final Map<String, Object> metric : delegate.getSources(context)) {
             accumulator.put(Integer.valueOf(metric.get("source_id").toString()), metric.get("source_name").toString());
         }
         return accumulator;
     }
 
     @Override
-    public synchronized int getOrAddSource(final String source) throws UnableToObtainConnectionException, CallbackFailedException {
+    public synchronized int getOrAddSource(final String source, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         delegate.begin();
-        delegate.addSource(source);
-        final Integer sourceId = delegate.getSourceId(source);
+        delegate.addSource(source, context);
+        final Integer sourceId = delegate.getSourceId(source, context);
         delegate.commit();
 
         return sourceId;
     }
 
     @Override
-    public Integer getEventCategoryId(final String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getEventCategoryId(eventCategory);
+    public Integer getEventCategoryId(final String eventCategory, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getEventCategoryId(eventCategory, context);
     }
 
     @Override
-    public String getEventCategory(final Integer eventCategoryId) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getEventCategory(eventCategoryId);
+    public String getEventCategory(final Integer eventCategoryId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getEventCategory(eventCategoryId, context);
     }
 
     @Override
-    public BiMap<Integer, String> getEventCategories() throws UnableToObtainConnectionException, CallbackFailedException {
+    public BiMap<Integer, String> getEventCategories(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         final HashBiMap<Integer, String> accumulator = HashBiMap.create();
-        for (final Map<String, Object> eventCategory : delegate.getEventCategories()) {
+        for (final Map<String, Object> eventCategory : delegate.getEventCategories(context)) {
             accumulator.put(Integer.valueOf(eventCategory.get("event_category_id").toString()), eventCategory.get("event_category").toString());
         }
         return accumulator;
     }
 
     @Override
-    public synchronized int getOrAddEventCategory(final String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException {
+    public synchronized int getOrAddEventCategory(final String eventCategory, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         delegate.begin();
-        delegate.addEventCategory(eventCategory);
-        final Integer eventCategoryId = delegate.getEventCategoryId(eventCategory);
+        delegate.addEventCategory(eventCategory, context);
+        final Integer eventCategoryId = delegate.getEventCategoryId(eventCategory, context);
         delegate.commit();
 
         return eventCategoryId;
     }
 
     @Override
-    public Integer getMetricId(final int eventCategoryId, final String metric) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getMetricId(eventCategoryId, metric);
+    public Integer getMetricId(final int eventCategoryId, final String metric, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getMetricId(eventCategoryId, metric, context);
     }
 
     @Override
-    public CategoryIdAndMetric getCategoryIdAndMetric(final Integer metricId) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getEventCategoryIdAndMetric(metricId);
+    public CategoryIdAndMetric getCategoryIdAndMetric(final Integer metricId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getEventCategoryIdAndMetric(metricId, context);
     }
 
     @Override
-    public BiMap<Integer, CategoryIdAndMetric> getMetrics() throws UnableToObtainConnectionException, CallbackFailedException {
+    public BiMap<Integer, CategoryIdAndMetric> getMetrics(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         final HashBiMap<Integer, CategoryIdAndMetric> accumulator = HashBiMap.create();
-        for (final Map<String, Object> metricInfo : delegate.getMetrics()) {
+        for (final Map<String, Object> metricInfo : delegate.getMetrics(context)) {
             accumulator.put(Integer.valueOf(metricInfo.get("sample_kind_id").toString()),
                             new CategoryIdAndMetric((Integer) metricInfo.get("event_category_id"), metricInfo.get("sample_kind").toString()));
         }
@@ -141,30 +143,30 @@ public class DefaultTimelineDao implements TimelineDao {
     }
 
     @Override
-    public synchronized int getOrAddMetric(final Integer sourceId, final Integer eventCategoryId, final String metric) throws UnableToObtainConnectionException, CallbackFailedException {
+    public synchronized int getOrAddMetric(final Integer sourceId, final Integer eventCategoryId, final String metric, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         delegate.begin();
-        delegate.addMetric(eventCategoryId, metric);
-        final Integer metricId = delegate.getMetricId(eventCategoryId, metric);
+        delegate.addMetric(eventCategoryId, metric, context);
+        final Integer metricId = delegate.getMetricId(eventCategoryId, metric, context);
         delegate.commit();
 
         return metricId;
     }
 
     @Override
-    public Iterable<Integer> getMetricIdsBySourceId(final Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getMetricIdsBySourceId(sourceId);
+    public Iterable<Integer> getMetricIdsBySourceId(final Integer sourceId, final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getMetricIdsBySourceId(sourceId, context);
     }
 
     @Override
-    public Iterable<SourceIdAndMetricId> getMetricIdsForAllSources() throws UnableToObtainConnectionException, CallbackFailedException {
-        return delegate.getMetricIdsForAllSources();
+    public Iterable<SourceIdAndMetricId> getMetricIdsForAllSources(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        return delegate.getMetricIdsForAllSources(context);
     }
 
     @Override
-    public Long insertTimelineChunk(final TimelineChunk timelineChunk) throws UnableToObtainConnectionException, CallbackFailedException {
+    public Long insertTimelineChunk(final TimelineChunk timelineChunk, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
         delegate.begin();
-        delegate.insertTimelineChunk(timelineChunk);
-        final long timelineChunkId = delegate.getLastInsertedId();
+        delegate.insertTimelineChunk(timelineChunk, context);
+        final long timelineChunkId = delegate.getLastInsertedId(context);
         delegate.commit();
         return timelineChunkId;
     }
@@ -174,7 +176,8 @@ public class DefaultTimelineDao implements TimelineDao {
                                                   @Nullable final List<Integer> metricIdList,
                                                   final DateTime startTime,
                                                   final DateTime endTime,
-                                                  final TimelineChunkConsumer chunkConsumer) {
+                                                  final TimelineChunkConsumer chunkConsumer,
+                                                  final InternalTenantContext context) {
         dbi.withHandle(new HandleCallback<Void>() {
             @Override
             public Void withHandle(final Handle handle) throws Exception {
@@ -214,42 +217,42 @@ public class DefaultTimelineDao implements TimelineDao {
     }
 
     @Override
-    public Integer insertLastStartTimes(final StartTimes startTimes) {
-        return delegate.insertLastStartTimes(startTimes);
+    public Integer insertLastStartTimes(final StartTimes startTimes, final InternalCallContext context) {
+        return delegate.insertLastStartTimes(startTimes, context);
     }
 
     @Override
-    public StartTimes getLastStartTimes() {
-        return delegate.getLastStartTimes();
+    public StartTimes getLastStartTimes(final InternalTenantContext context) {
+        return delegate.getLastStartTimes(context);
     }
 
     @Override
-    public void deleteLastStartTimes() {
-        delegate.deleteLastStartTimes();
+    public void deleteLastStartTimes(final InternalCallContext context) {
+        delegate.deleteLastStartTimes(context);
     }
 
     @Override
-    public void test() throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.test();
+    public void test(final InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.test(context);
     }
 
     @Override
-    public void bulkInsertSources(final List<String> sources) throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.bulkInsertSources(sources.iterator());
+    public void bulkInsertSources(final List<String> sources, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.bulkInsertSources(sources.iterator(), context);
     }
 
     @Override
-    public void bulkInsertEventCategories(final List<String> categoryNames) throws UnableToObtainConnectionException, CallbackFailedException {
-        delegate.bulkInsertEventCategories(categoryNames.iterator());
+    public void bulkInsertEventCategories(final List<String> categoryNames, final InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException {
+        delegate.bulkInsertEventCategories(categoryNames.iterator(), context);
     }
 
     @Override
-    public void bulkInsertMetrics(final List<CategoryIdAndMetric> categoryAndKinds) {
-        delegate.bulkInsertMetrics(categoryAndKinds.iterator());
+    public void bulkInsertMetrics(final List<CategoryIdAndMetric> categoryAndKinds, final InternalCallContext context) {
+        delegate.bulkInsertMetrics(categoryAndKinds.iterator(), context);
     }
 
     @Override
-    public void bulkInsertTimelineChunks(final List<TimelineChunk> timelineChunkList) {
-        delegate.bulkInsertTimelineChunks(timelineChunkList.iterator());
+    public void bulkInsertTimelineChunks(final List<TimelineChunk> timelineChunkList, final InternalCallContext context) {
+        delegate.bulkInsertTimelineChunks(timelineChunkList.iterator(), context);
     }
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineDao.java b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineDao.java
index 6cbdb34..d09b215 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineDao.java
@@ -29,6 +29,8 @@ import com.ning.billing.usage.timeline.chunks.TimelineChunk;
 import com.ning.billing.usage.timeline.consumer.TimelineChunkConsumer;
 import com.ning.billing.usage.timeline.shutdown.StartTimes;
 import com.ning.billing.usage.timeline.sources.SourceIdAndMetricId;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.common.collect.BiMap;
 
@@ -36,61 +38,62 @@ public interface TimelineDao {
 
     // Sources table
 
-    Integer getSourceId(String source) throws UnableToObtainConnectionException, CallbackFailedException;
+    Integer getSourceId(String source, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    String getSource(Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException;
+    String getSource(Integer sourceId, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    BiMap<Integer, String> getSources() throws UnableToObtainConnectionException, CallbackFailedException;
+    BiMap<Integer, String> getSources(InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    int getOrAddSource(String source) throws UnableToObtainConnectionException, CallbackFailedException;
+    int getOrAddSource(String source, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
     // Event categories table
 
-    Integer getEventCategoryId(String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException;
+    Integer getEventCategoryId(String eventCategory, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    String getEventCategory(Integer eventCategoryId) throws UnableToObtainConnectionException, CallbackFailedException;
+    String getEventCategory(Integer eventCategoryId, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    BiMap<Integer, String> getEventCategories() throws UnableToObtainConnectionException, CallbackFailedException;
+    BiMap<Integer, String> getEventCategories(InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    int getOrAddEventCategory(String eventCategory) throws UnableToObtainConnectionException, CallbackFailedException;
+    int getOrAddEventCategory(String eventCategory, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
     // Sample kinds table
 
-    Integer getMetricId(int eventCategory, String metric) throws UnableToObtainConnectionException, CallbackFailedException;
+    Integer getMetricId(int eventCategory, String metric, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    CategoryIdAndMetric getCategoryIdAndMetric(Integer metricId) throws UnableToObtainConnectionException, CallbackFailedException;
+    CategoryIdAndMetric getCategoryIdAndMetric(Integer metricId, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    BiMap<Integer, CategoryIdAndMetric> getMetrics() throws UnableToObtainConnectionException, CallbackFailedException;
+    BiMap<Integer, CategoryIdAndMetric> getMetrics(InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    int getOrAddMetric(Integer sourceId, Integer eventCategoryId, String metric) throws UnableToObtainConnectionException, CallbackFailedException;
+    int getOrAddMetric(Integer sourceId, Integer eventCategoryId, String metric, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    Iterable<Integer> getMetricIdsBySourceId(Integer sourceId) throws UnableToObtainConnectionException, CallbackFailedException;
+    Iterable<Integer> getMetricIdsBySourceId(Integer sourceId, InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    Iterable<SourceIdAndMetricId> getMetricIdsForAllSources() throws UnableToObtainConnectionException, CallbackFailedException;
+    Iterable<SourceIdAndMetricId> getMetricIdsForAllSources(InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
     // Timelines tables
 
-    Long insertTimelineChunk(TimelineChunk timelineChunk) throws UnableToObtainConnectionException, CallbackFailedException;
+    Long insertTimelineChunk(TimelineChunk timelineChunk, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
     void getSamplesBySourceIdsAndMetricIds(List<Integer> sourceIds,
                                            @Nullable List<Integer> metricIds,
                                            DateTime startTime,
                                            DateTime endTime,
-                                           TimelineChunkConsumer chunkConsumer) throws UnableToObtainConnectionException, CallbackFailedException;
+                                           TimelineChunkConsumer chunkConsumer,
+                                           InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    Integer insertLastStartTimes(StartTimes startTimes);
+    Integer insertLastStartTimes(StartTimes startTimes, InternalCallContext context);
 
-    StartTimes getLastStartTimes();
+    StartTimes getLastStartTimes(InternalTenantContext context);
 
-    void deleteLastStartTimes();
+    void deleteLastStartTimes(InternalCallContext context);
 
-    void bulkInsertSources(final List<String> sources) throws UnableToObtainConnectionException, CallbackFailedException;
+    void bulkInsertSources(List<String> sources, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    void bulkInsertEventCategories(final List<String> categoryNames) throws UnableToObtainConnectionException, CallbackFailedException;
+    void bulkInsertEventCategories(List<String> categoryNames, InternalCallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 
-    void bulkInsertMetrics(final List<CategoryIdAndMetric> categoryAndKinds);
+    void bulkInsertMetrics(List<CategoryIdAndMetric> categoryAndKinds, InternalCallContext context);
 
-    void bulkInsertTimelineChunks(final List<TimelineChunk> timelineChunkList);
+    void bulkInsertTimelineChunks(List<TimelineChunk> timelineChunkList, InternalCallContext context);
 
-    void test() throws UnableToObtainConnectionException, CallbackFailedException;
+    void test(InternalTenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.java b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.java
index ce6c5bd..3529020 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.java
@@ -42,90 +42,111 @@ import com.ning.billing.usage.timeline.shutdown.StartTimesBinder;
 import com.ning.billing.usage.timeline.shutdown.StartTimesMapper;
 import com.ning.billing.usage.timeline.sources.SourceIdAndMetricId;
 import com.ning.billing.usage.timeline.sources.SourceIdAndMetricIdMapper;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper({CategoryIdAndMetricMapper.class, StartTimesMapper.class, SourceIdAndMetricIdMapper.class})
 public interface TimelineSqlDao extends Transactional<TimelineSqlDao>, Transmogrifier {
 
     @SqlQuery
-    Integer getSourceId(@Bind("sourceName") final String source);
+    Integer getSourceId(@Bind("sourceName") final String source,
+                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    String getSource(@Bind("sourceId") final Integer sourceId);
+    String getSource(@Bind("sourceId") final Integer sourceId,
+                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @Mapper(DefaultMapper.class)
-    List<Map<String, Object>> getSources();
+    List<Map<String, Object>> getSources(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void addSource(@Bind("sourceName") final String source);
+    void addSource(@Bind("sourceName") final String source,
+                   @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch
     @BatchChunkSize(1000)
-    void bulkInsertSources(@Bind("sourceName") Iterator<String> sourcesIterator);
+    void bulkInsertSources(@Bind("sourceName") Iterator<String> sourcesIterator,
+                           @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    Integer getEventCategoryId(@Bind("eventCategory") final String eventCategory);
+    Integer getEventCategoryId(@Bind("eventCategory") final String eventCategory,
+                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    String getEventCategory(@Bind("eventCategoryId") final Integer eventCategoryId);
+    String getEventCategory(@Bind("eventCategoryId") final Integer eventCategoryId,
+                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void addEventCategory(@Bind("eventCategory") final String eventCategory);
+    void addEventCategory(@Bind("eventCategory") final String eventCategory,
+                          @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch
     @BatchChunkSize(1000)
-    void bulkInsertEventCategories(@Bind("eventCategory") Iterator<String> cateogoryNames);
+    void bulkInsertEventCategories(@Bind("eventCategory") Iterator<String> categoryNames,
+                                   @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    Iterable<Integer> getMetricIdsBySourceId(@Bind("sourceId") final Integer sourceId);
+    Iterable<Integer> getMetricIdsBySourceId(@Bind("sourceId") final Integer sourceId,
+                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    Iterable<SourceIdAndMetricId> getMetricIdsForAllSources();
+    Iterable<SourceIdAndMetricId> getMetricIdsForAllSources(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    Integer getMetricId(@Bind("eventCategoryId") final int eventCategoryId, @Bind("metric") final String metric);
+    Integer getMetricId(@Bind("eventCategoryId") final int eventCategoryId,
+                        @Bind("metric") final String metric,
+                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    CategoryIdAndMetric getEventCategoryIdAndMetric(@Bind("metricId") final Integer metricId);
+    CategoryIdAndMetric getEventCategoryIdAndMetric(@Bind("metricId") final Integer metricId,
+                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void addMetric(@Bind("eventCategoryId") final int eventCategoryId, @Bind("metric") final String metric);
+    void addMetric(@Bind("eventCategoryId") final int eventCategoryId,
+                   @Bind("metric") final String metric,
+                   @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch
     @BatchChunkSize(1000)
-    void bulkInsertMetrics(@CategoryIdAndMetricBinder Iterator<CategoryIdAndMetric> categoriesAndMetrics);
+    void bulkInsertMetrics(@CategoryIdAndMetricBinder Iterator<CategoryIdAndMetric> categoriesAndMetrics,
+                           @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     @Mapper(DefaultMapper.class)
-    List<Map<String, Object>> getEventCategories();
+    List<Map<String, Object>> getEventCategories(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @Mapper(DefaultMapper.class)
-    List<Map<String, Object>> getMetrics();
+    List<Map<String, Object>> getMetrics(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    int getLastInsertedId();
+    int getLastInsertedId(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    long getHighestTimelineChunkId();
+    long getHighestTimelineChunkId(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void insertTimelineChunk(@TimelineChunkBinder final TimelineChunk timelineChunk);
+    void insertTimelineChunk(@TimelineChunkBinder final TimelineChunk timelineChunk,
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch
     @BatchChunkSize(1000)
-    void bulkInsertTimelineChunks(@TimelineChunkBinder Iterator<TimelineChunk> chunkIterator);
+    void bulkInsertTimelineChunks(@TimelineChunkBinder Iterator<TimelineChunk> chunkIterator,
+                                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    Integer insertLastStartTimes(@StartTimesBinder final StartTimes startTimes);
+    Integer insertLastStartTimes(@StartTimesBinder final StartTimes startTimes,
+                                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    StartTimes getLastStartTimes();
+    StartTimes getLastStartTimes(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    void deleteLastStartTimes();
+    void deleteLastStartTimes(@InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    void test();
+    void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/TimelineEventHandler.java b/usage/src/main/java/com/ning/billing/usage/timeline/TimelineEventHandler.java
index f36c1df..88728ef 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/TimelineEventHandler.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/TimelineEventHandler.java
@@ -51,6 +51,8 @@ import com.ning.billing.usage.timeline.shutdown.ShutdownSaveMode;
 import com.ning.billing.usage.timeline.shutdown.StartTimes;
 import com.ning.billing.usage.timeline.sources.SourceSamplesForTimestamp;
 import com.ning.billing.usage.timeline.times.TimelineCoder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
@@ -203,8 +205,10 @@ public class TimelineEventHandler {
      * @param eventType      event category
      * @param eventTimestamp event timestamp
      * @param samples        samples to record
+     * @param context        the call context
      */
-    public void record(final String sourceName, final String eventType, final DateTime eventTimestamp, final Map<String, Object> samples) {
+    public void record(final String sourceName, final String eventType, final DateTime eventTimestamp,
+                       final Map<String, Object> samples, final InternalCallContext context) {
         if (shuttingDown.get()) {
             eventsReceivedAfterShuttingDown.incrementAndGet();
             return;
@@ -213,11 +217,11 @@ public class TimelineEventHandler {
             handledEventCount.incrementAndGet();
 
             // Find the sourceId
-            final int sourceId = timelineDAO.getOrAddSource(sourceName);
+            final int sourceId = timelineDAO.getOrAddSource(sourceName, context);
 
             // Extract and parse samples
             final Map<Integer, ScalarSample> scalarSamples = new LinkedHashMap<Integer, ScalarSample>();
-            convertSamplesToScalarSamples(sourceId, eventType, samples, scalarSamples);
+            convertSamplesToScalarSamples(sourceId, eventType, samples, scalarSamples, context);
 
             if (scalarSamples.isEmpty()) {
                 eventsDiscarded.incrementAndGet();
@@ -230,7 +234,7 @@ public class TimelineEventHandler {
                 backingBuffer.append(sourceSamples);
             }
             // Then add them to the in-memory accumulator
-            processSamples(sourceSamples);
+            processSamples(sourceSamples, context);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -260,24 +264,27 @@ public class TimelineEventHandler {
     }
 
     @VisibleForTesting
-    public void processSamples(final SourceSamplesForTimestamp hostSamples) throws ExecutionException, IOException {
+    public void processSamples(final SourceSamplesForTimestamp hostSamples, final InternalTenantContext context) throws ExecutionException, IOException {
         final int sourceId = hostSamples.getSourceId();
         final String category = hostSamples.getCategory();
-        final int categoryId = timelineDAO.getEventCategoryId(category);
+        final int categoryId = timelineDAO.getEventCategoryId(category, context);
         final DateTime timestamp = hostSamples.getTimestamp();
         final TimelineSourceEventAccumulator accumulator = getOrAddSourceEventAccumulator(sourceId, categoryId, timestamp);
         accumulator.addSourceSamples(hostSamples);
     }
 
-    public Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, @Nullable final DateTime filterStartTime, @Nullable final DateTime filterEndTime) throws IOException, ExecutionException {
-        return getInMemoryTimelineChunks(sourceId, ImmutableList.copyOf(timelineDAO.getMetricIdsBySourceId(sourceId)), filterStartTime, filterEndTime);
+    public Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, @Nullable final DateTime filterStartTime,
+                                                                         @Nullable final DateTime filterEndTime, final InternalTenantContext context) throws IOException, ExecutionException {
+        return getInMemoryTimelineChunks(sourceId, ImmutableList.copyOf(timelineDAO.getMetricIdsBySourceId(sourceId, context)), filterStartTime, filterEndTime);
     }
 
-    public Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, final Integer metricId, @Nullable final DateTime filterStartTime, @Nullable final DateTime filterEndTime) throws IOException, ExecutionException {
+    public Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, final Integer metricId, @Nullable final DateTime filterStartTime,
+                                                                         @Nullable final DateTime filterEndTime) throws IOException, ExecutionException {
         return getInMemoryTimelineChunks(sourceId, ImmutableList.<Integer>of(metricId), filterStartTime, filterEndTime);
     }
 
-    public synchronized Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, final List<Integer> metricIds, @Nullable final DateTime filterStartTime, @Nullable final DateTime filterEndTime) throws IOException, ExecutionException {
+    public synchronized Collection<? extends TimelineChunk> getInMemoryTimelineChunks(final Integer sourceId, final List<Integer> metricIds,
+                                                                                      @Nullable final DateTime filterStartTime, @Nullable final DateTime filterEndTime) throws IOException, ExecutionException {
         getInMemoryChunksCallCount.incrementAndGet();
         // Check first if there is an in-memory accumulator for this host
         final SourceAccumulatorsAndUpdateDate sourceAccumulatorsAndDate = accumulators.get(sourceId);
@@ -290,8 +297,8 @@ public class TimelineEventHandler {
         for (final TimelineSourceEventAccumulator accumulator : sourceAccumulatorsAndDate.getCategoryAccumulators().values()) {
             for (final TimelineChunk chunk : accumulator.getPendingTimelineChunks()) {
                 if ((filterStartTime != null && chunk.getEndTime().isBefore(filterStartTime)) ||
-                        (filterEndTime != null && chunk.getStartTime().isAfter(filterEndTime)) ||
-                        !metricIds.contains(chunk.getMetricId())) {
+                    (filterEndTime != null && chunk.getStartTime().isAfter(filterEndTime)) ||
+                    !metricIds.contains(chunk.getMetricId())) {
                     continue;
                 } else {
                     samplesBySourceName.add(chunk);
@@ -328,27 +335,28 @@ public class TimelineEventHandler {
     }
 
     @VisibleForTesting
-    void convertSamplesToScalarSamples(final Integer sourceId, final String eventType, final Map<String, Object> inputSamples, final Map<Integer, ScalarSample> outputSamples) {
+    void convertSamplesToScalarSamples(final Integer sourceId, final String eventType, final Map<String, Object> inputSamples,
+                                       final Map<Integer, ScalarSample> outputSamples, final InternalCallContext context) {
         if (inputSamples == null) {
             return;
         }
-        final Integer eventCategoryId = timelineDAO.getOrAddEventCategory(eventType);
+        final Integer eventCategoryId = timelineDAO.getOrAddEventCategory(eventType, context);
 
         for (final String attributeName : inputSamples.keySet()) {
-            final Integer metricId = timelineDAO.getOrAddMetric(sourceId, eventCategoryId, attributeName);
+            final Integer metricId = timelineDAO.getOrAddMetric(sourceId, eventCategoryId, attributeName, context);
             final Object sample = inputSamples.get(attributeName);
 
             outputSamples.put(metricId, ScalarSample.fromObject(sample));
         }
     }
 
-    public void replay(final String spoolDir) {
+    public void replay(final String spoolDir, final InternalCallContext context) {
         replayCount.incrementAndGet();
         log.info("Starting replay of files in {}", spoolDir);
         final Replayer replayer = new Replayer(spoolDir);
         StartTimes lastStartTimes = null;
         if (shutdownSaveMode == ShutdownSaveMode.SAVE_START_TIMES) {
-            lastStartTimes = timelineDAO.getLastStartTimes();
+            lastStartTimes = timelineDAO.getLastStartTimes(context);
             if (lastStartTimes == null) {
                 log.info("Did not find startTimes");
             } else {
@@ -374,22 +382,22 @@ public class TimelineEventHandler {
                         try {
                             final int sourceId = hostSamples.getSourceId();
                             final String category = hostSamples.getCategory();
-                            final int categoryId = timelineDAO.getEventCategoryId(category);
+                            final int categoryId = timelineDAO.getEventCategoryId(category, context);
                             // If startTimes is non-null and the samples come from before the first time for
                             // the given host and event category, ignore the samples
                             if (startTimes != null) {
                                 final DateTime timestamp = hostSamples.getTimestamp();
                                 final DateTime categoryStartTime = startTimes.getStartTimeForSourceIdAndCategoryId(sourceId, categoryId);
                                 if (timestamp == null ||
-                                        timestamp.isBefore(startTimes.getMinStartTime()) ||
-                                        (categoryStartTime != null && timestamp.isBefore(categoryStartTime))) {
+                                    timestamp.isBefore(startTimes.getMinStartTime()) ||
+                                    (categoryStartTime != null && timestamp.isBefore(categoryStartTime))) {
                                     replaySamplesOutsideTimeRangeCount.incrementAndGet();
                                     useSamples = false;
                                 }
                             }
                             if (useSamples) {
                                 replaySamplesProcessedCount.incrementAndGet();
-                                processSamples(hostSamples);
+                                processSamples(hostSamples, context);
                             }
                         } catch (Exception e) {
                             log.warn("Got exception replaying sample, data potentially lost! {}", hostSamples.toString());
@@ -400,7 +408,7 @@ public class TimelineEventHandler {
                 }
             });
             if (shutdownSaveMode == ShutdownSaveMode.SAVE_START_TIMES) {
-                timelineDAO.deleteLastStartTimes();
+                timelineDAO.deleteLastStartTimes(context);
                 log.info("Deleted old startTimes");
             }
             log.info(String.format("Replay completed; %d files skipped, samples read %d, samples outside time range %d, samples used %d",
@@ -420,13 +428,13 @@ public class TimelineEventHandler {
         log.info("Timelines committed");
     }
 
-    public void commitAndShutdown() {
+    public void commitAndShutdown(final InternalCallContext context) {
         shuttingDown.set(true);
         final boolean doingFastShutdown = shutdownSaveMode == ShutdownSaveMode.SAVE_START_TIMES;
         if (doingFastShutdown) {
             final StartTimes startTimes = new StartTimes();
             saveStartTimes(startTimes);
-            timelineDAO.insertLastStartTimes(startTimes);
+            timelineDAO.insertLastStartTimes(startTimes, context);
             log.info("During shutdown, saved timeline start times in the db");
         } else {
             saveAccumulators();
diff --git a/usage/src/main/java/com/ning/billing/usage/timeline/TimelineSourceEventAccumulator.java b/usage/src/main/java/com/ning/billing/usage/timeline/TimelineSourceEventAccumulator.java
index d352dd9..02c0fcd 100644
--- a/usage/src/main/java/com/ning/billing/usage/timeline/TimelineSourceEventAccumulator.java
+++ b/usage/src/main/java/com/ning/billing/usage/timeline/TimelineSourceEventAccumulator.java
@@ -38,6 +38,7 @@ import com.ning.billing.usage.timeline.samples.RepeatSample;
 import com.ning.billing.usage.timeline.samples.ScalarSample;
 import com.ning.billing.usage.timeline.sources.SourceSamplesForTimestamp;
 import com.ning.billing.usage.timeline.times.TimelineCoder;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 
 /**
  * This class represents a collection of timeline chunks, one for each
@@ -119,8 +120,8 @@ public class TimelineSourceEventAccumulator {
      * chunk writes.
      */
     public TimelineSourceEventAccumulator(final TimelineDao timelineDAO, final TimelineCoder timelineCoder, final SampleCoder sampleCoder,
-                                          final Integer sourceId, final int eventTypeId, final DateTime firstSampleTime) {
-        this(timelineDAO, timelineCoder, sampleCoder, new BackgroundDBChunkWriter(timelineDAO, null, true), sourceId, eventTypeId, firstSampleTime, Integer.MAX_VALUE);
+                                          final Integer sourceId, final int eventTypeId, final DateTime firstSampleTime, final InternalCallContextFactory internalCallContextFactory) {
+        this(timelineDAO, timelineCoder, sampleCoder, new BackgroundDBChunkWriter(timelineDAO, null, true, internalCallContextFactory), sourceId, eventTypeId, firstSampleTime, Integer.MAX_VALUE);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/usage/src/main/resources/com/ning/billing/usage/timeline/aggregator/TimelineAggregatorSqlDao.sql.stg b/usage/src/main/resources/com/ning/billing/usage/timeline/aggregator/TimelineAggregatorSqlDao.sql.stg
index 341ea3a..ff64329 100644
--- a/usage/src/main/resources/com/ning/billing/usage/timeline/aggregator/TimelineAggregatorSqlDao.sql.stg
+++ b/usage/src/main/resources/com/ning/billing/usage/timeline/aggregator/TimelineAggregatorSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group TimelineAggregatorDAO;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getStreamingAggregationCandidates() ::= <<
   select
     chunk_id
@@ -15,6 +18,7 @@ getStreamingAggregationCandidates() ::= <<
   , dont_aggregate
   from timeline_chunks
   where source_id != 0 and aggregation_level = :aggregationLevel and not_valid = 0
+  <AND_CHECK_TENANT()>
   order by source_id, metric_id, start_time
  >>
 
@@ -34,6 +38,7 @@ getStreamingAggregationCandidates() ::= <<
   from timeline_chunks
   where source_id = :source_id
   and metric_id in (<metricIds>)
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -45,6 +50,7 @@ makeTimelineChunkValid() ::= <<
   update timeline_chunks
   set not_valid = 0
   where chunk_id = :chunkId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -52,9 +58,10 @@ makeTimelineChunksInvalid(chunkIds) ::=<<
   update timeline_chunks
   set not_valid = 1
   where chunk_id in (<chunkIds>)
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 deleteTimelineChunks(chunkIds) ::=<<
-  delete from timeline_chunks where chunk_id in (<chunkIds>);
+  delete from timeline_chunks where chunk_id in (<chunkIds>) <AND_CHECK_TENANT()>;
 >>
diff --git a/usage/src/main/resources/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.sql.stg b/usage/src/main/resources/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.sql.stg
index 1e0364b..0db88d2 100644
--- a/usage/src/main/resources/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.sql.stg
+++ b/usage/src/main/resources/com/ning/billing/usage/timeline/persistent/TimelineSqlDao.sql.stg
@@ -1,10 +1,14 @@
 group TimelineSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getSource() ::= <<
   select
     source_name
   from sources
   where source_id = :sourceId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -13,17 +17,19 @@ getSources() ::= <<
     source_id
   , source_name
   from sources
+  where <CHECK_TENANT()>
   ;
 >>
 
 addSource() ::= <<
-  insert ignore into sources (source_name, created_dt)
-  values (:sourceName, unix_timestamp());
+  insert ignore into sources (source_name, created_dt, account_record_id, tenant_record_id)
+  values (:sourceName, unix_timestamp(), :accountRecordId, :tenantRecordId);
 >>
 
 getEventCategories() ::= <<
   select event_category_id, event_category
   from event_categories
+  where <CHECK_TENANT()>
   order by event_category_id asc
   ;
 >>
@@ -33,6 +39,7 @@ getEventCategoryId() ::= <<
     event_category_id
   from event_categories
   where event_category = :eventCategory
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -41,12 +48,13 @@ getEventCategory() ::= <<
     event_category
   from event_categories
   where event_category_id = :eventCategoryId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 addEventCategory() ::= <<
-  insert ignore into event_categories (event_category)
-  values (:eventCategory);
+  insert ignore into event_categories (event_category, account_record_id, tenant_record_id)
+  values (:eventCategory, :accountRecordId, :tenantRecordId);
 >>
 
 getMetricId() ::= <<
@@ -55,6 +63,7 @@ getMetricId() ::= <<
   from metrics
   where metric = :metric
     and event_category_id = :eventCategoryId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -64,6 +73,7 @@ getEventCategoryIdAndMetric() ::= <<
   , metric
   from metrics
   where metric_id = :metricId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -72,24 +82,27 @@ getMetric() ::= <<
     metric
   from metrics
   where metric_id = :metricId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 addMetric() ::= <<
-  insert ignore into metrics (event_category_id, metric)
-  values (:eventCategoryId, :metric);
+  insert ignore into metrics (event_category_id, metric, account_record_id, tenant_record_id)
+  values (:eventCategoryId, :metric, :accountRecordId, :tenantRecordId);
 >>
 
 getMetricIdsBySourceId() ::= <<
   select distinct metric_id
   from timeline_chunks c
   where source_id = :sourceId
+  <AND_CHECK_TENANT()>
   ;
 >>
 
 getMetricIdsForAllSources() ::= <<
   select distinct metric_id, source_id
   from timeline_chunks c
+  where <CHECK_TENANT()>
   ;
 >>
 
@@ -99,6 +112,7 @@ getMetrics() ::= <<
   , event_category_id
   , metric
   from metrics
+  <AND_CHECK_TENANT()>
   ;
 >>
 
@@ -107,8 +121,8 @@ getLastInsertedId() ::= <<
 >>
 
 insertTimelineChunk() ::= <<
-  insert into timeline_chunks (record_id, source_id, metric_id, sample_count, start_time, end_time, in_row_samples, blob_samples, aggregation_level, not_valid, dont_aggregate)
-  values (:chunkId, :sourceId, :metricId, :sampleCount, :startTime, :endTime, :inRowSamples, :blobSamples, :aggregationLevel, :notValid, :dontAggregate);
+  insert into timeline_chunks (record_id, source_id, metric_id, sample_count, start_time, end_time, in_row_samples, blob_samples, aggregation_level, not_valid, dont_aggregate, account_record_id, tenant_record_id)
+  values (:chunkId, :sourceId, :metricId, :sampleCount, :startTime, :endTime, :inRowSamples, :blobSamples, :aggregationLevel, :notValid, :dontAggregate, :accountRecordId, :tenantRecordId);
 >>
 
 getSamplesBySourceIdsAndMetricIds(sourceIds, metricIds) ::= <<
@@ -132,50 +146,52 @@ getSamplesBySourceIdsAndMetricIds(sourceIds, metricIds) ::= <<
     and metric_id in (<metricIds>)
   <endif>
   and not_valid = 0
+  <AND_CHECK_TENANT()>
   order by source_id, metric_id, start_time asc
   ;
 >>
 
 insertLastStartTimes() ::= <<
-  insert into last_start_times (time_inserted, start_times)
-                        values (:timeInserted, :startTimes)
+  insert into last_start_times (time_inserted, start_times, account_record_id, tenant_record_id)
+                        values (:timeInserted, :startTimes, :accountRecordId, :tenantRecordId)
 >>
 
 getLastStartTimes() ::= <<
   select time_inserted, start_times
   from last_start_times
+  where <CHECK_TENANT()>
   order by time_inserted desc
   limit 1
 >>
 
 deleteLastStartTimes() ::= <<
-  delete from last_start_times
+  delete from last_start_times where <CHECK_TENANT()>
 >>
 
 bulkInsertSources() ::= <<
-  insert into sources (source_name, created_dt)
-  values (:sourceName, unix_timestamp());
+  insert into sources (source_name, created_dt, account_record_id, tenant_record_id)
+  values (:sourceName, unix_timestamp(), :accountRecordId, :tenantRecordId);
 >>
 
 bulkInsertEventCategories() ::= <<
-  insert into event_categories (event_category)
-  values (:eventCategory);
+  insert into event_categories (event_category, account_record_id, tenant_record_id)
+  values (:eventCategory, :accountRecordId, :tenantRecordId);
 >>
 
 bulkInsertMetrics() ::= <<
-  insert into metrics (event_category_id, metric)
-  values (:eventCategoryId, :metric);
+  insert into metrics (event_category_id, metric, account_record_id, tenant_record_id)
+  values (:eventCategoryId, :metric, :accountRecordId, :tenantRecordId);
 >>
 
 bulkInsertTimelineChunks() ::= <<
-  insert into timeline_chunks (record_id, source_id, metric_id, sample_count, start_time, end_time, not_valid, dont_aggregate, aggregation_level, in_row_samples, blob_samples)
-  values (:chunkId, :sourceId, :metricId, :sampleCount, :startTime, :endTime, :dontAggregate, :notValid, :aggregationLevel, :inRowSamples, :blobSamples);
+  insert into timeline_chunks (record_id, source_id, metric_id, sample_count, start_time, end_time, not_valid, dont_aggregate, aggregation_level, in_row_samples, blob_samples, account_record_id, tenant_record_id)
+  values (:chunkId, :sourceId, :metricId, :sampleCount, :startTime, :endTime, :dontAggregate, :notValid, :aggregationLevel, :inRowSamples, :blobSamples, :accountRecordId, :tenantRecordId);
 >>
 
 getHighestTimelineChunkId() ::= <<
-  select record_id from timeline_chunks order by record_id desc limit 1;
+  select record_id from timeline_chunks where <CHECK_TENANT()> order by record_id desc limit 1;
 >>
 
 test() ::= <<
-  select 1;
+  select 1 where <CHECK_TENANT()>;
 >>
diff --git a/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java b/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
index 7ced15e..8995e6f 100644
--- a/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
@@ -45,6 +45,8 @@ import com.ning.billing.util.audit.DefaultAuditLogsForInvoices;
 import com.ning.billing.util.audit.DefaultAuditLogsForPayments;
 import com.ning.billing.util.audit.DefaultAuditLogsForRefunds;
 import com.ning.billing.util.audit.dao.AuditDao;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.TableName;
 
@@ -53,23 +55,25 @@ import com.google.common.collect.ImmutableList;
 public class DefaultAuditUserApi implements AuditUserApi {
 
     private final AuditDao auditDao;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultAuditUserApi(final AuditDao auditDao) {
+    public DefaultAuditUserApi(final AuditDao auditDao, final InternalCallContextFactory internalCallContextFactory) {
         this.auditDao = auditDao;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
-    public AuditLogsForBundles getAuditLogsForBundles(final List<BundleTimeline> bundles, final AuditLevel auditLevel) {
+    public AuditLogsForBundles getAuditLogsForBundles(final List<BundleTimeline> bundles, final AuditLevel auditLevel, final TenantContext context) {
         final Map<UUID, List<AuditLog>> bundlesAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Map<UUID, List<AuditLog>> subscriptionsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Map<UUID, List<AuditLog>> subscriptionEventsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final BundleTimeline bundle : bundles) {
-            bundlesAuditLogs.put(bundle.getBundleId(), getAuditLogs(bundle.getBundleId(), ObjectType.BUNDLE, auditLevel));
+            bundlesAuditLogs.put(bundle.getBundleId(), getAuditLogs(bundle.getBundleId(), ObjectType.BUNDLE, auditLevel, context));
             for (final SubscriptionTimeline subscriptionTimeline : bundle.getSubscriptions()) {
-                subscriptionsAuditLogs.put(subscriptionTimeline.getId(), getAuditLogs(subscriptionTimeline.getId(), ObjectType.SUBSCRIPTION, auditLevel));
+                subscriptionsAuditLogs.put(subscriptionTimeline.getId(), getAuditLogs(subscriptionTimeline.getId(), ObjectType.SUBSCRIPTION, auditLevel, context));
                 for (final ExistingEvent event : subscriptionTimeline.getExistingEvents()) {
-                    subscriptionEventsAuditLogs.put(event.getEventId(), getAuditLogs(event.getEventId(), ObjectType.SUBSCRIPTION_EVENT, auditLevel));
+                    subscriptionEventsAuditLogs.put(event.getEventId(), getAuditLogs(event.getEventId(), ObjectType.SUBSCRIPTION_EVENT, auditLevel, context));
                 }
             }
         }
@@ -78,43 +82,43 @@ public class DefaultAuditUserApi implements AuditUserApi {
     }
 
     @Override
-    public AuditLogsForInvoicePayments getAuditLogsForInvoicePayments(final List<InvoicePayment> invoicePayments, final AuditLevel auditLevel) {
+    public AuditLogsForInvoicePayments getAuditLogsForInvoicePayments(final List<InvoicePayment> invoicePayments, final AuditLevel auditLevel, final TenantContext context) {
         final Map<UUID, List<AuditLog>> invoicePaymentsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final InvoicePayment invoicePayment : invoicePayments) {
-            invoicePaymentsAuditLogs.put(invoicePayment.getId(), getAuditLogs(invoicePayment.getId(), ObjectType.INVOICE_PAYMENT, auditLevel));
+            invoicePaymentsAuditLogs.put(invoicePayment.getId(), getAuditLogs(invoicePayment.getId(), ObjectType.INVOICE_PAYMENT, auditLevel, context));
         }
 
         return new DefaultAuditLogsForInvoicePayments(invoicePaymentsAuditLogs);
     }
 
     @Override
-    public AuditLogsForRefunds getAuditLogsForRefunds(final List<Refund> refunds, final AuditLevel auditLevel) {
+    public AuditLogsForRefunds getAuditLogsForRefunds(final List<Refund> refunds, final AuditLevel auditLevel, final TenantContext context) {
         final Map<UUID, List<AuditLog>> refundsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final Refund refund : refunds) {
-            refundsAuditLogs.put(refund.getId(), getAuditLogs(refund.getId(), ObjectType.REFUND, auditLevel));
+            refundsAuditLogs.put(refund.getId(), getAuditLogs(refund.getId(), ObjectType.REFUND, auditLevel, context));
         }
 
         return new DefaultAuditLogsForRefunds(refundsAuditLogs);
     }
 
     @Override
-    public AuditLogsForPayments getAuditLogsForPayments(final List<Payment> payments, final AuditLevel auditLevel) {
+    public AuditLogsForPayments getAuditLogsForPayments(final List<Payment> payments, final AuditLevel auditLevel, final TenantContext context) {
         final Map<UUID, List<AuditLog>> paymentsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final Payment payment : payments) {
-            paymentsAuditLogs.put(payment.getId(), getAuditLogs(payment.getId(), ObjectType.PAYMENT, auditLevel));
+            paymentsAuditLogs.put(payment.getId(), getAuditLogs(payment.getId(), ObjectType.PAYMENT, auditLevel, context));
         }
 
         return new DefaultAuditLogsForPayments(paymentsAuditLogs);
     }
 
     @Override
-    public AuditLogsForInvoices getAuditLogsForInvoices(final List<Invoice> invoices, final AuditLevel auditLevel) {
+    public AuditLogsForInvoices getAuditLogsForInvoices(final List<Invoice> invoices, final AuditLevel auditLevel, final TenantContext context) {
         final Map<UUID, List<AuditLog>> invoiceAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Map<UUID, List<AuditLog>> invoiceItemsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final Invoice invoice : invoices) {
-            invoiceAuditLogs.put(invoice.getId(), getAuditLogs(invoice.getId(), ObjectType.INVOICE, auditLevel));
+            invoiceAuditLogs.put(invoice.getId(), getAuditLogs(invoice.getId(), ObjectType.INVOICE, auditLevel, context));
             for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
-                invoiceItemsAuditLogs.put(invoiceItem.getId(), getAuditLogs(invoiceItem.getId(), ObjectType.INVOICE_ITEM, auditLevel));
+                invoiceItemsAuditLogs.put(invoiceItem.getId(), getAuditLogs(invoiceItem.getId(), ObjectType.INVOICE_ITEM, auditLevel, context));
             }
         }
 
@@ -122,7 +126,7 @@ public class DefaultAuditUserApi implements AuditUserApi {
     }
 
     @Override
-    public List<AuditLog> getAuditLogs(final UUID objectId, final ObjectType objectType, final AuditLevel auditLevel) {
+    public List<AuditLog> getAuditLogs(final UUID objectId, final ObjectType objectType, final AuditLevel auditLevel, final TenantContext context) {
         // Optimization - bail early
         if (AuditLevel.NONE.equals(auditLevel)) {
             return ImmutableList.<AuditLog>of();
@@ -133,7 +137,7 @@ public class DefaultAuditUserApi implements AuditUserApi {
             return ImmutableList.<AuditLog>of();
         }
 
-        return auditDao.getAuditLogsForId(tableName, objectId, auditLevel);
+        return auditDao.getAuditLogsForId(tableName, objectId, auditLevel, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     private TableName getTableNameFromObjectType(final ObjectType objectType) {
diff --git a/util/src/main/java/com/ning/billing/util/audit/dao/AuditDao.java b/util/src/main/java/com/ning/billing/util/audit/dao/AuditDao.java
index 3f0e485..eed4012 100644
--- a/util/src/main/java/com/ning/billing/util/audit/dao/AuditDao.java
+++ b/util/src/main/java/com/ning/billing/util/audit/dao/AuditDao.java
@@ -21,9 +21,10 @@ import java.util.UUID;
 
 import com.ning.billing.util.api.AuditLevel;
 import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.TableName;
 
 public interface AuditDao {
 
-    public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel);
+    public List<AuditLog> getAuditLogsForId(TableName tableName, UUID objectId, AuditLevel auditLevel, InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
index c70b99c..1b75842 100644
--- a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
+++ b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
@@ -27,6 +27,7 @@ import org.skife.jdbi.v2.IDBI;
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.api.AuditLevel;
 import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.TableName;
 
@@ -42,43 +43,43 @@ public class DefaultAuditDao implements AuditDao {
     }
 
     @Override
-    public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel) {
+    public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel, final InternalTenantContext context) {
         if (tableName.hasHistoryTable()) {
-            return doGetAuditLogsViaHistoryForId(tableName, objectId, auditLevel);
+            return doGetAuditLogsViaHistoryForId(tableName, objectId, auditLevel, context);
         } else {
-            return doGetAuditLogsForId(tableName, objectId, auditLevel);
+            return doGetAuditLogsForId(tableName, objectId, auditLevel, context);
         }
     }
 
-    private List<AuditLog> doGetAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel) {
+    private List<AuditLog> doGetAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel, final InternalTenantContext context) {
         // Look at the table and gather all record_id for that objectId
-        final Long recordId = auditSqlDao.getRecordIdForTable(tableName.getTableName().toLowerCase(), objectId.toString());
+        final Long recordId = auditSqlDao.getRecordIdForTable(tableName.getTableName().toLowerCase(), objectId.toString(), context);
         if (recordId == null) {
             return ImmutableList.<AuditLog>of();
         } else {
-            return getAuditLogsForRecordId(tableName, recordId, auditLevel);
+            return getAuditLogsForRecordId(tableName, recordId, auditLevel, context);
         }
     }
 
-    private List<AuditLog> doGetAuditLogsViaHistoryForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel) {
+    private List<AuditLog> doGetAuditLogsViaHistoryForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel, final InternalTenantContext context) {
         final List<AuditLog> auditLogs = new ArrayList<AuditLog>();
 
         // Look at the history table and gather all the history_record_id for that objectId
         final List<Long> recordIds = auditSqlDao.getHistoryRecordIdsForTable(tableName.getHistoryTableName().getTableName().toLowerCase(),
-                                                                             objectId.toString());
+                                                                             objectId.toString(), context);
         if (recordIds == null) {
             return auditLogs;
         } else {
             for (final Long recordId : recordIds) {
-                auditLogs.addAll(getAuditLogsForRecordId(tableName.getHistoryTableName(), recordId, auditLevel));
+                auditLogs.addAll(getAuditLogsForRecordId(tableName.getHistoryTableName(), recordId, auditLevel, context));
             }
 
             return auditLogs;
         }
     }
 
-    private List<AuditLog> getAuditLogsForRecordId(final TableName tableName, final Long recordId, final AuditLevel auditLevel) {
-        final List<AuditLog> allAuditLogs = auditSqlDao.getAuditLogsForRecordId(tableName, recordId);
+    private List<AuditLog> getAuditLogsForRecordId(final TableName tableName, final Long recordId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        final List<AuditLog> allAuditLogs = auditSqlDao.getAuditLogsForRecordId(tableName, recordId, context);
         if (AuditLevel.FULL.equals(auditLevel)) {
             return allAuditLogs;
         } else if (AuditLevel.MINIMAL.equals(auditLevel) && allAuditLogs.size() > 0) {
diff --git a/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java b/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
index 71190eb..c80fcba 100644
--- a/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
@@ -32,6 +32,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueueEntryLifecycleState;
@@ -42,25 +45,36 @@ public interface PersistentBusSqlDao extends Transactional<PersistentBusSqlDao>,
 
     @SqlQuery
     @Mapper(PersistentBusSqlMapper.class)
-    public BusEventEntry getNextBusEventEntry(@Bind("max") int max, @Bind("owner") String owner, @Bind("now") Date now);
+    public BusEventEntry getNextBusEventEntry(@Bind("max") int max,
+                                              @Bind("owner") String owner,
+                                              @Bind("now") Date now,
+                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public int claimBusEvent(@Bind("owner") String owner, @Bind("nextAvailable") Date nextAvailable,
-                             @Bind("recordId") Long id, @Bind("now") Date now);
+    public int claimBusEvent(@Bind("owner") String owner,
+                             @Bind("nextAvailable") Date nextAvailable,
+                             @Bind("recordId") Long id,
+                             @Bind("now") Date now,
+                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void clearBusEvent(@Bind("recordId") Long id, @Bind("owner") String owner);
+    public void clearBusEvent(@Bind("recordId") Long id,
+                              @Bind("owner") String owner,
+                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void removeBusEventsById(@Bind("recordId") Long id);
+    public void removeBusEventsById(@Bind("recordId") Long id,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void insertBusEvent(@Bind(binder = PersistentBusSqlBinder.class) BusEventEntry evt);
+    public void insertBusEvent(@Bind(binder = PersistentBusSqlBinder.class) BusEventEntry evt,
+                               @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void insertClaimedHistory(@Bind("ownerId") String owner, @Bind("claimedDate") Date claimedDate,
-                                     @Bind("busEventId") long id);
-
+    public void insertClaimedHistory(@Bind("ownerId") String owner,
+                                     @Bind("claimedDate") Date claimedDate,
+                                     @Bind("busEventId") long id,
+                                     @InternalTenantContextBinder final InternalCallContext context);
 
     public static class PersistentBusSqlBinder extends BinderBase implements Binder<Bind, BusEventEntry> {
 
diff --git a/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java b/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
index d4fc1d3..64370ee 100644
--- a/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
+++ b/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.bus;
 
-import com.google.inject.Inject;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 
+import com.google.inject.Inject;
+
 public class DefaultBusService implements BusService {
 
 
diff --git a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
index c5e5375..a6d6e92 100644
--- a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
+++ b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.util.bus;
 
 import java.util.Collections;
@@ -21,6 +22,8 @@ import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 
+import javax.annotation.Nullable;
+
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
@@ -28,15 +31,19 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.eventbus.EventBus;
-import com.google.inject.Inject;
 import com.ning.billing.util.Hostname;
 import com.ning.billing.util.bus.dao.BusEventEntry;
 import com.ning.billing.util.bus.dao.PersistentBusSqlDao;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.jackson.ObjectMapper;
 import com.ning.billing.util.queue.PersistentQueueBase;
 
+import com.google.common.eventbus.EventBus;
+import com.google.inject.Inject;
+
 public class PersistentBus extends PersistentQueueBase implements Bus {
 
     private static final long DELTA_IN_PROCESSING_TIME_MS = 1000L * 60L * 5L; // 5 minutes
@@ -46,12 +53,13 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
 
     private final PersistentBusSqlDao dao;
 
-
     private final EventBusDelegate eventBusDelegate;
     private final Clock clock;
     private final String hostname;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     private static final class EventBusDelegate extends EventBus {
+
         public EventBusDelegate(final String busName) {
             super(busName);
         }
@@ -72,8 +80,7 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
     }
 
     @Inject
-    public PersistentBus(final IDBI dbi, final Clock clock, final PersistentBusConfig config) {
-
+    public PersistentBus(final IDBI dbi, final Clock clock, final PersistentBusConfig config, final InternalCallContextFactory internalCallContextFactory) {
         super("Bus", Executors.newFixedThreadPool(config.getNbThreads(), new ThreadFactory() {
             @Override
             public Thread newThread(final Runnable r) {
@@ -86,6 +93,7 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
         this.clock = clock;
         this.eventBusDelegate = new EventBusDelegate("Killbill EventBus");
         this.hostname = Hostname.get();
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
@@ -100,8 +108,9 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
 
     @Override
     public int doProcessEvents() {
+        final InternalCallContext context = createCallContext(null);
 
-        final List<BusEventEntry> events = getNextBusEvent();
+        final List<BusEventEntry> events = getNextBusEvent(context);
         if (events.size() == 0) {
             return 0;
         }
@@ -112,25 +121,23 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
             result++;
             // STEPH exception handling is done by GUAVA-- logged a bug Issue-780
             eventBusDelegate.post(evt);
-            dao.clearBusEvent(cur.getId(), hostname);
+            dao.clearBusEvent(cur.getId(), hostname, context);
         }
         return result;
     }
 
-
-    private List<BusEventEntry> getNextBusEvent() {
-
+    private List<BusEventEntry> getNextBusEvent(final InternalCallContext context) {
         final Date now = clock.getUTCNow().toDate();
         final Date nextAvailable = clock.getUTCNow().plus(DELTA_IN_PROCESSING_TIME_MS).toDate();
 
-        final BusEventEntry input = dao.getNextBusEventEntry(MAX_BUS_EVENTS, hostname, now);
+        final BusEventEntry input = dao.getNextBusEventEntry(MAX_BUS_EVENTS, hostname, now, context);
         if (input == null) {
             return Collections.emptyList();
         }
 
-        final boolean claimed = (dao.claimBusEvent(hostname, nextAvailable, input.getId(), now) == 1);
+        final boolean claimed = (dao.claimBusEvent(hostname, nextAvailable, input.getId(), now, context) == 1);
         if (claimed) {
-            dao.insertClaimedHistory(hostname, now, input.getId());
+            dao.insertClaimedHistory(hostname, now, input.getId(), context);
             return Collections.singletonList(input);
         }
         return Collections.emptyList();
@@ -169,9 +176,14 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
         try {
             final String json = objectMapper.writeValueAsString(event);
             final BusEventEntry entry = new BusEventEntry(hostname, event.getClass().getName(), json);
-            transactional.insertBusEvent(entry);
+            transactional.insertBusEvent(entry, createCallContext(event));
         } catch (Exception e) {
             log.error("Failed to post BusEvent " + event, e);
         }
     }
+
+    private InternalCallContext createCallContext(@Nullable final BusEvent event) {
+        return internalCallContextFactory.createInternalCallContext("PersistentBus", CallOrigin.INTERNAL, UserType.SYSTEM,
+                                                                    event == null ? null : event.getUserToken());
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
index 2c21d05..c5dd11f 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
@@ -18,8 +18,11 @@ package com.ning.billing.util.callcontext;
 
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 public abstract class CallContextBase implements CallContext {
 
+    protected final UUID tenantId;
     protected final UUID userToken;
     protected final String userName;
     protected final CallOrigin callOrigin;
@@ -27,16 +30,17 @@ public abstract class CallContextBase implements CallContext {
     protected final String reasonCode;
     protected final String comment;
 
-    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType) {
-        this(userName, callOrigin, userType, null);
+    public CallContextBase(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType) {
+        this(tenantId, userName, callOrigin, userType, null);
     }
 
-    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType, final UUID userToken) {
-        this(userName, callOrigin, userType, null, null, userToken);
+    public CallContextBase(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType, final UUID userToken) {
+        this(tenantId, userName, callOrigin, userType, null, null, userToken);
     }
 
-    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType,
+    public CallContextBase(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType,
                            final String reasonCode, final String comment, final UUID userToken) {
+        this.tenantId = tenantId;
         this.userName = userName;
         this.callOrigin = callOrigin;
         this.userType = userType;
@@ -46,6 +50,11 @@ public abstract class CallContextBase implements CallContext {
     }
 
     @Override
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    @Override
     public String getUserName() {
         return userName;
     }
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
index 53b2cfa..454d40e 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
@@ -18,17 +18,20 @@ package com.ning.billing.util.callcontext;
 
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 public interface CallContextFactory {
-    CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType, UUID userToken);
 
-    CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType,
-                                  String reasonCode, String comment, UUID userToken);
+    TenantContext createTenantContext(@Nullable UUID tenantId);
 
-    CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType);
+    CallContext createCallContext(@Nullable UUID tenantId, String userName, CallOrigin callOrigin, UserType userType, UUID userToken);
+
+    CallContext createCallContext(@Nullable UUID tenantId, String userName, CallOrigin callOrigin, UserType userType,
+                                  String reasonCode, String comment, UUID userToken);
 
-    CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate);
+    CallContext createCallContext(@Nullable UUID tenantId, String userName, CallOrigin callOrigin, UserType userType);
 
-    CallContext toMigrationCallContext(CallContext callContext, DateTime createdDate, DateTime updatedDate);
+    CallContext toMigrationCallContext(@Nullable CallContext callContext, DateTime createdDate, DateTime updatedDate);
 }
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextSqlDao.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextSqlDao.java
new file mode 100644
index 0000000..5580273
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextSqlDao.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+
+public interface CallContextSqlDao {
+
+    @SqlQuery("select record_id from tenants where id = :tenantId;")
+    public Long getTenantRecordId(@Bind("tenantId") final String tenantId);
+
+    @SqlQuery("select record_id from accounts where id = :accountId;")
+    public Long getAccountRecordId(@Bind("accountId") final String accountId);
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
index e294d30..0cb9858 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
@@ -25,27 +25,35 @@ import com.ning.billing.util.clock.Clock;
 public class DefaultCallContext extends CallContextBase {
 
     private final DateTime createdDate;
+    private final DateTime updateDate;
 
-    public DefaultCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final UUID userToken, final Clock clock) {
-        super(userName, callOrigin, userType, userToken);
+    public DefaultCallContext(final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType,
+                              final UUID userToken, final Clock clock) {
+        super(tenantId, userName, callOrigin, userType, userToken);
         this.createdDate = clock.getUTCNow();
+        this.updateDate = createdDate;
     }
 
-    public DefaultCallContext(final String userName, final CallOrigin callOrigin, final UserType userType,
+    public DefaultCallContext(final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType,
                               final String reasonCode, final String comment,
                               final UUID userToken, final Clock clock) {
-        super(userName, callOrigin, userType, reasonCode, comment, userToken);
+        super(tenantId, userName, callOrigin, userType, reasonCode, comment, userToken);
         this.createdDate = clock.getUTCNow();
+        this.updateDate = createdDate;
     }
 
-    public DefaultCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final Clock clock) {
-        this(userName, callOrigin, userType, null, clock);
+    public DefaultCallContext(final UUID tenantId, final String userName, final DateTime createdDate, final String reasonCode,
+                              final String comment, final UUID userToken) {
+        super(tenantId, userName, null, null, reasonCode, comment, userToken);
+        this.createdDate = createdDate;
+        this.updateDate = createdDate;
     }
 
-    public DefaultCallContext(final String userName, final DateTime createdDate, final String reasonCode,
-                              final String comment, final UUID userToken) {
-        super(userName, null, null, reasonCode, comment, userToken);
+    public DefaultCallContext(final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType, final String reasonCode,
+                              final String comment, final UUID userToken, final DateTime createdDate, final DateTime updatedDate) {
+        super(tenantId, userName, callOrigin, userType, reasonCode, comment, userToken);
         this.createdDate = createdDate;
+        this.updateDate = updatedDate;
     }
 
     @Override
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
index afd72bd..57dd334 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
@@ -16,15 +16,18 @@
 
 package com.ning.billing.util.callcontext;
 
-import javax.annotation.Nullable;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class DefaultCallContextFactory implements CallContextFactory {
+
     private final Clock clock;
 
     @Inject
@@ -33,25 +36,25 @@ public class DefaultCallContextFactory implements CallContextFactory {
     }
 
     @Override
-    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType,
-                                         @Nullable final UUID userToken) {
-        return new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
+    public TenantContext createTenantContext(final UUID tenantId) {
+        return new DefaultTenantContext(tenantId);
     }
 
     @Override
-    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType,
-                                         final String reasonCode, final String comment, final UUID userToken) {
-        return new DefaultCallContext(userName, callOrigin, userType, reasonCode, comment, userToken, clock);
+    public CallContext createCallContext(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin,
+                                         final UserType userType, @Nullable final UUID userToken) {
+        return new DefaultCallContext(tenantId, userName, callOrigin, userType, userToken, clock);
     }
 
     @Override
-    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType) {
-        return createCallContext(userName, callOrigin, userType, null);
+    public CallContext createCallContext(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin,
+                                         final UserType userType, final String reasonCode, final String comment, final UUID userToken) {
+        return new DefaultCallContext(tenantId, userName, callOrigin, userType, reasonCode, comment, userToken, clock);
     }
 
     @Override
-    public CallContext createMigrationCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final DateTime createdDate, final DateTime updatedDate) {
-        return new MigrationCallContext(userName, callOrigin, userType, createdDate, updatedDate);
+    public CallContext createCallContext(@Nullable final UUID tenantId, final String userName, final CallOrigin callOrigin, final UserType userType) {
+        return createCallContext(tenantId, userName, callOrigin, userType, null);
     }
 
     @Override
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java
new file mode 100644
index 0000000..4d072d2
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+public class DefaultTenantContext implements TenantContext {
+
+    private final UUID tenantId;
+
+    public DefaultTenantContext() {
+        this(null);
+    }
+
+    public DefaultTenantContext(@Nullable final UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    @Override
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultTenantContext");
+        sb.append("{tenantId=").append(tenantId);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultTenantContext that = (DefaultTenantContext) o;
+
+        if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return tenantId != null ? tenantId.hashCode() : 0;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContext.java
new file mode 100644
index 0000000..2986ec9
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContext.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+
+/**
+ * Internal use only
+ */
+public class InternalCallContext extends InternalTenantContext {
+
+    private final UUID userToken;
+    private final String userName;
+    private final CallOrigin callOrigin;
+    private final UserType userType;
+    private final String reasonCode;
+    private final String comment;
+    private final DateTime createdDate;
+    private final DateTime updatedDate;
+
+    public InternalCallContext(final Long tenantRecordId, @Nullable final Long accountRecordId, final UUID userToken, final String userName,
+                               final CallOrigin callOrigin, final UserType userType, final String reasonCode, final String comment,
+                               final DateTime createdDate, final DateTime updatedDate) {
+        super(tenantRecordId, accountRecordId);
+        this.userToken = userToken;
+        this.userName = userName;
+        this.callOrigin = callOrigin;
+        this.userType = userType;
+        this.reasonCode = reasonCode;
+        this.comment = comment;
+        this.createdDate = createdDate;
+        this.updatedDate = updatedDate;
+    }
+
+    public InternalCallContext(final Long tenantRecordId, @Nullable final Long accountRecordId, final CallContext callContext) {
+        this(tenantRecordId, accountRecordId, callContext.getUserToken(), callContext.getUserName(), callContext.getCallOrigin(),
+             callContext.getUserType(), callContext.getReasonCode(), callContext.getComment(), callContext.getCreatedDate(),
+             callContext.getUpdatedDate());
+    }
+
+    public CallContext toCallContext() {
+        // TODO - can't go back to CallContext (need to extract internal APIs first)
+        return new DefaultCallContext(null, userName, callOrigin, userType, reasonCode, comment, userToken, createdDate, updatedDate);
+    }
+
+    public UUID getUserToken() {
+        return userToken;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public CallOrigin getCallOrigin() {
+        return callOrigin;
+    }
+
+    public UserType getUserType() {
+        return userType;
+    }
+
+    public String getReasonCode() {
+        return reasonCode;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("InternalCallContext");
+        sb.append("{userToken=").append(userToken);
+        sb.append(", userName='").append(userName).append('\'');
+        sb.append(", callOrigin=").append(callOrigin);
+        sb.append(", userType=").append(userType);
+        sb.append(", reasonCode='").append(reasonCode).append('\'');
+        sb.append(", comment='").append(comment).append('\'');
+        sb.append(", createdDate=").append(createdDate);
+        sb.append(", updatedDate=").append(updatedDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+
+        final InternalCallContext that = (InternalCallContext) o;
+
+        if (callOrigin != that.callOrigin) {
+            return false;
+        }
+        if (comment != null ? !comment.equals(that.comment) : that.comment != null) {
+            return false;
+        }
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) {
+            return false;
+        }
+        if (reasonCode != null ? !reasonCode.equals(that.reasonCode) : that.reasonCode != null) {
+            return false;
+        }
+        if (updatedDate != null ? !updatedDate.equals(that.updatedDate) : that.updatedDate != null) {
+            return false;
+        }
+        if (userName != null ? !userName.equals(that.userName) : that.userName != null) {
+            return false;
+        }
+        if (userToken != null ? !userToken.equals(that.userToken) : that.userToken != null) {
+            return false;
+        }
+        if (userType != that.userType) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (userToken != null ? userToken.hashCode() : 0);
+        result = 31 * result + (userName != null ? userName.hashCode() : 0);
+        result = 31 * result + (callOrigin != null ? callOrigin.hashCode() : 0);
+        result = 31 * result + (userType != null ? userType.hashCode() : 0);
+        result = 31 * result + (reasonCode != null ? reasonCode.hashCode() : 0);
+        result = 31 * result + (comment != null ? comment.hashCode() : 0);
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        result = 31 * result + (updatedDate != null ? updatedDate.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
new file mode 100644
index 0000000..cbadb35
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.util.clock.Clock;
+
+public class InternalCallContextFactory {
+
+    private static final Logger log = LoggerFactory.getLogger(InternalCallContextFactory.class);
+
+    public static final UUID INTERNAL_TENANT_ID = new UUID(0L, 0L);
+    public static final long INTERNAL_TENANT_RECORD_ID = 0L;
+
+    private final CallContextSqlDao callContextSqlDao;
+    private final Clock clock;
+
+    @Inject
+    public InternalCallContextFactory(final IDBI dbi, final Clock clock) {
+        this.callContextSqlDao = dbi.onDemand(CallContextSqlDao.class);
+        this.clock = clock;
+    }
+
+    // Internal use only (notification queue, etc.) - no tenant for now
+    public InternalTenantContext createInternalTenantContext() {
+        return createInternalTenantContext(INTERNAL_TENANT_RECORD_ID, null);
+    }
+
+    // Used for r/o or update/delete operations - we don't need the account id in that case
+    public InternalTenantContext createInternalTenantContext(final TenantContext context) {
+        return createInternalTenantContext(getTenantRecordId(context), null);
+    }
+
+    // Used for r/w operations - we need the account id to populate the account_record_id field
+    public InternalTenantContext createInternalTenantContext(final UUID accountId, final TenantContext context) {
+        return createInternalTenantContext(getTenantRecordId(context), getAccountRecordId(accountId));
+    }
+
+    // Internal use only (notification queue, etc.) - no tenant for now
+    public InternalCallContext createInternalCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken) {
+        return createInternalCallContext(INTERNAL_TENANT_RECORD_ID, null, new DefaultCallContext(INTERNAL_TENANT_ID, userName, callOrigin, userType, userToken, clock));
+    }
+
+    // Used for r/o or update/delete operations - we don't need the account id in that case
+    // TODO - more work is needed for this statement to hold (especially for junction, overdue, custom fields and tags)
+    public InternalCallContext createInternalCallContext(final CallContext context) {
+        return createInternalCallContext(getTenantRecordId(context), null, context);
+    }
+
+    // Used for r/w operations - we need the account id to populate the account_record_id field
+    public InternalCallContext createInternalCallContext(final UUID accountId, final CallContext context) {
+        return createInternalCallContext(getTenantRecordId(context), getAccountRecordId(accountId), context);
+    }
+
+    private InternalTenantContext createInternalTenantContext(final Long tenantRecordId, @Nullable final Long accountRecordId) {
+        return new InternalTenantContext(tenantRecordId, accountRecordId);
+    }
+
+    private InternalCallContext createInternalCallContext(final Long tenantRecordId, @Nullable final Long accountRecordId, final CallContext context) {
+        return new InternalCallContext(tenantRecordId, accountRecordId, context);
+    }
+
+    private Long getTenantRecordId(final TenantContext context) {
+        // Default to single default tenant (e.g. single tenant mode)
+        if (context.getTenantId() == null) {
+            return INTERNAL_TENANT_RECORD_ID;
+        } else {
+            return callContextSqlDao.getTenantRecordId(context.getTenantId().toString());
+        }
+    }
+
+    private Long getAccountRecordId(final UUID accountId) {
+        return callContextSqlDao.getAccountRecordId(accountId.toString());
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java
new file mode 100644
index 0000000..5454264
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import javax.annotation.Nullable;
+
+/**
+ * Internal use only
+ */
+public class InternalTenantContext {
+
+    protected final Long tenantRecordId;
+    protected final Long accountRecordId;
+
+    public InternalTenantContext(final Long tenantRecordId, @Nullable final Long accountRecordId) {
+        this.tenantRecordId = tenantRecordId;
+        this.accountRecordId = accountRecordId;
+    }
+
+    public InternalTenantContext(final long defaultTenantRecordId) {
+        this(defaultTenantRecordId, null);
+    }
+
+    public TenantContext toTenantContext() {
+        return new DefaultTenantContext();
+    }
+
+    public Long getAccountRecordId() {
+        return accountRecordId;
+    }
+
+    public Long getTenantRecordId() {
+        return tenantRecordId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("InternalTenantContext");
+        sb.append("{accountRecordId=").append(accountRecordId);
+        sb.append(", tenantRecordId=").append(tenantRecordId);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final InternalTenantContext that = (InternalTenantContext) o;
+
+        if (accountRecordId != null ? !accountRecordId.equals(that.accountRecordId) : that.accountRecordId != null) {
+            return false;
+        }
+        if (tenantRecordId != null ? !tenantRecordId.equals(that.tenantRecordId) : that.tenantRecordId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountRecordId != null ? accountRecordId.hashCode() : 0;
+        result = 31 * result + (tenantRecordId != null ? tenantRecordId.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContextBinder.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContextBinder.java
new file mode 100644
index 0000000..0349be5
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContextBinder.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.callcontext;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Types;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.util.callcontext.InternalTenantContextBinder.InternalTenantContextBinderFactory;
+
+@BindingAnnotation(InternalTenantContextBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface InternalTenantContextBinder {
+
+    public static class InternalTenantContextBinderFactory implements BinderFactory {
+
+        @Override
+        public Binder build(final Annotation annotation) {
+            return new Binder<InternalTenantContextBinder, InternalTenantContext>() {
+                @Override
+                public void bind(final SQLStatement q, final InternalTenantContextBinder bind, final InternalTenantContext context) {
+                    if (context.getTenantRecordId() == null) {
+                        // TODO - shouldn't be null, but for now...
+                        q.bindNull("tenantRecordId", Types.INTEGER);
+                    } else {
+                        q.bind("tenantRecordId", context.getTenantRecordId());
+                    }
+
+                    if (context.getAccountRecordId() == null) {
+                        q.bindNull("accountRecordId", Types.INTEGER);
+                    } else {
+                        q.bind("accountRecordId", context.getAccountRecordId());
+                    }
+
+                    if (context instanceof InternalCallContext) {
+                        final InternalCallContext callContext = (InternalCallContext) context;
+                        q.bind("userName", callContext.getUserName());
+                        if (callContext.getCreatedDate() == null) {
+                            q.bindNull("createdDate", Types.DATE);
+                        } else {
+                            q.bind("createdDate", callContext.getCreatedDate().toDate());
+                        }
+                        if (callContext.getUpdatedDate() == null) {
+                            q.bindNull("updatedDate", Types.DATE);
+                        } else {
+                            q.bind("updatedDate", callContext.getUpdatedDate().toDate());
+                        }
+                        q.bind("reasonCode", callContext.getReasonCode());
+                        q.bind("comment", callContext.getComment());
+                        q.bind("userToken", (callContext.getUserToken() != null) ? callContext.getUserToken().toString() : null);
+                    }
+                }
+            };
+        }
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
index 4ab9e66..a60f2d7 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
@@ -19,17 +19,12 @@ package com.ning.billing.util.callcontext;
 import org.joda.time.DateTime;
 
 public class MigrationCallContext extends CallContextBase {
+
     private final DateTime createdDate;
     private final DateTime updatedDate;
 
-    public MigrationCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final DateTime createdDate, final DateTime updatedDate) {
-        super(userName, callOrigin, userType);
-        this.createdDate = createdDate;
-        this.updatedDate = updatedDate;
-    }
-
     public MigrationCallContext(final CallContext context, final DateTime createdDate, final DateTime updatedDate) {
-        super(context.getUserName(), context.getCallOrigin(), context.getUserType());
+        super(context.getTenantId(), context.getUserName(), context.getCallOrigin(), context.getUserType());
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
     }
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
index ae772a6..d5a7cfa 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
@@ -16,10 +16,10 @@
 
 package com.ning.billing.util.config;
 
+import java.net.URI;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
-import java.net.URI;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public abstract class ValidatingConfig<Context> {
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
index b182b7c..b3349ea 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.util.config;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -24,9 +28,6 @@ import javax.xml.transform.TransformerException;
 import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java b/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
index 205d449..6763c09 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
@@ -16,6 +16,15 @@
 
 package com.ning.billing.util.config;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.SchemaOutputResolver;
@@ -27,14 +36,6 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
 
 import org.w3c.dom.Document;
 
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLWriter.java b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
index 001b6c9..1569c8c 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
@@ -16,9 +16,10 @@
 
 package com.ning.billing.util.config;
 
+import java.io.ByteArrayOutputStream;
+
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
-import java.io.ByteArrayOutputStream;
 
 public class XMLWriter<T> {
     private static final int MAX_XML_SIZE_IN_BYTES = 100000;
diff --git a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
index 1c09e90..ec836b8 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
@@ -20,28 +20,35 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.inject.Inject;
+
 public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
+
+    private final InternalCallContextFactory internalCallContextFactory;
     private final CustomFieldDao customFieldDao;
 
     @Inject
-    public DefaultCustomFieldUserApi(final CustomFieldDao customFieldDao) {
+    public DefaultCustomFieldUserApi(final InternalCallContextFactory internalCallContextFactory, final CustomFieldDao customFieldDao) {
+        this.internalCallContextFactory = internalCallContextFactory;
         this.customFieldDao = customFieldDao;
     }
 
     @Override
-    public Map<String, CustomField> getCustomFields(final UUID objectId, final ObjectType objectType) {
-        return customFieldDao.loadEntities(objectId, objectType);
+    public Map<String, CustomField> getCustomFields(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+        return customFieldDao.loadEntities(objectId, objectType, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
     public void saveCustomFields(final UUID objectId, final ObjectType objectType, final List<CustomField> fields, final CallContext context) {
-        customFieldDao.saveEntities(objectId, objectType, fields, context);
+        // TODO accountId?
+        customFieldDao.saveEntities(objectId, objectType, fields, internalCallContextFactory.createInternalCallContext(context));
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
index 56326df..1f66082 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
@@ -19,13 +19,16 @@ package com.ning.billing.util.customfield.dao;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.google.inject.Inject;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.dao.AuditedCollectionDaoBase;
 import com.ning.billing.util.dao.TableName;
 import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlDao;
 
+import com.google.inject.Inject;
+
 public class AuditedCustomFieldDao extends AuditedCollectionDaoBase<CustomField, String> implements CustomFieldDao {
+
     private final CustomFieldSqlDao dao;
 
     @Inject
@@ -34,7 +37,7 @@ public class AuditedCustomFieldDao extends AuditedCollectionDaoBase<CustomField,
     }
 
     @Override
-    protected TableName getTableName() {
+    protected TableName getTableName(final InternalTenantContext context) {
         return TableName.CUSTOM_FIELD_HISTORY;
     }
 
@@ -44,73 +47,73 @@ public class AuditedCustomFieldDao extends AuditedCollectionDaoBase<CustomField,
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<CustomField> transmogrifyDao(final Transmogrifier transactionalDao) {
+    protected UpdatableEntityCollectionSqlDao<CustomField> transmogrifyDao(final Transmogrifier transactionalDao, InternalTenantContext context) {
         return transactionalDao.become(CustomFieldSqlDao.class);
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<CustomField> getSqlDao() {
+    protected UpdatableEntityCollectionSqlDao<CustomField> getSqlDao(final InternalTenantContext context) {
         return dao;
     }
 
     @Override
-    protected String getKey(final CustomField entity) {
+    protected String getKey(final CustomField entity, final InternalTenantContext context) {
         return entity.getName();
     }
 
-//    @Override
-//    public void saveEntitiesFromTransaction(Transmogrifier dao, UUID objectId, ObjectType objectType, List<CustomField> fields, CallContext context) {
-//        CustomFieldSqlDao customFieldSqlDao = dao.become(CustomFieldSqlDao.class);
-//
-//        // get list of existing fields
-//        List<CustomField> existingFields = customFieldSqlDao.load(objectId.toString(), objectType);
-//        List<CustomField> fieldsToUpdate = new ArrayList<CustomField>();
-//
-//        // sort into fields to update (fieldsToUpdate), fields to add (fields), and fields to delete (existingFields)
-//        Iterator<CustomField> fieldIterator = fields.iterator();
-//        while (fieldIterator.hasNext()) {
-//            CustomField field = fieldIterator.next();
-//
-//            Iterator<CustomField> existingFieldIterator = existingFields.iterator();
-//            while (existingFieldIterator.hasNext()) {
-//                CustomField existingField = existingFieldIterator.next();
-//                if (field.getName().equals(existingField.getName())) {
-//                    // if the tagStore match, remove from both lists
-//                    fieldsToUpdate.add(field);
-//                    fieldIterator.remove();
-//                    existingFieldIterator.remove();
-//                }
-//            }
-//        }
-//
-//        customFieldSqlDao.batchInsertFromTransaction(objectId.toString(), objectType, fields, context);
-//        customFieldSqlDao.batchUpdateFromTransaction(objectId.toString(), objectType, fieldsToUpdate, context);
-//
-//        // get all custom fields (including those that are about to be deleted) from the database in order to get the record ids
-//        List<Mapper> recordIds = customFieldSqlDao.getRecordIds(objectId.toString(), objectType);
-//        Map<UUID, Long> recordIdMap = new HashMap<UUID, Long>();
-//        for (Mapper recordId : recordIds) {
-//            recordIdMap.put(recordId.getId(), recordId.getRecordId());
-//        }
-//
-//        customFieldSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingFields, context);
-//
-//        List<MappedEntity<CustomField>> fieldHistories = new ArrayList<MappedEntity<CustomField>>();
-//        fieldHistories.addAll(convertToHistory(fields, recordIdMap, ChangeType.INSERT));
-//        fieldHistories.addAll(convertToHistory(fieldsToUpdate, recordIdMap, ChangeType.UPDATE));
-//        fieldHistories.addAll(convertToHistory(existingFields, recordIdMap, ChangeType.DELETE));
-//
-//        customFieldSqlDao.batchAddHistoryFromTransaction(objectId.toString(), objectType, fieldHistories, context);
-//        customFieldSqlDao.batchInsertAuditLogFromTransaction(TableName.CUSTOM_FIELD_HISTORY, objectId.toString(), objectType, fieldHistories, context);
-//    }
-//
-//    private List<MappedEntity<CustomField>> convertToHistory(List<CustomField> fields, Map<UUID, Long> recordIds, ChangeType changeType) {
-//        List<MappedEntity<CustomField>> result = new ArrayList<MappedEntity<CustomField>>();
-//
-//        for (CustomField field : fields) {
-//            result.add(new MappedEntity<CustomField>(recordIds.get(field.getId()), field, changeType));
-//        }
-//
-//        return result;
-//    }
+    //    @Override
+    //    public void saveEntitiesFromTransaction(Transmogrifier dao, UUID objectId, ObjectType objectType, List<CustomField> fields, CallContext context) {
+    //        CustomFieldSqlDao customFieldSqlDao = dao.become(CustomFieldSqlDao.class);
+    //
+    //        // get list of existing fields
+    //        List<CustomField> existingFields = customFieldSqlDao.load(objectId.toString(), objectType);
+    //        List<CustomField> fieldsToUpdate = new ArrayList<CustomField>();
+    //
+    //        // sort into fields to update (fieldsToUpdate), fields to add (fields), and fields to delete (existingFields)
+    //        Iterator<CustomField> fieldIterator = fields.iterator();
+    //        while (fieldIterator.hasNext()) {
+    //            CustomField field = fieldIterator.next();
+    //
+    //            Iterator<CustomField> existingFieldIterator = existingFields.iterator();
+    //            while (existingFieldIterator.hasNext()) {
+    //                CustomField existingField = existingFieldIterator.next();
+    //                if (field.getName().equals(existingField.getName())) {
+    //                    // if the tagStore match, remove from both lists
+    //                    fieldsToUpdate.add(field);
+    //                    fieldIterator.remove();
+    //                    existingFieldIterator.remove();
+    //                }
+    //            }
+    //        }
+    //
+    //        customFieldSqlDao.batchInsertFromTransaction(objectId.toString(), objectType, fields, context);
+    //        customFieldSqlDao.batchUpdateFromTransaction(objectId.toString(), objectType, fieldsToUpdate, context);
+    //
+    //        // get all custom fields (including those that are about to be deleted) from the database in order to get the record ids
+    //        List<Mapper> recordIds = customFieldSqlDao.getRecordIds(objectId.toString(), objectType);
+    //        Map<UUID, Long> recordIdMap = new HashMap<UUID, Long>();
+    //        for (Mapper recordId : recordIds) {
+    //            recordIdMap.put(recordId.getId(), recordId.getRecordId());
+    //        }
+    //
+    //        customFieldSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingFields, context);
+    //
+    //        List<MappedEntity<CustomField>> fieldHistories = new ArrayList<MappedEntity<CustomField>>();
+    //        fieldHistories.addAll(convertToHistory(fields, recordIdMap, ChangeType.INSERT));
+    //        fieldHistories.addAll(convertToHistory(fieldsToUpdate, recordIdMap, ChangeType.UPDATE));
+    //        fieldHistories.addAll(convertToHistory(existingFields, recordIdMap, ChangeType.DELETE));
+    //
+    //        customFieldSqlDao.batchAddHistoryFromTransaction(objectId.toString(), objectType, fieldHistories, context);
+    //        customFieldSqlDao.batchInsertAuditLogFromTransaction(TableName.CUSTOM_FIELD_HISTORY, objectId.toString(), objectType, fieldHistories, context);
+    //    }
+    //
+    //    private List<MappedEntity<CustomField>> convertToHistory(List<CustomField> fields, Map<UUID, Long> recordIds, ChangeType changeType) {
+    //        List<MappedEntity<CustomField>> result = new ArrayList<MappedEntity<CustomField>>();
+    //
+    //        for (CustomField field : fields) {
+    //            result.add(new MappedEntity<CustomField>(recordIds.get(field.getId()), field, changeType));
+    //        }
+    //
+    //        return result;
+    //    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
index 93fd002..e08c569 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -26,8 +26,8 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.ObjectType;
@@ -37,32 +37,33 @@ import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlD
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(CustomFieldMapper.class)
 public interface CustomFieldSqlDao extends UpdatableEntityCollectionSqlDao<CustomField>,
-        Transactional<CustomFieldSqlDao>, Transmogrifier {
+                                           Transactional<CustomFieldSqlDao>, Transmogrifier {
+
     @Override
     @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch
     public void addHistoryFromTransaction(@Bind("objectId") final String objectId,
                                           @ObjectTypeBinder final ObjectType objectType,
                                           @CustomFieldHistoryBinder final List<EntityHistory<CustomField>> entities,
-                                          @CallContextBinder final CallContext context);
+                                          @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
index 2577ff2..18388cd 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
@@ -22,16 +22,18 @@ import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.Entity;
 
 public interface AuditedCollectionDao<T extends Entity> {
+
     void saveEntitiesFromTransaction(Transmogrifier transactionalDao, UUID objectId, ObjectType objectType,
-                                     List<T> entities, CallContext context);
+                                     List<T> entities, InternalCallContext context);
 
-    void saveEntities(UUID objectId, ObjectType objectType, List<T> entities, CallContext context);
+    void saveEntities(UUID objectId, ObjectType objectType, List<T> entities, InternalCallContext context);
 
-    Map<String, T> loadEntities(UUID objectId, ObjectType objectType);
+    Map<String, T> loadEntities(UUID objectId, ObjectType objectType, InternalTenantContext context);
 
-    Map<String, T> loadEntitiesFromTransaction(Transmogrifier dao, UUID objectId, ObjectType objectType);
+    Map<String, T> loadEntitiesFromTransaction(Transmogrifier dao, UUID objectId, ObjectType objectType, InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
index e01e6a9..ffdcb09 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.dao;
 
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -27,13 +26,16 @@ import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.google.common.collect.Sets;
 import com.ning.billing.util.ChangeType;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.Entity;
 import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlDao;
 
+import com.google.common.collect.Sets;
+
 public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements AuditedCollectionDao<T> {
+
     /**
      * Returns equivalence object for the entities, so that dao
      * can figure out if entities have changed (UPDATE statement) or
@@ -61,11 +63,12 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
      * @param context          the current content
      */
     @Override
-    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType, final List<T> newEntities, final CallContext context) {
-        final UpdatableEntityCollectionSqlDao<T> dao = transmogrifyDao(transactionalDao);
+    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType,
+                                            final List<T> newEntities, final InternalCallContext context) {
+        final UpdatableEntityCollectionSqlDao<T> dao = transmogrifyDao(transactionalDao, context);
 
         // Get list of all existing entities for this parent object, e.g. find all email addresses for this account
-        final List<T> currentEntities = dao.load(objectId.toString(), objectType);
+        final List<T> currentEntities = dao.load(objectId.toString(), objectType, context);
 
         // Compute the list of objects to add, remove and/or update
         final Map<V, T> currentObjs = new HashMap<V, T>(currentEntities.size());
@@ -111,7 +114,7 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
         }
 
         // Find all pairs <entity id, record id> (including those that are about to be deleted) for this parent object
-        final List<Mapper<UUID, Long>> recordIds = dao.getRecordIds(objectId.toString(), objectType);
+        final List<Mapper<UUID, Long>> recordIds = dao.getRecordIds(objectId.toString(), objectType, context);
         // Flip the map to look up the record id associated with an entity id
         final Map<UUID, Long> recordIdMap = convertToHistoryMap(recordIds, objectType);
 
@@ -126,41 +129,41 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
         entityHistories.addAll(convertToHistory(objsToUpdate, recordIdMap, ChangeType.UPDATE));
         entityHistories.addAll(convertToHistory(objsToRemove, recordIdMap, ChangeType.DELETE));
 
-        final Long maxHistoryRecordId = dao.getMaxHistoryRecordId();
+        final Long maxHistoryRecordId = dao.getMaxHistoryRecordId(context);
         // Save the records in the history table
         dao.addHistoryFromTransaction(objectId.toString(), objectType, entityHistories, context);
 
         // We have to fetch history record ids to update audit log
-        final List<Mapper<Long, Long>> historyRecordIds = dao.getHistoryRecordIds(maxHistoryRecordId);
+        final List<Mapper<Long, Long>> historyRecordIds = dao.getHistoryRecordIds(maxHistoryRecordId, context);
         final Map<Long, Long> historyRecordIdMap = convertToAuditMap(historyRecordIds);
-        final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap);
+        final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap, context);
 
         // Save an entry in the audit log
         dao.insertAuditFromTransaction(entityAudits, context);
     }
 
     @Override
-    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<T> entities, final CallContext context) {
-        this.saveEntitiesFromTransaction(getSqlDao(), objectId, objectType, entities, context);
+    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<T> entities, final InternalCallContext context) {
+        this.saveEntitiesFromTransaction(getSqlDao(context), objectId, objectType, entities, context);
     }
 
     @Override
-    public Map<String, T> loadEntities(final UUID objectId, final ObjectType objectType) {
-        final UpdatableEntityCollectionSqlDao<T> thisDao = getSqlDao();
-        return getMap(thisDao, objectId, objectType);
+    public Map<String, T> loadEntities(final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
+        final UpdatableEntityCollectionSqlDao<T> thisDao = getSqlDao(context);
+        return getMap(thisDao, objectId, objectType, context);
     }
 
     @Override
-    public Map<String, T> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType) {
-        final UpdatableEntityCollectionSqlDao<T> thisDao = transmogrifyDao(dao);
-        return getMap(thisDao, objectId, objectType);
+    public Map<String, T> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
+        final UpdatableEntityCollectionSqlDao<T> thisDao = transmogrifyDao(dao, context);
+        return getMap(thisDao, objectId, objectType, context);
     }
 
-    private Map<String, T> getMap(final UpdatableEntityCollectionSqlDao<T> dao, final UUID objectId, final ObjectType objectType) {
-        final List<T> entities = dao.load(objectId.toString(), objectType);
+    private Map<String, T> getMap(final UpdatableEntityCollectionSqlDao<T> dao, final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
+        final List<T> entities = dao.load(objectId.toString(), objectType, context);
         final Map<String, T> results = new HashMap<String, T>();
         for (final T entity : entities) {
-            results.put(getKey(entity), entity);
+            results.put(getKey(entity, context), entity);
         }
         return results;
     }
@@ -181,13 +184,13 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
         return histories;
     }
 
-    protected List<EntityAudit> convertToAudits(final List<EntityHistory<T>> histories, final Map<Long, Long> historyRecordIds) {
+    protected List<EntityAudit> convertToAudits(final List<EntityHistory<T>> histories, final Map<Long, Long> historyRecordIds, final InternalTenantContext context) {
         final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
         for (final EntityHistory<T> history : histories) {
             final Long recordId = history.getValue();
             final Long historyRecordId = historyRecordIds.get(recordId);
-            audits.add(new EntityAudit(getTableName(), historyRecordId, history.getChangeType()));
+            audits.add(new EntityAudit(getTableName(context), historyRecordId, history.getChangeType()));
         }
 
         return audits;
@@ -217,11 +220,11 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
         return historyRecordIdMap;
     }
 
-    protected abstract TableName getTableName();
+    protected abstract TableName getTableName(InternalTenantContext context);
 
-    protected abstract UpdatableEntityCollectionSqlDao<T> transmogrifyDao(Transmogrifier transactionalDao);
+    protected abstract UpdatableEntityCollectionSqlDao<T> transmogrifyDao(Transmogrifier transactionalDao, InternalTenantContext context);
 
-    protected abstract UpdatableEntityCollectionSqlDao<T> getSqlDao();
+    protected abstract UpdatableEntityCollectionSqlDao<T> getSqlDao(InternalTenantContext context);
 
-    protected abstract String getKey(T entity);
+    protected abstract String getKey(T entity, InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java b/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
index 188ea71..f6d0d6c 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
@@ -44,7 +44,8 @@ public class AuditLogMapper extends MapperBase implements ResultSetMapper<AuditL
         final UUID userToken = getUUID(r, "user_token");
 
         final EntityAudit entityAudit = new EntityAudit(TableName.valueOf(tableName), recordId, ChangeType.valueOf(changeType));
-        final CallContext callContext = new DefaultCallContext(changedBy, changeDate, reasonCode, comments, userToken);
+        // TODO - we have the tenant_record_id but not the tenant id here
+        final CallContext callContext = new DefaultCallContext(null, changedBy, changeDate, reasonCode, comments, userToken);
         return new DefaultAuditLog(entityAudit, callContext);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
index 341b448..a4540b6 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
@@ -27,8 +27,9 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
 import com.ning.billing.util.audit.AuditLog;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(AuditLogMapper.class)
@@ -36,28 +37,31 @@ public interface AuditSqlDao {
 
     @SqlUpdate
     public void insertAuditFromTransaction(@AuditBinder final EntityAudit audit,
-                                           @CallContextBinder final CallContext context);
+                                           @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch(transactional = false)
     public void insertAuditFromTransaction(@AuditBinder final List<EntityAudit> audit,
-                                           @CallContextBinder final CallContext context);
+                                           @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     public List<AuditLog> getAuditLogsForRecordId(@TableNameBinder final TableName tableName,
-                                                  @Bind("recordId") final long recordId);
+                                                  @Bind("recordId") final long recordId,
+                                                  @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public Long getRecordId(@Bind("id") final String id);
+    public Long getRecordId(@Bind("id") final String id, @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     public Long getRecordIdForTable(@Define("tableName") final String tableName,
-                                    @Bind("id") final String id);
+                                    @Bind("id") final String id,
+                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     public List<Long> getHistoryRecordIdsForTable(@Define("tableName") final String tableName,
-                                                  @Bind("id") final String id);
+                                                  @Bind("id") final String id,
+                                                  @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public Long getHistoryRecordId(@Bind("recordId") final Long recordId);
-
+    public Long getHistoryRecordId(@Bind("recordId") final Long recordId,
+                                   @InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
index 2ab74f6..7d92a65 100644
--- a/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
@@ -21,17 +21,19 @@ import java.util.List;
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.entity.Entity;
 
 public interface CollectionHistorySqlDao<T extends Entity> {
+
     @SqlBatch
     public void addHistoryFromTransaction(String objectId, ObjectType objectType,
                                           List<EntityHistory<T>> histories,
-                                          CallContext context);
+                                          @InternalTenantContextBinder InternalCallContext context);
 
     @SqlUpdate
     public void addHistoryFromTransaction(String objectId, ObjectType objectType,
                                           EntityHistory<T> history,
-                                          CallContext context);
+                                          @InternalTenantContextBinder InternalCallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
index 19abc79..15a2ac5 100644
--- a/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
@@ -21,15 +21,16 @@ import java.util.List;
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.entity.Entity;
 
 public interface HistorySqlDao<T extends Entity> {
     @SqlBatch(transactional = false)
     public void batchAddHistoryFromTransaction(List<EntityHistory<T>> histories,
-                                               CallContext context);
+                                               @InternalTenantContextBinder InternalCallContext context);
 
     @SqlUpdate
     public void addHistoryFromTransaction(EntityHistory<T> history,
-                                          CallContext context);
+                                          @InternalTenantContextBinder InternalCallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/TableName.java b/util/src/main/java/com/ning/billing/util/dao/TableName.java
index 5bbf68c..84e9710 100644
--- a/util/src/main/java/com/ning/billing/util/dao/TableName.java
+++ b/util/src/main/java/com/ning/billing/util/dao/TableName.java
@@ -41,6 +41,7 @@ public enum TableName {
     REFUNDS("refunds", ObjectType.REFUND, REFUND_HISTORY),
     TAG_DEFINITIONS("tag_definitions", ObjectType.TAG_DEFINITION),
     TAG_HISTORY("tag_history"),
+    TENANT("tenants", ObjectType.TENANT),
     TAG("tags", TAG_HISTORY);
 
     private final String tableName;
diff --git a/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java b/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
index 2decb16..db1505a 100644
--- a/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
@@ -27,8 +27,9 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.Mapper;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.ObjectTypeBinder;
@@ -42,27 +43,30 @@ import com.ning.billing.util.entity.Entity;
  * @param <T>
  */
 public interface EntityCollectionSqlDao<T extends Entity> {
+
     @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     public List<T> load(@Bind("objectId") final String objectId,
-                        @ObjectTypeBinder final ObjectType objectType);
+                        @ObjectTypeBinder final ObjectType objectType,
+                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @RegisterMapper(RecordIdMapper.class)
     @SqlQuery
     public List<Mapper<UUID, Long>> getRecordIds(@Bind("objectId") final String objectId,
-                                                 @ObjectTypeBinder final ObjectType objectType);
+                                                 @ObjectTypeBinder final ObjectType objectType,
+                                                 @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public void test();
+    public void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java b/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
index 554120f..92d119f 100644
--- a/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
@@ -27,8 +27,8 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.CollectionHistorySqlDao;
 import com.ning.billing.util.dao.HistoryRecordIdMapper;
@@ -38,18 +38,20 @@ import com.ning.billing.util.dao.ObjectTypeBinder;
 import com.ning.billing.util.entity.Entity;
 
 public interface UpdatableEntityCollectionSqlDao<T extends Entity> extends EntityCollectionSqlDao<T>,
-        CollectionHistorySqlDao<T>,
-        AuditSqlDao, CloseMe, Transmogrifier {
+                                                                           CollectionHistorySqlDao<T>,
+                                                                           AuditSqlDao, CloseMe, Transmogrifier {
+
     @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public long getMaxHistoryRecordId();
+    public long getMaxHistoryRecordId(@InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     @RegisterMapper(HistoryRecordIdMapper.class)
-    public List<Mapper<Long, Long>> getHistoryRecordIds(@Bind("maxHistoryRecordId") final long maxHistoryRecordId);
+    public List<Mapper<Long, Long>> getHistoryRecordIds(@Bind("maxHistoryRecordId") final long maxHistoryRecordId,
+                                                        @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntityDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntityDao.java
index 1d2d173..3d4ab80 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntityDao.java
@@ -19,16 +19,20 @@ package com.ning.billing.util.entity.dao;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.Entity;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
 public interface EntityDao<T extends Entity> {
-    public void create(final T entity, final CallContext context) throws EntityPersistenceException;
 
-    public T getById(final UUID id);
+    public void create(T entity, InternalCallContext context) throws EntityPersistenceException;
 
-    public List<T> get();
+    public Long getRecordId(UUID id, InternalTenantContext context);
 
-    public void test();
+    public T getById(UUID id, InternalTenantContext context);
+
+    public List<T> get(InternalTenantContext context);
+
+    public void test(InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
index 3db47da..9dd5589 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
@@ -23,30 +23,37 @@ import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.entity.Entity;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
 public interface EntitySqlDao<T extends Entity> {
+
     @SqlUpdate
-    public void create(@BindBean final T entity, @CallContextBinder final CallContext context) throws EntityPersistenceException;
+    public void create(@BindBean final T entity,
+                       @InternalTenantContextBinder final InternalCallContext context) throws EntityPersistenceException;
 
     @SqlQuery
-    public T getById(@Bind("id") final String id);
+    public T getById(@Bind("id") final String id,
+                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public T getByRecordId(@Bind("recordId") final Long recordId);
+    public T getByRecordId(@Bind("recordId") final Long recordId,
+                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public Long getRecordId(@Bind("id") final String id);
+    public Long getRecordId(@Bind("id") final String id,
+                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public Long getHistoryRecordId(@Bind("recordId") final Long recordId);
+    public Long getHistoryRecordId(@Bind("recordId") final Long recordId,
+                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public List<T> get();
+    public List<T> get(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public void test();
+    public void test(@InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
index 2dedcbf..e04c33c 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.entity.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.entity.UpdatableEntity;
 
 public interface UpdatableEntityDao<T extends UpdatableEntity> extends EntityDao<T> {
-    public void update(T entity, CallContext context) throws EntityPersistenceException;
+
+    public void update(T entity, InternalCallContext context) throws EntityPersistenceException;
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
index e8a2f2e..47e8e90 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
@@ -18,17 +18,20 @@ package com.ning.billing.util.entity.dao;
 
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.entity.Entity;
 
-// this interface needs to be extended by an interface that provides (externalized) sql and object binders and mappers
+// This interface needs to be extended by an interface that provides (externalized) sql and object binders and mappers
 public interface UpdatableEntitySqlDao<T extends Entity> extends EntitySqlDao<T>, AuditSqlDao {
+
     @SqlUpdate
-    public void update(final T entity, final CallContext context);
+    public void update(final T entity,
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void insertHistoryFromTransaction(final EntityHistory<T> account,
-                                             final CallContext context);
+                                             @InternalTenantContextBinder final InternalCallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/glue/BusModule.java b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
index f27e1c0..3d2261b 100644
--- a/util/src/main/java/com/ning/billing/util/glue/BusModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
@@ -18,7 +18,6 @@ package com.ning.billing.util.glue;
 
 import org.skife.config.ConfigurationObjectFactory;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
@@ -26,6 +25,8 @@ import com.ning.billing.util.bus.InMemoryBus;
 import com.ning.billing.util.bus.PersistentBus;
 import com.ning.billing.util.bus.PersistentBusConfig;
 
+import com.google.inject.AbstractModule;
+
 public class BusModule extends AbstractModule {
 
     private final BusType type;
diff --git a/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
index 6c0cca0..a287c37 100644
--- a/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 
+import com.google.inject.AbstractModule;
+
 public class CallContextModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/util/src/main/java/com/ning/billing/util/glue/ClockModule.java b/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
index 187a500..3f5d796 100644
--- a/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.inject.AbstractModule;
+
 public class ClockModule extends AbstractModule {
 
     @Override
diff --git a/util/src/main/java/com/ning/billing/util/glue/CustomFieldModule.java b/util/src/main/java/com/ning/billing/util/glue/CustomFieldModule.java
index 2bacba5..97fbec0 100644
--- a/util/src/main/java/com/ning/billing/util/glue/CustomFieldModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/CustomFieldModule.java
@@ -16,12 +16,13 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.customfield.api.DefaultCustomFieldUserApi;
 import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldDao;
 
+import com.google.inject.AbstractModule;
+
 public class CustomFieldModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java b/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
index a6e6f66..7d976f5 100644
--- a/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
 
+import com.google.inject.AbstractModule;
+
 public class GlobalLockerModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/util/src/main/java/com/ning/billing/util/glue/NotificationQueueModule.java b/util/src/main/java/com/ning/billing/util/glue/NotificationQueueModule.java
index f0babf9..557a6e1 100644
--- a/util/src/main/java/com/ning/billing/util/glue/NotificationQueueModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/NotificationQueueModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.AbstractModule;
+
 public class NotificationQueueModule extends AbstractModule {
 
     @Override
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
index d1c763a..9a7ca81 100644
--- a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.tag.api.DefaultTagUserApi;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
@@ -24,6 +23,8 @@ import com.ning.billing.util.tag.dao.DefaultTagDefinitionDao;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
+import com.google.inject.AbstractModule;
+
 public class TagStoreModule extends AbstractModule {
     protected void installDaos() {
         bind(TagDefinitionDao.class).to(DefaultTagDefinitionDao.class).asEagerSingleton();
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
index 43629b1..0398a68 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
@@ -35,6 +35,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.notificationq.DefaultNotification;
@@ -49,30 +52,47 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
     //
     @SqlQuery
     @Mapper(NotificationSqlMapper.class)
-    public List<Notification> getReadyNotifications(@Bind("now") Date now, @Bind("owner") String owner, @Bind("max") int max, @Bind("queueName") String queueName);
+    public List<Notification> getReadyNotifications(@Bind("now") Date now,
+                                                    @Bind("owner") String owner,
+                                                    @Bind("max") int max,
+                                                    @Bind("queueName") String queueName,
+                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
     @Mapper(NotificationSqlMapper.class)
-    public List<Notification> getNotificationForAccountAndDate(@Bind("accountId") final String accountId, @Bind("effectiveDate") final Date effectiveDate);
+    public List<Notification> getNotificationForAccountAndDate(@Bind("accountId") final String accountId,
+                                                               @Bind("effectiveDate") final Date effectiveDate,
+                                                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public void removeNotification(@Bind("id") String id);
+    public void removeNotification(@Bind("id") String id,
+                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public int claimNotification(@Bind("owner") String owner, @Bind("nextAvailable") Date nextAvailable,
-                                 @Bind("id") String id, @Bind("now") Date now);
+    public int claimNotification(@Bind("owner") String owner,
+                                 @Bind("nextAvailable") Date nextAvailable,
+                                 @Bind("id") String id,
+                                 @Bind("now") Date now,
+                                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void clearNotification(@Bind("id") String id, @Bind("owner") String owner);
+    public void clearNotification(@Bind("id") String id,
+                                  @Bind("owner") String owner,
+                                  @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void removeNotificationsByKey(@Bind("notificationKey") String key);
+    public void removeNotificationsByKey(@Bind("notificationKey") String key,
+                                         @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void insertNotification(@Bind(binder = NotificationSqlDaoBinder.class) Notification evt);
+    public void insertNotification(@Bind(binder = NotificationSqlDaoBinder.class) Notification evt,
+                                   @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    public void insertClaimedHistory(@Bind("ownerId") String ownerId, @Bind("claimedDate") Date claimedDate, @Bind("notificationId") String notificationId);
+    public void insertClaimedHistory(@Bind("ownerId") String ownerId,
+                                     @Bind("claimedDate") Date claimedDate,
+                                     @Bind("notificationId") String notificationId,
+                                     @InternalTenantContextBinder final InternalCallContext context);
 
     public static class NotificationSqlDaoBinder extends BinderBase implements Binder<Bind, Notification> {
         @Override
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
index 246b187..197e366 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
@@ -29,25 +29,35 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.ning.billing.config.NotificationConfig;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 
 public class DefaultNotificationQueue extends NotificationQueueBase {
+
     private static final Logger log = LoggerFactory.getLogger(DefaultNotificationQueue.class);
 
     private final NotificationSqlDao dao;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     public DefaultNotificationQueue(final IDBI dbi, final Clock clock, final String svcName, final String queueName,
-                                    final NotificationQueueHandler handler, final NotificationConfig config) {
+                                    final NotificationQueueHandler handler, final NotificationConfig config,
+                                    final InternalCallContextFactory internalCallContextFactory) {
         super(clock, svcName, queueName, handler, config);
         this.dao = dbi.onDemand(NotificationSqlDao.class);
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
     public int doProcessEvents() {
+        final InternalCallContext context = createCallContext();
+
         logDebug("ENTER doProcessEvents");
-        final List<Notification> notifications = getReadyNotifications();
+        final List<Notification> notifications = getReadyNotifications(context);
         if (notifications.size() == 0) {
             logDebug("EXIT doProcessEvents");
             return 0;
@@ -62,7 +72,7 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
             final NotificationKey key = deserializeEvent(cur.getNotificationKeyClass(), cur.getNotificationKey());
             getHandler().handleReadyNotification(key, cur.getEffectiveDate());
             result++;
-            clearNotification(cur);
+            clearNotification(cur, context);
             logDebug("done handling notification %s, key = %s for time %s", cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
         }
 
@@ -70,50 +80,54 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
     }
 
     @Override
-    public void recordFutureNotification(final DateTime futureNotificationTime, final UUID accountId, final NotificationKey notificationKey) throws IOException {
-        recordFutureNotificationInternal(futureNotificationTime, accountId, notificationKey, dao);
+    public void recordFutureNotification(final DateTime futureNotificationTime,
+                                         final UUID accountId,
+                                         final NotificationKey notificationKey,
+                                         final InternalCallContext context) throws IOException {
+        recordFutureNotificationInternal(futureNotificationTime, accountId, notificationKey, dao, context);
     }
 
     @Override
     public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao,
                                                         final DateTime futureNotificationTime,
                                                         final UUID accountId,
-                                                        final NotificationKey notificationKey) throws IOException {
+                                                        final NotificationKey notificationKey,
+                                                        final InternalCallContext context) throws IOException {
         final NotificationSqlDao transactionalNotificationDao = transactionalDao.become(NotificationSqlDao.class);
-        recordFutureNotificationInternal(futureNotificationTime, accountId, notificationKey, transactionalNotificationDao);
+        recordFutureNotificationInternal(futureNotificationTime, accountId, notificationKey, transactionalNotificationDao, context);
     }
 
     private void recordFutureNotificationInternal(final DateTime futureNotificationTime,
-            final UUID accountId,
-            final NotificationKey notificationKey,
-
-                                                  final NotificationSqlDao thisDao) throws IOException {
+                                                  final UUID accountId,
+                                                  final NotificationKey notificationKey,
+                                                  final NotificationSqlDao thisDao,
+                                                  final InternalCallContext context) throws IOException {
         final String json = objectMapper.writeValueAsString(notificationKey);
         final Notification notification = new DefaultNotification(getFullQName(), getHostname(), notificationKey.getClass().getName(), json, accountId, futureNotificationTime);
-        thisDao.insertNotification(notification);
+        thisDao.insertNotification(notification, context);
     }
 
-    private void clearNotification(final Notification cleared) {
-        dao.clearNotification(cleared.getId().toString(), getHostname());
+    private void clearNotification(final Notification cleared, final InternalCallContext context) {
+        dao.clearNotification(cleared.getId().toString(), getHostname(), context);
     }
 
-    private List<Notification> getReadyNotifications() {
+    private List<Notification> getReadyNotifications(final InternalCallContext context) {
         final Date now = getClock().getUTCNow().toDate();
         final Date nextAvailable = getClock().getUTCNow().plus(CLAIM_TIME_MS).toDate();
-        final List<Notification> input = dao.getReadyNotifications(now, getHostname(), CLAIM_TIME_MS, getFullQName());
+        final List<Notification> input = dao.getReadyNotifications(now, getHostname(), CLAIM_TIME_MS, getFullQName(), context);
 
         final List<Notification> claimedNotifications = new ArrayList<Notification>();
         for (final Notification cur : input) {
             logDebug("about to claim notification %s,  key = %s for time %s",
                      cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
 
-            final boolean claimed = (dao.claimNotification(getHostname(), nextAvailable, cur.getId().toString(), now) == 1);
+            final boolean claimed = (dao.claimNotification(getHostname(), nextAvailable, cur.getId().toString(), now, context) == 1);
             logDebug("claimed notification %s, key = %s for time %s result = %s",
                      cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate(), claimed);
 
             if (claimed) {
                 claimedNotifications.add(cur);
-                dao.insertClaimedHistory(getHostname(), now, cur.getId().toString());
+                dao.insertClaimedHistory(getHostname(), now, cur.getId().toString(), context);
             }
         }
 
@@ -134,17 +148,21 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
     }
 
     @Override
-    public void removeNotificationsByKey(final NotificationKey notificationKey) {
-        dao.removeNotificationsByKey(notificationKey.toString());
+    public void removeNotificationsByKey(final NotificationKey notificationKey, final InternalCallContext context) {
+        dao.removeNotificationsByKey(notificationKey.toString(), context);
     }
 
     @Override
-    public List<Notification> getNotificationForAccountAndDate(final UUID accountId, final DateTime effectiveDate) {
-        return dao.getNotificationForAccountAndDate(accountId.toString(), effectiveDate.toDate());
+    public List<Notification> getNotificationForAccountAndDate(final UUID accountId, final DateTime effectiveDate, final InternalCallContext context) {
+        return dao.getNotificationForAccountAndDate(accountId.toString(), effectiveDate.toDate(), context);
     }
 
     @Override
-    public void removeNotification(UUID notificationId) {
-        dao.removeNotification(notificationId.toString());
+    public void removeNotification(final UUID notificationId, final InternalCallContext context) {
+        dao.removeNotification(notificationId.toString(), context);
+    }
+
+    private InternalCallContext createCallContext() {
+        return internalCallContextFactory.createInternalCallContext("NotificationQueue", CallOrigin.INTERNAL, UserType.SYSTEM, null);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
index 9949110..9cd3658 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
@@ -18,17 +18,21 @@ package com.ning.billing.util.notificationq;
 
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.Inject;
 import com.ning.billing.config.NotificationConfig;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class DefaultNotificationQueueService extends NotificationQueueServiceBase {
     private final IDBI dbi;
+    private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultNotificationQueueService(final IDBI dbi, final Clock clock) {
+    public DefaultNotificationQueueService(final IDBI dbi, final Clock clock, final InternalCallContextFactory internalCallContextFactory) {
         super(clock);
         this.dbi = dbi;
+        this.internalCallContextFactory = internalCallContextFactory;
     }
 
     @Override
@@ -36,6 +40,6 @@ public class DefaultNotificationQueueService extends NotificationQueueServiceBas
                                                                 final String queueName,
                                                                 final NotificationQueueHandler handler,
                                                                 final NotificationConfig config) {
-        return new DefaultNotificationQueue(dbi, clock, svcName, queueName, handler, config);
+        return new DefaultNotificationQueue(dbi, clock, svcName, queueName, handler, config, internalCallContextFactory);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
index 42cacea..1444425 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
@@ -23,6 +23,7 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.queue.QueueLifecycle;
 
 public interface NotificationQueue extends QueueLifecycle {
@@ -33,8 +34,11 @@ public interface NotificationQueue extends QueueLifecycle {
      * @param futureNotificationTime the time at which the notification is ready
      * @param notificationKey        the key for that notification
      */
-    public void recordFutureNotification(final DateTime futureNotificationTime, final UUID accountId, final NotificationKey notificationKey)
-        throws IOException;
+    public void recordFutureNotification(final DateTime futureNotificationTime,
+                                         final UUID accountId,
+                                         final NotificationKey notificationKey,
+                                         final InternalCallContext context)
+            throws IOException;
 
     /**
      * Record from within a transaction the need to be called back when the notification is ready
@@ -46,23 +50,22 @@ public interface NotificationQueue extends QueueLifecycle {
     public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao,
                                                         final DateTime futureNotificationTime,
                                                         final UUID accountId,
-                                                        final NotificationKey notificationKey)
-        throws IOException;
-
+                                                        final NotificationKey notificationKey,
+                                                        final InternalCallContext context)
+            throws IOException;
 
     /**
      * Remove all notifications associated with this key
-     *
-     * @param key
      */
-    public void removeNotificationsByKey(final NotificationKey notificationKey);
-
-
+    public void removeNotificationsByKey(final NotificationKey notificationKey,
+                                         final InternalCallContext context);
 
-    public List<Notification> getNotificationForAccountAndDate(final UUID accountId, final DateTime effectiveDate);
-
-    public void removeNotification(final UUID notificationId);
+    public List<Notification> getNotificationForAccountAndDate(final UUID accountId,
+                                                               final DateTime effectiveDate,
+                                                               final InternalCallContext context);
 
+    public void removeNotification(final UUID notificationId,
+                                   final InternalCallContext context);
 
     /**
      * This is only valid when the queue has been configured with isNotificationProcessingOff is true
@@ -86,6 +89,4 @@ public interface NotificationQueue extends QueueLifecycle {
      * @return the queue name associated
      */
     public String getQueueName();
-
-
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
index f39fc46..bf52f41 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
@@ -25,11 +25,12 @@ import java.util.TreeMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Joiner;
-import com.google.inject.Inject;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.common.base.Joiner;
+import com.google.inject.Inject;
+
 public abstract class NotificationQueueServiceBase implements NotificationQueueService {
     protected final Logger log = LoggerFactory.getLogger(DefaultNotificationQueueService.class);
 
diff --git a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
index 09bb1b5..e4d194b 100644
--- a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
+++ b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
@@ -22,7 +22,6 @@ import java.util.concurrent.TimeUnit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 import com.ning.billing.config.PersistentQueueConfig;
 import com.ning.billing.util.jackson.ObjectMapper;
 
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagService.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagService.java
index 0a1fa28..8e8cb71 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagService.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagService.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.tag.api;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.api.TagService;
 import com.ning.billing.util.api.TagUserApi;
 
+import com.google.inject.Inject;
+
 public class DefaultTagService implements TagService {
     private static final String TAG_DEFINITION_SERVICE_NAME = "tag-service";
 
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
index ce09032..87eba08 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
@@ -21,89 +21,98 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
+import com.google.inject.Inject;
+
 public class DefaultTagUserApi implements TagUserApi {
+
+    private final InternalCallContextFactory internalCallContextFactory;
     private final TagDefinitionDao tagDefinitionDao;
     private final TagDao tagDao;
 
     @Inject
-    public DefaultTagUserApi(final TagDefinitionDao tagDefinitionDao, final TagDao tagDao) {
+    public DefaultTagUserApi(final InternalCallContextFactory internalCallContextFactory, final TagDefinitionDao tagDefinitionDao, final TagDao tagDao) {
+        this.internalCallContextFactory = internalCallContextFactory;
         this.tagDefinitionDao = tagDefinitionDao;
         this.tagDao = tagDao;
     }
 
     @Override
-    public List<TagDefinition> getTagDefinitions() {
-        return tagDefinitionDao.getTagDefinitions();
+    public List<TagDefinition> getTagDefinitions(final TenantContext context) {
+        return tagDefinitionDao.getTagDefinitions(internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
     public TagDefinition create(final String definitionName, final String description, final CallContext context) throws TagDefinitionApiException {
-        return tagDefinitionDao.create(definitionName, description, context);
+        return tagDefinitionDao.create(definitionName, description, internalCallContextFactory.createInternalCallContext(context));
     }
 
     @Override
     public void deleteTagDefinition(final UUID definitionId, final CallContext context) throws TagDefinitionApiException {
-        tagDefinitionDao.deleteById(definitionId, context);
+        tagDefinitionDao.deleteById(definitionId, internalCallContextFactory.createInternalCallContext(context));
     }
 
     @Override
-    public TagDefinition getTagDefinition(final UUID tagDefinitionId)
+    public TagDefinition getTagDefinition(final UUID tagDefinitionId, final TenantContext context)
             throws TagDefinitionApiException {
-        return tagDefinitionDao.getById(tagDefinitionId);
+        return tagDefinitionDao.getById(tagDefinitionId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-
     @Override
-    public List<TagDefinition> getTagDefinitions(Collection<UUID> tagDefinitionIds)
+    public List<TagDefinition> getTagDefinitions(final Collection<UUID> tagDefinitionIds, final TenantContext context)
             throws TagDefinitionApiException {
-        return tagDefinitionDao.getByIds(tagDefinitionIds);
+        return tagDefinitionDao.getByIds(tagDefinitionIds, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
     public void addTags(final UUID objectId, final ObjectType objectType, final Collection<UUID> tagDefinitionIds, final CallContext context) throws TagApiException {
         // TODO: consider making this batch
         for (final UUID tagDefinitionId : tagDefinitionIds) {
-            tagDao.insertTag(objectId, objectType, tagDefinitionId, context);
+            // TODO accountId?
+            tagDao.insertTag(objectId, objectType, tagDefinitionId, internalCallContextFactory.createInternalCallContext(context));
         }
     }
 
     @Override
     public void addTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final CallContext context) throws TagApiException {
-        tagDao.insertTag(objectId, objectType, tagDefinitionId, context);
+        // TODO accountId?
+        tagDao.insertTag(objectId, objectType, tagDefinitionId, internalCallContextFactory.createInternalCallContext(context));
     }
 
     @Override
     public void removeTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final CallContext context) throws TagApiException {
-        tagDao.deleteTag(objectId, objectType, tagDefinitionId, context);
+        // TODO accountId?
+        tagDao.deleteTag(objectId, objectType, tagDefinitionId, internalCallContextFactory.createInternalCallContext(context));
     }
 
     @Override
     public void removeTags(final UUID objectId, final ObjectType objectType, final Collection<UUID> tagDefinitionIds, final CallContext context) throws TagApiException {
         // TODO: consider making this batch
         for (final UUID tagDefinitionId : tagDefinitionIds) {
-            tagDao.deleteTag(objectId, objectType, tagDefinitionId, context);
+            // TODO accountId?
+            tagDao.deleteTag(objectId, objectType, tagDefinitionId, internalCallContextFactory.createInternalCallContext(context));
         }
     }
 
     @Override
-    public Map<String, Tag> getTags(final UUID objectId, final ObjectType objectType) {
-        return tagDao.loadEntities(objectId, objectType);
+    public Map<String, Tag> getTags(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+        return tagDao.loadEntities(objectId, objectType, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public TagDefinition getTagDefinitionForName(String tagDefinitionName)
+    public TagDefinition getTagDefinitionForName(final String tagDefinitionName, final TenantContext context)
             throws TagDefinitionApiException {
-        return tagDefinitionDao.getByName(tagDefinitionName);
+        return tagDefinitionDao.getByName(tagDefinitionName, internalCallContextFactory.createInternalTenantContext(context));
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagCreationEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagCreationEvent.java
index 3f24ac4..cfa8f30 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagCreationEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagCreationEvent.java
@@ -18,13 +18,14 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.ControlTagCreationEvent;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultControlTagCreationEvent implements ControlTagCreationEvent {
     private final UUID tagId;
     private final UUID objectId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionCreationEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionCreationEvent.java
index f21db81..a7987e9 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionCreationEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionCreationEvent.java
@@ -18,11 +18,12 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.api.ControlTagDefinitionCreationEvent;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.util.tag.TagDefinition;
-import com.ning.billing.util.tag.api.ControlTagDefinitionCreationEvent;
 
 public class DefaultControlTagDefinitionCreationEvent implements ControlTagDefinitionCreationEvent {
     private final UUID tagDefinitionId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionDeletionEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionDeletionEvent.java
index 386b25b..9225dda 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionDeletionEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDefinitionDeletionEvent.java
@@ -18,11 +18,12 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.api.ControlTagDefinitionDeletionEvent;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.util.tag.TagDefinition;
-import com.ning.billing.util.tag.api.ControlTagDefinitionDeletionEvent;
 
 public class DefaultControlTagDefinitionDeletionEvent implements ControlTagDefinitionDeletionEvent {
     private final UUID tagDefinitionId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDeletionEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDeletionEvent.java
index 326d50f..93114b9 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDeletionEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultControlTagDeletionEvent.java
@@ -18,13 +18,14 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.ControlTagDeletionEvent;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultControlTagDeletionEvent implements ControlTagDeletionEvent {
     private final UUID tagId;
     final UUID objectId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagCreationEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagCreationEvent.java
index ae386f1..8997f3e 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagCreationEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagCreationEvent.java
@@ -18,13 +18,14 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.UserTagCreationEvent;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultUserTagCreationEvent implements UserTagCreationEvent {
     private final UUID tagId;
     private final UUID objectId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionCreationEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionCreationEvent.java
index 5d86e4b..bf76b7b 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionCreationEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionCreationEvent.java
@@ -18,11 +18,12 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.api.UserTagDefinitionCreationEvent;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.util.tag.TagDefinition;
-import com.ning.billing.util.tag.api.UserTagDefinitionCreationEvent;
 
 public class DefaultUserTagDefinitionCreationEvent implements UserTagDefinitionCreationEvent {
     private final UUID tagDefinitionId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionDeletionEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionDeletionEvent.java
index a324d49..6c50c6c 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionDeletionEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDefinitionDeletionEvent.java
@@ -18,11 +18,12 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.api.UserTagDefinitionDeletionEvent;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.util.tag.TagDefinition;
-import com.ning.billing.util.tag.api.UserTagDefinitionDeletionEvent;
 
 public class DefaultUserTagDefinitionDeletionEvent implements UserTagDefinitionDeletionEvent {
     private final UUID tagDefinitionId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDeletionEvent.java b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDeletionEvent.java
index a19f97b..92678ae 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDeletionEvent.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/user/DefaultUserTagDeletionEvent.java
@@ -18,13 +18,14 @@ package com.ning.billing.util.tag.api.user;
 
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.UserTagDeletionEvent;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class DefaultUserTagDeletionEvent implements UserTagDeletionEvent {
     private final UUID tagId;
     private final UUID objectId;
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java
index 95b1991..d7f6ffc 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java
@@ -29,13 +29,13 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.AuditedCollectionDaoBase;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.EntityHistory;
@@ -50,7 +50,10 @@ import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.TagEvent;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 
+import com.google.inject.Inject;
+
 public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements TagDao {
+
     private static final Logger log = LoggerFactory.getLogger(AuditedTagDao.class);
 
     private final TagSqlDao tagSqlDao;
@@ -69,9 +72,7 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
         return obj;
     }
 
-    private TagDefinition getTagDefinitionFromTransaction(final TagSqlDao transTagSqlDao, final UUID tagDefinitionId)
-        throws TagApiException {
-
+    private TagDefinition getTagDefinitionFromTransaction(final UUID tagDefinitionId, final InternalTenantContext context) throws TagApiException {
         TagDefinition tagDefintion = null;
         for (final ControlTagType t : ControlTagType.values()) {
             if (t.getId().equals(tagDefinitionId)) {
@@ -81,7 +82,7 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
         }
         if (tagDefintion == null) {
             final TagDefinitionSqlDao transTagDefintionSqlDao = tagSqlDao.become(TagDefinitionSqlDao.class);
-            tagDefintion = transTagDefintionSqlDao.getById(tagDefinitionId.toString());
+            tagDefintion = transTagDefintionSqlDao.getById(tagDefinitionId.toString(), context);
         }
 
         if (tagDefintion == null) {
@@ -90,36 +91,35 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
         return tagDefintion;
     }
 
-
     @Override
-    public void insertTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final CallContext context)
-     throws TagApiException {
+    public void insertTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final InternalCallContext context)
+            throws TagApiException {
         tagSqlDao.inTransaction(new Transaction<Void, TagSqlDao>() {
             @Override
             public Void inTransaction(final TagSqlDao transTagSqlDao, final TransactionStatus status) throws Exception {
 
                 final String tagId = UUID.randomUUID().toString();
-                final TagDefinition tagDefinition = getTagDefinitionFromTransaction(transTagSqlDao, tagDefinitionId);
+                final TagDefinition tagDefinition = getTagDefinitionFromTransaction(tagDefinitionId, context);
 
                 // Create the tag
                 tagSqlDao.addTagFromTransaction(tagId, tagDefinitionId.toString(), objectId.toString(), objectType, context);
 
-                final Tag tag = tagSqlDao.findTag(tagDefinitionId.toString(), objectId.toString(), objectType);
+                final Tag tag = tagSqlDao.findTag(tagDefinitionId.toString(), objectId.toString(), objectType, context);
                 final List<Tag> tagList = Arrays.asList(tag);
 
                 // Gather the tag ids for this object id
-                final List<Mapper<UUID, Long>> recordIds = tagSqlDao.getRecordIds(objectId.toString(), objectType);
+                final List<Mapper<UUID, Long>> recordIds = tagSqlDao.getRecordIds(objectId.toString(), objectType, context);
                 final Map<UUID, Long> recordIdMap = convertToHistoryMap(recordIds, objectType);
 
                 // Update the history table
                 final List<EntityHistory<Tag>> entityHistories = convertToHistory(tagList, recordIdMap, ChangeType.INSERT);
-                final Long maxHistoryRecordId = tagSqlDao.getMaxHistoryRecordId();
+                final Long maxHistoryRecordId = tagSqlDao.getMaxHistoryRecordId(context);
                 tagSqlDao.addHistoryFromTransaction(objectId.toString(), objectType, entityHistories, context);
 
                 // Have to fetch the history record ids to update the audit log
-                final List<Mapper<Long, Long>> historyRecordIds = tagSqlDao.getHistoryRecordIds(maxHistoryRecordId);
+                final List<Mapper<Long, Long>> historyRecordIds = tagSqlDao.getHistoryRecordIds(maxHistoryRecordId, context);
                 final Map<Long, Long> historyRecordIdMap = convertToAuditMap(historyRecordIds);
-                final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap);
+                final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap, context);
                 tagSqlDao.insertAuditFromTransaction(entityAudits, context);
 
                 // Post an event to the Bus
@@ -140,14 +140,14 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
     }
 
     @Override
-    public void deleteTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final CallContext context) throws TagApiException {
+    public void deleteTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final InternalCallContext context) throws TagApiException {
         try {
             tagSqlDao.inTransaction(new Transaction<Void, TagSqlDao>() {
                 @Override
                 public Void inTransaction(final TagSqlDao transTagSqlDao, final TransactionStatus status) throws Exception {
 
-                    final TagDefinition tagDefinition = getTagDefinitionFromTransaction(transTagSqlDao, tagDefinitionId);
-                    final Tag tag = tagSqlDao.findTag(tagDefinitionId.toString(), objectId.toString(), objectType);
+                    final TagDefinition tagDefinition = getTagDefinitionFromTransaction(tagDefinitionId, context);
+                    final Tag tag = tagSqlDao.findTag(tagDefinitionId.toString(), objectId.toString(), objectType, context);
                     if (tag == null) {
                         throw new TagApiException(ErrorCode.TAG_DOES_NOT_EXIST, tagDefinition.getName());
                     }
@@ -155,7 +155,7 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
                     final List<Tag> tagList = Arrays.asList(tag);
 
                     // Before the deletion, gather the tag ids for this object id
-                    final List<Mapper<UUID, Long>> recordIds = tagSqlDao.getRecordIds(objectId.toString(), objectType);
+                    final List<Mapper<UUID, Long>> recordIds = tagSqlDao.getRecordIds(objectId.toString(), objectType, context);
                     final Map<UUID, Long> recordIdMap = convertToHistoryMap(recordIds, objectType);
 
                     // Delete the tag
@@ -163,13 +163,13 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
 
                     // Update the history table
                     final List<EntityHistory<Tag>> entityHistories = convertToHistory(tagList, recordIdMap, ChangeType.DELETE);
-                    final Long maxHistoryRecordId = tagSqlDao.getMaxHistoryRecordId();
+                    final Long maxHistoryRecordId = tagSqlDao.getMaxHistoryRecordId(context);
                     tagSqlDao.addHistoryFromTransaction(objectId.toString(), objectType, entityHistories, context);
 
                     // Have to fetch the history record ids to update the audit log
-                    final List<Mapper<Long, Long>> historyRecordIds = tagSqlDao.getHistoryRecordIds(maxHistoryRecordId);
+                    final List<Mapper<Long, Long>> historyRecordIds = tagSqlDao.getHistoryRecordIds(maxHistoryRecordId, context);
                     final Map<Long, Long> historyRecordIdMap = convertToAuditMap(historyRecordIds);
-                    final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap);
+                    final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap, context);
                     tagSqlDao.insertAuditFromTransaction(entityAudits, context);
 
                     // Post an event to the Bus
@@ -198,22 +198,22 @@ public class AuditedTagDao extends AuditedCollectionDaoBase<Tag, Tag> implements
     }
 
     @Override
-    protected TableName getTableName() {
+    protected TableName getTableName(final InternalTenantContext context) {
         return TableName.TAG_HISTORY;
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<Tag> transmogrifyDao(final Transmogrifier transactionalDao) {
+    protected UpdatableEntityCollectionSqlDao<Tag> transmogrifyDao(final Transmogrifier transactionalDao, final InternalTenantContext context) {
         return transactionalDao.become(TagSqlDao.class);
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<Tag> getSqlDao() {
+    protected UpdatableEntityCollectionSqlDao<Tag> getSqlDao(final InternalTenantContext context) {
         return tagSqlDao;
     }
 
     @Override
-    protected String getKey(final Tag entity) {
+    protected String getKey(final Tag entity, final InternalTenantContext context) {
         return entity.getId().toString();
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
index 30700a1..1cd1615 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
@@ -28,20 +28,23 @@ import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.api.TagDefinitionEvent;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
+
 public class DefaultTagDefinitionDao implements TagDefinitionDao {
+
     private static final Logger log = LoggerFactory.getLogger(DefaultTagDefinitionDao.class);
 
     private final TagDefinitionSqlDao tagDefinitionSqlDao;
@@ -56,10 +59,10 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
     }
 
     @Override
-    public List<TagDefinition> getTagDefinitions() {
+    public List<TagDefinition> getTagDefinitions(final InternalTenantContext context) {
         // Get user definitions from the database
         final List<TagDefinition> definitionList = new LinkedList<TagDefinition>();
-        definitionList.addAll(tagDefinitionSqlDao.get());
+        definitionList.addAll(tagDefinitionSqlDao.get(context));
 
         // Add control tag definitions
         for (final ControlTagType controlTag : ControlTagType.values()) {
@@ -69,28 +72,27 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
     }
 
     @Override
-    public TagDefinition getByName(final String definitionName) {
+    public TagDefinition getByName(final String definitionName, final InternalTenantContext context) {
         for (final ControlTagType controlTag : ControlTagType.values()) {
             if (controlTag.name().equals(definitionName)) {
                 return new DefaultTagDefinition(controlTag);
             }
-         }
-        return tagDefinitionSqlDao.getByName(definitionName);
+        }
+        return tagDefinitionSqlDao.getByName(definitionName, context);
     }
 
-
     @Override
-    public TagDefinition getById(final UUID definitionId) {
+    public TagDefinition getById(final UUID definitionId, final InternalTenantContext context) {
         for (final ControlTagType controlTag : ControlTagType.values()) {
             if (controlTag.getId().equals(definitionId)) {
                 return new DefaultTagDefinition(controlTag);
             }
         }
-        return tagDefinitionSqlDao.getById(definitionId.toString());
+        return tagDefinitionSqlDao.getById(definitionId.toString(), context);
     }
 
     @Override
-    public List<TagDefinition> getByIds(final Collection<UUID> definitionIds) {
+    public List<TagDefinition> getByIds(final Collection<UUID> definitionIds, final InternalTenantContext context) {
         final List<TagDefinition> result = new LinkedList<TagDefinition>();
         for (final UUID cur : definitionIds) {
             for (final ControlTagType controlTag : ControlTagType.values()) {
@@ -103,18 +105,18 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
         if (definitionIds.size() > 0) {
             result.addAll(tagDefinitionSqlDao.getByIds(Collections2.transform(definitionIds, new Function<UUID, String>() {
                 @Override
-                public String apply(UUID input) {
+                public String apply(final UUID input) {
                     return input.toString();
                 }
 
-            })));
+            }), context));
         }
         return result;
     }
 
     @Override
     public TagDefinition create(final String definitionName, final String description,
-                                final CallContext context) throws TagDefinitionApiException {
+                                final InternalCallContext context) throws TagDefinitionApiException {
         // Make sure a control tag with this name don't already exist
         if (isControlTagName(definitionName)) {
             throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_CONFLICTS_WITH_CONTROL_TAG, definitionName);
@@ -125,7 +127,7 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
                 @Override
                 public TagDefinition inTransaction(final TagDefinitionSqlDao tagDefinitionSqlDao, final TransactionStatus status) throws Exception {
                     // Make sure the tag definition doesn't exist already
-                    final TagDefinition existingDefinition = tagDefinitionSqlDao.getByName(definitionName);
+                    final TagDefinition existingDefinition = tagDefinitionSqlDao.getByName(definitionName, context);
                     if (existingDefinition != null) {
                         throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_ALREADY_EXISTS, definitionName);
                     }
@@ -170,19 +172,19 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
     }
 
     @Override
-    public void deleteById(final UUID definitionId, final CallContext context) throws TagDefinitionApiException {
+    public void deleteById(final UUID definitionId, final InternalCallContext context) throws TagDefinitionApiException {
         try {
             tagDefinitionSqlDao.inTransaction(new Transaction<Void, TagDefinitionSqlDao>() {
                 @Override
                 public Void inTransaction(final TagDefinitionSqlDao tagDefinitionSqlDao, final TransactionStatus status) throws Exception {
                     // Make sure the tag definition exists
-                    final TagDefinition tagDefinition = tagDefinitionSqlDao.getById(definitionId.toString());
+                    final TagDefinition tagDefinition = tagDefinitionSqlDao.getById(definitionId.toString(), context);
                     if (tagDefinition == null) {
                         throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionId);
                     }
 
                     // Make sure it is not used currently
-                    if (tagDefinitionSqlDao.tagDefinitionUsageCount(definitionId.toString()) > 0) {
+                    if (tagDefinitionSqlDao.tagDefinitionUsageCount(definitionId.toString(), context) > 0) {
                         throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_IN_USE, definitionId);
                     }
 
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
index c46c8e7..c7af586 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
@@ -19,14 +19,14 @@ package com.ning.billing.util.tag.dao;
 import java.util.UUID;
 
 import com.ning.billing.util.api.TagApiException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.dao.AuditedCollectionDao;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
 
 public interface TagDao extends AuditedCollectionDao<Tag> {
-    void insertTag(UUID objectId, ObjectType objectType, UUID tagDefinition, CallContext context) throws TagApiException;
 
-    void deleteTag(UUID objectId, ObjectType objectType, UUID tagDefinition, CallContext context) throws TagApiException;
+    void insertTag(UUID objectId, ObjectType objectType, UUID tagDefinition, InternalCallContext context) throws TagApiException;
+
+    void deleteTag(UUID objectId, ObjectType objectType, UUID tagDefinition, InternalCallContext context) throws TagApiException;
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
index 72807a2..b2cc4f0 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
@@ -21,19 +21,21 @@ import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.tag.TagDefinition;
 
 public interface TagDefinitionDao {
-    public List<TagDefinition> getTagDefinitions();
 
-    public TagDefinition getById(final UUID definitionId);
+    public List<TagDefinition> getTagDefinitions(InternalTenantContext context);
 
-    public TagDefinition getByName(final String definitionName);
+    public TagDefinition getById(UUID definitionId, InternalTenantContext context);
 
-    public List<TagDefinition> getByIds(final Collection<UUID> definitionIds);
+    public TagDefinition getByName(String definitionName, InternalTenantContext context);
 
-    public TagDefinition create(final String definitionName, final String description, final CallContext context) throws TagDefinitionApiException;
+    public List<TagDefinition> getByIds(Collection<UUID> definitionIds, InternalTenantContext context);
 
-    public void deleteById(final UUID definitionId, final CallContext context) throws TagDefinitionApiException;
+    public TagDefinition create(String definitionName, String description, InternalCallContext context) throws TagDefinitionApiException;
+
+    public void deleteById(UUID definitionId, InternalCallContext context) throws TagDefinitionApiException;
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
index 3256ba8..3df4c49 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
@@ -41,8 +41,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.entity.dao.EntitySqlDao;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.TagDefinition;
@@ -50,23 +51,30 @@ import com.ning.billing.util.tag.TagDefinition;
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(TagDefinitionSqlDao.TagDefinitionMapper.class)
 public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinition>, Transactional<TagDefinitionSqlDao>, Transmogrifier {
+
     @Override
     @SqlUpdate
-    public void create(@TagDefinitionBinder final TagDefinition entity, @CallContextBinder final CallContext context);
+    public void create(@TagDefinitionBinder final TagDefinition entity,
+                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public TagDefinition getByName(@Bind("name") final String definitionName);
+    public TagDefinition getByName(@Bind("name") final String definitionName,
+                                   @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    public void deleteTagDefinition(@Bind("id") final String definitionId, @CallContextBinder final CallContext context);
+    public void deleteTagDefinition(@Bind("id") final String definitionId,
+                                    @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public int tagDefinitionUsageCount(@Bind("id") final String definitionId);
+    public int tagDefinitionUsageCount(@Bind("id") final String definitionId,
+                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    public List<TagDefinition> getByIds(@UUIDCollectionBinder final Collection<String> definitionIds);
+    public List<TagDefinition> getByIds(@UUIDCollectionBinder final Collection<String> definitionIds,
+                                        @InternalTenantContextBinder final InternalTenantContext context);
 
     public class TagDefinitionMapper implements ResultSetMapper<TagDefinition> {
+
         @Override
         public TagDefinition map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
             final UUID id = UUID.fromString(result.getString("id"));
@@ -80,7 +88,9 @@ public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinition>, Transa
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.PARAMETER})
     public @interface TagDefinitionBinder {
+
         public static class TagDefinitionBinderFactory implements BinderFactory {
+
             @Override
             public Binder build(final Annotation annotation) {
                 return new Binder<TagDefinitionBinder, TagDefinition>() {
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java
index 23bdce6..b8622b0 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java
@@ -28,8 +28,9 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.ObjectTypeBinder;
@@ -39,49 +40,51 @@ import com.ning.billing.util.tag.Tag;
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(TagMapper.class)
 public interface TagSqlDao extends UpdatableEntityCollectionSqlDao<Tag>, Transactional<TagSqlDao>, Transmogrifier {
+
     @Override
     @SqlBatch(transactional = false)
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @TagBinder final Collection<Tag> tags,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch(transactional = false)
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @TagBinder final Collection<Tag> tags,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch(transactional = false)
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @TagBinder final Collection<Tag> tags,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @Override
     @SqlBatch(transactional = false)
     public void addHistoryFromTransaction(@Bind("objectId") final String objectId,
                                           @ObjectTypeBinder final ObjectType objectType,
                                           @TagHistoryBinder final List<EntityHistory<Tag>> histories,
-                                          @CallContextBinder final CallContext context);
+                                          @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void addTagFromTransaction(@Bind("id") final String tagId,
                                       @Bind("tagDefinitionId") final String tagDefinitionId,
                                       @Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
-                                      @CallContextBinder final CallContext context);
+                                      @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void removeTagFromTransaction(@Bind("tagDefinitionId") final String tagDefinitionId,
                                          @Bind("objectId") final String objectId,
                                          @ObjectTypeBinder final ObjectType objectType,
-                                         @CallContextBinder final CallContext context);
+                                         @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
     public Tag findTag(@Bind("tagDefinitionId") final String tagDefinitionId,
                        @Bind("objectId") final String objectId,
-                       @ObjectTypeBinder final ObjectType objectType);
+                       @ObjectTypeBinder final ObjectType objectType,
+                       @InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/UUIDCollectionBinder.java b/util/src/main/java/com/ning/billing/util/tag/dao/UUIDCollectionBinder.java
index 7cd131c..98181b1 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/UUIDCollectionBinder.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/UUIDCollectionBinder.java
@@ -21,7 +21,6 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.util.Collection;
-import java.util.List;
 
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.sqlobject.Binder;
diff --git a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
index d21e5ad..d271708 100644
--- a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
+++ b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
@@ -27,11 +27,12 @@ import java.util.ResourceBundle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.util.LocaleUtils;
 import com.ning.billing.util.config.UriAccessor;
 
+import com.google.inject.Inject;
+
 public abstract class DefaultTranslatorBase implements Translator {
     protected final TranslatorConfig config;
     protected final Logger log = LoggerFactory.getLogger(DefaultTranslatorBase.class);
diff --git a/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
index 20ecbc4..276cd81 100644
--- a/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
+++ b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeoutException;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
-import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.util.bus.BusEvent;
diff --git a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
index 9213b37..a300e72 100644
--- a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
+++ b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
@@ -20,9 +20,10 @@ import java.util.List;
 
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.validation.ColumnInfo;
 
+import com.google.inject.Inject;
+
 public class DatabaseSchemaDao {
     private final DatabaseSchemaSqlDao dao;
 
diff --git a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
index 7a5b0cf..4d069b4 100644
--- a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
@@ -32,10 +32,12 @@ import com.ning.billing.util.validation.ColumnInfo;
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(DatabaseSchemaSqlDao.ColumnInfoMapper.class)
 public interface DatabaseSchemaSqlDao {
+
     @SqlQuery
     List<ColumnInfo> getSchemaInfo(@Bind("schemaName") final String schemaName);
 
     class ColumnInfoMapper implements ResultSetMapper<ColumnInfo> {
+
         @Override
         public ColumnInfo map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
             final String tableName = r.getString("table_name");
diff --git a/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java b/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
index a1813b6..54e4bdf 100644
--- a/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
+++ b/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
@@ -23,9 +23,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import com.google.inject.Inject;
 import com.ning.billing.util.validation.dao.DatabaseSchemaDao;
 
+import com.google.inject.Inject;
+
 public class ValidationManager {
     private final DatabaseSchemaDao dao;
 
diff --git a/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
index 61e991b..9bd6aa4 100644
--- a/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group PersistentBusSqlDao;
           
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getNextBusEventEntry() ::= <<
     select
       record_id
@@ -65,6 +68,8 @@ insertBusEvent() ::= <<
     , processing_owner
     , processing_available_date
     , processing_state
+    , account_record_id
+    , tenant_record_id
     ) values (
       :className
     , :eventJson
@@ -73,7 +78,9 @@ insertBusEvent() ::= <<
     , :processingOwner
     , :processingAvailableDate
     , :processingState
-    );   
+    , :accountRecordId
+    , :tenantRecordId
+    );
 >>
 
 insertClaimedHistory() ::= <<
@@ -81,9 +88,13 @@ insertClaimedHistory() ::= <<
           owner_id
         , claimed_date
         , bus_event_id
+        , account_record_id
+        , tenant_record_id
       ) values (
           :ownerId
         , :claimedDate
         , :busEventId
+        , :accountRecordId
+        , :tenantRecordId
       );
 >>
diff --git a/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
index 94d21c9..9c6ff53 100644
--- a/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
@@ -1,31 +1,42 @@
 group CustomFieldSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 insertFromTransaction() ::= <<
-    INSERT INTO custom_fields(id, object_id, object_type, field_name, field_value, created_by, created_date, updated_by, updated_date)
-    VALUES (:id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :createdDate, :userName, :updatedDate);
+    INSERT INTO custom_fields(id, object_id, object_type, field_name, field_value, created_by, created_date, updated_by, updated_date, account_record_id, tenant_record_id)
+    VALUES (:id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :createdDate, :userName, :updatedDate, :accountRecordId, :tenantRecordId);
 >>
 
 updateFromTransaction() ::= <<
     UPDATE custom_fields
     SET field_value = :fieldValue, updated_by = :userName, updated_date = :updatedDate
-    WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName;
+    WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 deleteFromTransaction() ::= <<
     DELETE FROM custom_fields
-    WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName;
+    WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 load() ::= <<
     SELECT id, object_id, object_type, field_name, field_value, created_by, created_date, updated_by, updated_date
     FROM custom_fields
-    WHERE object_id = :objectId AND object_type = :objectType;
+    WHERE object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordIds() ::= <<
     SELECT record_id, id
     FROM custom_fields
-    WHERE object_id = :objectId AND object_type = :objectType;
+    WHERE object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 historyFields(prefix) ::= <<
@@ -37,23 +48,29 @@ historyFields(prefix) ::= <<
   <prefix>field_value,
   <prefix>updated_by,
   <prefix>date,
-  <prefix>change_type
+  <prefix>change_type,
+  <prefix>account_record_id,
+  <prefix>tenant_record_id
 >>
 
 addHistoryFromTransaction() ::= <<
     INSERT INTO custom_field_history(<historyFields()>)
-    VALUES(:recordId, :id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :updatedDate, :changeType);
+    VALUES(:recordId, :id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :updatedDate, :changeType, :accountRecordId, :tenantRecordId);
 >>
 
 getMaxHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
-    FROM custom_field_history;
+    FROM custom_field_history
+    WHERE <CHECK_TENANT()>
+    ;
 >>
 
 getHistoryRecordIds() ::= <<
     SELECT history_record_id, record_id
     FROM custom_field_history
-    WHERE history_record_id > :maxHistoryRecordId;
+    WHERE history_record_id > :maxHistoryRecordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -64,16 +81,18 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
-    SELECT 1 FROM custom_fields;
+    SELECT 1 FROM custom_fields WHERE <CHECK_TENANT()>;
 >>
 ;
 
diff --git a/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
index 20cd42f..7bf93e4 100644
--- a/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group AuditSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>table_name,
     <prefix>record_id,
@@ -8,12 +11,14 @@ fields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<fields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 getAuditLogsForRecordId() ::= <<
@@ -21,6 +26,7 @@ getAuditLogsForRecordId() ::= <<
   FROM audit_log
   WHERE record_id = :recordId
   AND table_name = :tableName
+  <AND_CHECK_TENANT()>
   ORDER BY change_date ASC
 >>
 
@@ -28,6 +34,7 @@ getRecordIdForTable(tableName) ::= <<
   SELECT record_id
   FROM <tableName>
   WHERE id = :id
+  <AND_CHECK_TENANT()>
   LIMIT 1
 >>
 
@@ -35,4 +42,5 @@ getHistoryRecordIdsForTable(tableName) ::= <<
   SELECT history_record_id record_id
   FROM <tableName>
   WHERE id = :id
+  <AND_CHECK_TENANT()>
 >>
diff --git a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
index 8cb0a27..230795b 100644
--- a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group NotificationSqlDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 getReadyNotifications() ::= <<
     select
       record_id
@@ -57,7 +60,7 @@ removeNotification()  ::= <<
   processing_state = 'REMOVED'
     where
   id = :id
-; 
+;
 >>
 
 claimNotification() ::= <<
@@ -105,6 +108,8 @@ insertNotification() ::= <<
       , processing_owner
       , processing_available_date
       , processing_state
+      , account_record_id
+      , tenant_record_id
     ) values (
       :id
       , :className
@@ -117,7 +122,9 @@ insertNotification() ::= <<
       , :processingOwner
       , :processingAvailableDate
       , :processingState
-    );   
+      , :accountRecordId
+      , :tenantRecordId
+    );
 >>
 
 insertClaimedHistory() ::= <<
@@ -125,9 +132,13 @@ insertClaimedHistory() ::= <<
           owner_id
         , claimed_date
         , notification_id
+        , account_record_id
+        , tenant_record_id
       ) values (
           :ownerId
         , :claimedDate
         , :notificationId
+        , :accountRecordId
+        , :tenantRecordId
       );
 >>
diff --git a/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
index 832bb17..9fb5bf2 100644
--- a/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
@@ -1,5 +1,8 @@
 group TagDefinitionDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>id,
     <prefix>name,
@@ -7,52 +10,65 @@ fields(prefix) ::= <<
     <prefix>created_by,
     <prefix>created_date ,
     <prefix>updated_by,
-    <prefix>updated_date
+    <prefix>updated_date,
+    <prefix>tenant_record_id
 >>
 
 get() ::= <<
   SELECT <fields()>
-  FROM tag_definitions;
+  FROM tag_definitions
+  WHERE <CHECK_TENANT()>
+  ;
 >>
 
 create() ::= <<
   INSERT INTO tag_definitions(<fields()>)
-  VALUES(:id, :name, :description, :userName, :createdDate, :userName, :updatedDate);
+  VALUES(:id, :name, :description, :userName, :createdDate, :userName, :updatedDate, :tenantRecordId);
 >>
 
 load() ::= <<
   SELECT <fields()>
   FROM tag_definitions
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 
 deleteTagDefinition() ::= <<
   DELETE FROM tag_definitions
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 tagDefinitionUsageCount() ::= <<
   SELECT COUNT(id)
   FROM tags
   WHERE tag_definition_id = :id
+  <AND_CHECK_TENANT()>
 >>
 
 getByName() ::= <<
   SELECT <fields()>
    FROM tag_definitions
-  WHERE name = :name;
+  WHERE name = :name
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getById() ::= <<
   SELECT <fields()>
   FROM tag_definitions
-  WHERE id = :id;
+  WHERE id = :id
+  <AND_CHECK_TENANT()>
+  ;
 >>
 
 getByIds(tag_definition_ids) ::= <<
   SELECT <fields()>
   FROM tag_definitions
   WHERE id IN (<tag_definition_ids: {id | :id_<i0>}; separator="," >)
+  <AND_CHECK_TENANT()>
 >>
 ;
diff --git a/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg
index e80ada7..a1a674d 100644
--- a/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg
@@ -1,46 +1,59 @@
 group TagDao;
 
+CHECK_TENANT() ::= "tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
+
 fields(prefix) ::= <<
     <prefix>id,
     <prefix>tag_definition_id,
     <prefix>object_id,
     <prefix>object_type,
     <prefix>created_by,
-    <prefix>created_date
+    <prefix>created_date,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 insertFromTransaction() ::= <<
   INSERT INTO tags(<fields()>)
-  VALUES (:id, :tagDefinitionId, :objectId, :objectType, :userName, :createdDate);
+  VALUES (:id, :tagDefinitionId, :objectId, :objectType, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 deleteFromTransaction() ::= <<
     DELETE FROM tags
     WHERE tag_definition_id = :tagDefinitionId
-        AND object_id = :objectId AND object_type = :objectType;
+        AND object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 addTagFromTransaction() ::= <<
     INSERT INTO tags(<fields()>)
-    VALUES (:id, :tagDefinitionId, :objectId, :objectType, :userName, :createdDate);
+    VALUES (:id, :tagDefinitionId, :objectId, :objectType, :userName, :createdDate, :accountRecordId, :tenantRecordId);
 >>
 
 removeTagFromTransaction() ::= <<
     DELETE FROM tags
     WHERE tag_definition_id = :tagDefinitionId
-    AND object_id = :objectId AND object_type = :objectType;
+    AND object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 findTag() ::= <<
     SELECT <fields()> FROM tags
     WHERE tag_definition_id = :tagDefinitionId
-    AND object_id = :objectId AND object_type = :objectType;
+    AND object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 getRecordIds() ::= <<
     SELECT record_id, id
     FROM tags
-    WHERE object_id = :objectId AND object_type = :objectType;
+    WHERE object_id = :objectId AND object_type = :objectType
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 historyFields(prefix) ::= <<
@@ -51,23 +64,29 @@ historyFields(prefix) ::= <<
   <prefix>tag_definition_id,
   <prefix>updated_by,
   <prefix>date,
-  <prefix>change_type
+  <prefix>change_type,
+  <prefix>account_record_id,
+  <prefix>tenant_record_id
 >>
 
 addHistoryFromTransaction() ::= <<
     INSERT INTO tag_history(<historyFields()>)
-    VALUES(:recordId, :id, :objectId, :objectType, :tagDefinitionId, :userName, :updatedDate, :changeType);
+    VALUES(:recordId, :id, :objectId, :objectType, :tagDefinitionId, :userName, :updatedDate, :changeType, :accountRecordId, :tenantRecordId);
 >>
 
 getMaxHistoryRecordId() ::= <<
     SELECT MAX(history_record_id)
-    FROM tag_history;
+    FROM tag_history
+    WHERE <CHECK_TENANT()>
+    ;
 >>
 
 getHistoryRecordIds() ::= <<
     SELECT history_record_id, record_id
     FROM tag_history
-    WHERE history_record_id > :maxHistoryRecordId;
+    WHERE history_record_id > :maxHistoryRecordId
+    <AND_CHECK_TENANT()>
+    ;
 >>
 
 auditFields(prefix) ::= <<
@@ -78,21 +97,24 @@ auditFields(prefix) ::= <<
     <prefix>changed_by,
     <prefix>reason_code,
     <prefix>comments,
-    <prefix>user_token
+    <prefix>user_token,
+    <prefix>account_record_id,
+    <prefix>tenant_record_id
 >>
 
 load() ::= <<
   SELECT <fields()>
     FROM tags
-  WHERE object_id = :objectId AND object_type = :objectType;
+  WHERE object_id = :objectId AND object_type = :objectType
+  <AND_CHECK_TENANT()>;
 >>
 
 insertAuditFromTransaction() ::= <<
     INSERT INTO audit_log(<auditFields()>)
-    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken);
+    VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, :reasonCode, :comment, :userToken, :accountRecordId, :tenantRecordId);
 >>
 
 test() ::= <<
-  SELECT 1 FROM tags;
+  SELECT 1 FROM tags WHERE <CHECK_TENANT()>;
 >>
-;
\ No newline at end of file
+;
diff --git a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
index 6cb1852..02d090a 100644
--- a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
+++ b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
@@ -34,10 +34,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 
+import com.ning.billing.util.io.IOUtils;
+
 import com.google.common.io.Resources;
 import com.mysql.management.MysqldResource;
 import com.mysql.management.MysqldResourceI;
-import com.ning.billing.util.io.IOUtils;
 
 /**
  * Utility class to embed MySQL for testing purposes
@@ -48,9 +49,9 @@ public class MysqlTestingHelper {
 
     private static final Logger log = LoggerFactory.getLogger(MysqlTestingHelper.class);
 
-    private static final String DB_NAME = "killbill";
-    private static final String USERNAME = "root";
-    private static final String PASSWORD = "root";
+    public static final String DB_NAME = "killbill";
+    public static final String USERNAME = "root";
+    public static final String PASSWORD = "root";
 
     // Discover dynamically list of all tables in that database;
     private List<String> allTables;
@@ -177,12 +178,20 @@ public class MysqlTestingHelper {
     }
 
     public IDBI getDBI() {
-        final String dbiString = "jdbc:mysql://localhost:" + port + "/" + DB_NAME + "?createDatabaseIfNotExist=true&allowMultiQueries=true";
+        final String dbiString = getJdbcConnectionString() + "?createDatabaseIfNotExist=true&allowMultiQueries=true";
         return new DBI(dbiString, USERNAME, PASSWORD);
     }
 
+    public String getJdbcConnectionString() {
+        return "jdbc:mysql://localhost:" + port + "/" + DB_NAME;
+    }
+
     public void initDb() throws IOException {
-        for (final String pack : new String[]{"account", "analytics", "entitlement", "util", "payment", "invoice", "junction"}) {
+        // We always want the accounts and tenants table
+        initDb("drop table if exists accounts; create table accounts(record_id int(11) unsigned not null auto_increment, id char(36) not null, primary key(record_id)) engine=innodb;");
+        initDb("drop table if exists tenants; create table tenants(record_id int(11) unsigned not null auto_increment, id char(36) not null, primary key(record_id)) engine=innodb;");
+
+        for (final String pack : new String[]{"account", "analytics", "entitlement", "util", "payment", "invoice", "junction", "tenant"}) {
             final String ddl;
             try {
                 ddl = IOUtils.toString(Resources.getResource("com/ning/billing/" + pack + "/ddl.sql").openStream());
diff --git a/util/src/test/java/com/ning/billing/KillbillTestSuite.java b/util/src/test/java/com/ning/billing/KillbillTestSuite.java
index 9f6d924..f5d9882 100644
--- a/util/src/test/java/com/ning/billing/KillbillTestSuite.java
+++ b/util/src/test/java/com/ning/billing/KillbillTestSuite.java
@@ -17,13 +17,22 @@
 package com.ning.billing;
 
 import java.lang.reflect.Method;
+import java.util.UUID;
 
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.ITestResult;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
+
 public class KillbillTestSuite {
 
     // Use the simple name here to save screen real estate
@@ -31,6 +40,12 @@ public class KillbillTestSuite {
 
     private boolean hasFailed = false;
 
+    protected final InternalCallContext internalCallContext = new InternalCallContext(InternalCallContextFactory.INTERNAL_TENANT_RECORD_ID, 1687L, UUID.randomUUID(),
+                                                                                      UUID.randomUUID().toString(), CallOrigin.TEST,
+                                                                                      UserType.TEST, "Testing", "This is a test",
+                                                                                      new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC));
+    protected final CallContext callContext = internalCallContext.toCallContext();
+
     @BeforeMethod(alwaysRun = true)
     public void startTestSuite(final Method method) throws Exception {
         log.info("***************************************************************************************************");
diff --git a/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java b/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
index d0210c2..8494212 100644
--- a/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
+++ b/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
@@ -33,8 +33,10 @@ import com.ning.billing.account.api.MigrationAccountData;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.mock.MockAccountBuilder;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class MockAccountUserApi implements AccountUserApi {
+
     private final CopyOnWriteArrayList<Account> accounts = new CopyOnWriteArrayList<Account>();
 
     public Account createAccount(final UUID id,
@@ -87,7 +89,7 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public Account getAccountByKey(final String key) {
+    public Account getAccountByKey(final String key, final TenantContext context) {
         for (final Account account : accounts) {
             if (key.equals(account.getExternalKey())) {
                 return account;
@@ -97,7 +99,7 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public Account getAccountById(final UUID uid) {
+    public Account getAccountById(final UUID uid, final TenantContext context) {
         for (final Account account : accounts) {
             if (uid.equals(account.getId())) {
                 return account;
@@ -107,12 +109,12 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public List<Account> getAccounts() {
+    public List<Account> getAccounts(final TenantContext context) {
         return new ArrayList<Account>(accounts);
     }
 
     @Override
-    public UUID getIdFromKey(final String externalKey) {
+    public UUID getIdFromKey(final String externalKey, final TenantContext context) {
         for (final Account account : accounts) {
             if (externalKey.equals(account.getExternalKey())) {
                 return account.getId();
@@ -122,7 +124,7 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public List<AccountEmail> getEmails(final UUID accountId) {
+    public List<AccountEmail> getEmails(final UUID accountId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
@@ -167,15 +169,12 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public void updatePaymentMethod(UUID accountId, UUID paymentMethodId,
-            CallContext context) throws AccountApiException {
+    public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, final CallContext context) throws AccountApiException {
         throw new UnsupportedOperationException();
-
     }
 
     @Override
-    public void removePaymentMethod(UUID accountId, CallContext context)
-            throws AccountApiException {
+    public void removePaymentMethod(final UUID accountId, final CallContext context) throws AccountApiException {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/util/src/test/java/com/ning/billing/mock/api/MockEntitlementUserApi.java b/util/src/test/java/com/ning/billing/mock/api/MockEntitlementUserApi.java
index 09a1820..4d92c2a 100644
--- a/util/src/test/java/com/ning/billing/mock/api/MockEntitlementUserApi.java
+++ b/util/src/test/java/com/ning/billing/mock/api/MockEntitlementUserApi.java
@@ -32,8 +32,10 @@ import com.ning.billing.entitlement.api.user.SubscriptionStatusDryRun;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 public class MockEntitlementUserApi implements EntitlementUserApi {
+
     private final Map<UUID, String> subscriptionBundles = new HashMap<UUID, String>();
     private final Map<UUID, UUID> accountForBundle = new HashMap<UUID, UUID>();
     private final Map<UUID, Subscription> subscriptionsById = new HashMap<UUID, Subscription>();
@@ -44,7 +46,7 @@ public class MockEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public SubscriptionBundle getBundleFromId(final UUID id) {
+    public SubscriptionBundle getBundleFromId(final UUID id, final TenantContext context) {
         final String key = subscriptionBundles.get(id);
         if (key == null) {
             return null;
@@ -79,23 +81,23 @@ public class MockEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final UUID id) {
+    public Subscription getSubscriptionFromId(final UUID id, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId) {
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForKey(String bundleKey)
+    public List<SubscriptionBundle> getBundlesForKey(final String bundleKey, final TenantContext context)
             throws EntitlementUserApiException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId) {
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
@@ -105,7 +107,7 @@ public class MockEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey) {
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
@@ -116,23 +118,22 @@ public class MockEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey) {
+    public SubscriptionBundle getBundleForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public DateTime getNextBillingDate(final UUID account) {
+    public DateTime getNextBillingDate(final UUID account, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public Subscription getBaseSubscription(final UUID bundleId) {
+    public Subscription getBaseSubscription(final UUID bundleId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(
-            final UUID subscriptionId, final String productName, final DateTime requestedDate)
+    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, final String productName, final DateTime requestedDate, final TenantContext context)
             throws EntitlementUserApiException {
         throw new UnsupportedOperationException();
     }
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
index 2a94dd1..c67ae9d 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.mock.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
+import com.google.inject.AbstractModule;
+
 
 public class MockClockModule extends AbstractModule {
 
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
index d1b8027..e8beb2d 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
@@ -19,12 +19,13 @@ package com.ning.billing.mock.glue;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 
+import com.google.inject.AbstractModule;
+
 public class MockDbHelperModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
index e408e14..c7b2ac3 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
@@ -18,7 +18,6 @@ package com.ning.billing.mock.glue;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.entitlement.api.EntitlementService;
 import com.ning.billing.entitlement.api.billing.ChargeThruApi;
 import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi;
@@ -28,6 +27,8 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.glue.EntitlementModule;
 import com.ning.billing.util.glue.RealImplementation;
 
+import com.google.inject.AbstractModule;
+
 public class MockEntitlementModule extends AbstractModule implements EntitlementModule {
     @Override
     public void installEntitlementService() {
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
index ecca1cd..a36eb02 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
@@ -18,12 +18,13 @@ package com.ning.billing.mock.glue;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.glue.InvoiceModule;
 import com.ning.billing.invoice.api.InvoiceMigrationApi;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 
+import com.google.inject.AbstractModule;
+
 public class MockInvoiceModule extends AbstractModule implements InvoiceModule {
     @Override
     public void installInvoiceUserApi() {
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
index fedd51e..d74f00a 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
@@ -18,13 +18,14 @@ package com.ning.billing.mock.glue;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.glue.JunctionModule;
 import com.ning.billing.junction.api.BillingApi;
 import com.ning.billing.junction.api.BlockingApi;
 
+import com.google.inject.AbstractModule;
+
 public class MockJunctionModule extends AbstractModule implements JunctionModule {
     private final BillingApi billingApi = Mockito.mock(BillingApi.class);
     private final BlockingApi blockingApi = Mockito.mock(BlockingApi.class);
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java
index 899be2b..aed75f5 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.mock.glue;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.util.notificationq.MockNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
+import com.google.inject.AbstractModule;
+
 public class MockNotificationQueueModule extends AbstractModule {
 
     @Override
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockOverdueModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockOverdueModule.java
index 013005b..ed8c97e 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockOverdueModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockOverdueModule.java
@@ -18,10 +18,11 @@ package com.ning.billing.mock.glue;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.glue.OverdueModule;
 import com.ning.billing.overdue.OverdueUserApi;
 
+import com.google.inject.AbstractModule;
+
 public class MockOverdueModule extends AbstractModule implements OverdueModule {
     @Override
     public void installOverdueUserApi() {
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
index d2c7ddd..d3505f0 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
@@ -18,9 +18,10 @@ package com.ning.billing.mock.glue;
 
 import org.mockito.Mockito;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.payment.api.PaymentApi;
 
+import com.google.inject.AbstractModule;
+
 public class MockPaymentModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
index 634631a..644afee 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
@@ -19,12 +19,13 @@ package com.ning.billing.mock.glue;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
-import com.google.inject.AbstractModule;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 
+import com.google.inject.AbstractModule;
+
 public class TestDbiModule extends AbstractModule {
     protected void configure() {
         final MysqlTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getMysqlTestingHelper();
diff --git a/util/src/test/java/com/ning/billing/mock/MockEffectiveSubscriptionEvent.java b/util/src/test/java/com/ning/billing/mock/MockEffectiveSubscriptionEvent.java
index e214e95..76f9001 100644
--- a/util/src/test/java/com/ning/billing/mock/MockEffectiveSubscriptionEvent.java
+++ b/util/src/test/java/com/ning/billing/mock/MockEffectiveSubscriptionEvent.java
@@ -20,13 +20,14 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class MockEffectiveSubscriptionEvent implements EffectiveSubscriptionEvent {
 
     private final Long totalOrdering;
diff --git a/util/src/test/java/com/ning/billing/mock/MockSubscription.java b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
index 0ff6407..9286a9a 100644
--- a/util/src/test/java/com/ning/billing/mock/MockSubscription.java
+++ b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
@@ -23,8 +23,6 @@ import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.mockito.Mockito;
 
-import com.google.common.collect.ImmutableList;
-
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Plan;
@@ -38,6 +36,8 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.util.callcontext.CallContext;
 
+import com.google.common.collect.ImmutableList;
+
 public class MockSubscription implements Subscription {
     private final UUID id;
     private final UUID bundleId;
diff --git a/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java b/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
index f4a79d1..acf8faa 100644
--- a/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
+++ b/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
@@ -42,6 +42,7 @@ import com.ning.billing.util.audit.AuditLogsForPayments;
 import com.ning.billing.util.audit.AuditLogsForRefunds;
 import com.ning.billing.util.audit.AuditLogsTestBase;
 import com.ning.billing.util.audit.dao.MockAuditDao;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.TableName;
 import com.ning.billing.util.entity.Entity;
@@ -66,7 +67,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
             }
         }
 
-        auditUserApi = new DefaultAuditUserApi(auditDao);
+        auditUserApi = new DefaultAuditUserApi(auditDao, Mockito.mock(InternalCallContextFactory.class));
     }
 
     @Test(groups = "fast")
@@ -79,7 +80,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         }
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final AuditLogsForBundles auditLogsForBundles = auditUserApi.getAuditLogsForBundles(bundles, level);
+            final AuditLogsForBundles auditLogsForBundles = auditUserApi.getAuditLogsForBundles(bundles, level, callContext);
             verifyAuditLogs(auditLogsForBundles.getBundlesAuditLogs(), level);
         }
     }
@@ -89,7 +90,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         final List<InvoicePayment> invoicePayments = createMocks(InvoicePayment.class);
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final AuditLogsForInvoicePayments auditLogsForInvoicePayments = auditUserApi.getAuditLogsForInvoicePayments(invoicePayments, level);
+            final AuditLogsForInvoicePayments auditLogsForInvoicePayments = auditUserApi.getAuditLogsForInvoicePayments(invoicePayments, level, callContext);
             verifyAuditLogs(auditLogsForInvoicePayments.getInvoicePaymentsAuditLogs(), level);
         }
     }
@@ -99,7 +100,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         final List<Refund> refunds = createMocks(Refund.class);
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final AuditLogsForRefunds auditLogsForRefunds = auditUserApi.getAuditLogsForRefunds(refunds, level);
+            final AuditLogsForRefunds auditLogsForRefunds = auditUserApi.getAuditLogsForRefunds(refunds, level, callContext);
             verifyAuditLogs(auditLogsForRefunds.getRefundsAuditLogs(), level);
         }
     }
@@ -109,7 +110,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         final List<Payment> payments = createMocks(Payment.class);
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final AuditLogsForPayments auditLogsForPayments = auditUserApi.getAuditLogsForPayments(payments, level);
+            final AuditLogsForPayments auditLogsForPayments = auditUserApi.getAuditLogsForPayments(payments, level, callContext);
             verifyAuditLogs(auditLogsForPayments.getPaymentsAuditLogs(), level);
         }
     }
@@ -123,7 +124,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         }
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final AuditLogsForInvoices auditLogsForInvoices = auditUserApi.getAuditLogsForInvoices(invoices, level);
+            final AuditLogsForInvoices auditLogsForInvoices = auditUserApi.getAuditLogsForInvoices(invoices, level, callContext);
             verifyAuditLogs(auditLogsForInvoices.getInvoiceAuditLogs(), level);
             verifyAuditLogs(auditLogsForInvoices.getInvoiceItemsAuditLogs(), level);
         }
@@ -135,11 +136,11 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
             for (final UUID objectId : objectIds) {
                 for (final AuditLevel level : AuditLevel.values()) {
                     if (AuditLevel.NONE.equals(level)) {
-                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level).size(), 0);
+                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level, callContext).size(), 0);
                     } else if (AuditLevel.MINIMAL.equals(level)) {
-                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level), ImmutableList.<AuditLog>of(auditLogs.get(0)));
+                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level, callContext), ImmutableList.<AuditLog>of(auditLogs.get(0)));
                     } else {
-                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level), auditLogs);
+                        Assert.assertEquals(auditUserApi.getAuditLogs(objectId, objectType, level, callContext), auditLogs);
                     }
                 }
             }
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/MockAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/MockAuditDao.java
index daee3e8..ad7938c 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/MockAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/MockAuditDao.java
@@ -24,6 +24,7 @@ import java.util.UUID;
 
 import com.ning.billing.util.api.AuditLevel;
 import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.TableName;
 
 import com.google.common.base.Objects;
@@ -50,7 +51,7 @@ public class MockAuditDao implements AuditDao {
     }
 
     @Override
-    public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel) {
+    public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId, final AuditLevel auditLevel, final InternalTenantContext context) {
         final Map<UUID, List<AuditLog>> auditLogsForTableName = auditLogsForTables.get(tableName);
         if (auditLogsForTableName == null) {
             return ImmutableList.<AuditLog>of();
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
index 220e564..db20a04 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
@@ -36,10 +36,6 @@ import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.TableName;
@@ -73,12 +69,10 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
     @Inject
     private IDBI dbi;
 
-    private CallContext context;
     private UUID tagId;
 
     @BeforeClass(groups = "slow")
     public void setup() throws IOException {
-        context = new DefaultCallContextFactory(clock).createCallContext("Audit DAO test", CallOrigin.TEST, UserType.TEST, UUID.randomUUID());
         bus.start();
     }
 
@@ -97,7 +91,7 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         handle.close();
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG_HISTORY, UUID.fromString(tagHistoryString), level);
+            final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG_HISTORY, UUID.fromString(tagHistoryString), level, internalCallContext);
             verifyAuditLogsForTag(auditLogs, level);
         }
     }
@@ -107,7 +101,7 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         addTag();
 
         for (final AuditLevel level : AuditLevel.values()) {
-            final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG, tagId, level);
+            final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG, tagId, level, internalCallContext);
             verifyAuditLogsForTag(auditLogs, level);
         }
     }
@@ -116,13 +110,13 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         // Create a tag definition
         final TagDefinition tagDefinition = tagDefinitionDao.create(UUID.randomUUID().toString().substring(0, 5),
                                                                     UUID.randomUUID().toString().substring(0, 5),
-                                                                    context);
-        Assert.assertEquals(tagDefinitionDao.getById(tagDefinition.getId()), tagDefinition);
+                                                                    internalCallContext);
+        Assert.assertEquals(tagDefinitionDao.getById(tagDefinition.getId(), internalCallContext), tagDefinition);
 
         // Create a tag
         final UUID objectId = UUID.randomUUID();
-        tagDao.insertTag(objectId, ObjectType.ACCOUNT, tagDefinition.getId(), context);
-        final Map<String, Tag> tags = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
+        tagDao.insertTag(objectId, ObjectType.ACCOUNT, tagDefinition.getId(), internalCallContext);
+        final Map<String, Tag> tags = tagDao.loadEntities(objectId, ObjectType.ACCOUNT, internalCallContext);
         Assert.assertEquals(tags.size(), 1);
         final Tag tag = tags.values().iterator().next();
         Assert.assertEquals(tag.getTagDefinitionId(), tagDefinition.getId());
@@ -136,11 +130,11 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         }
 
         Assert.assertEquals(auditLogs.size(), 1);
-        Assert.assertEquals(auditLogs.get(0).getUserToken(), context.getUserToken().toString());
+        Assert.assertEquals(auditLogs.get(0).getUserToken(), internalCallContext.getUserToken().toString());
         Assert.assertEquals(auditLogs.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertNull(auditLogs.get(0).getComment());
-        Assert.assertNull(auditLogs.get(0).getReasonCode());
-        Assert.assertEquals(auditLogs.get(0).getUserName(), context.getUserName());
+        Assert.assertEquals(auditLogs.get(0).getComment(), internalCallContext.getComment());
+        Assert.assertEquals(auditLogs.get(0).getReasonCode(), internalCallContext.getReasonCode());
+        Assert.assertEquals(auditLogs.get(0).getUserName(), internalCallContext.getUserName());
         Assert.assertNotNull(auditLogs.get(0).getCreatedDate());
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/audit/TestDefaultAuditLog.java b/util/src/test/java/com/ning/billing/util/audit/TestDefaultAuditLog.java
index 709708f..06e4b43 100644
--- a/util/src/test/java/com/ning/billing/util/audit/TestDefaultAuditLog.java
+++ b/util/src/test/java/com/ning/billing/util/audit/TestDefaultAuditLog.java
@@ -40,12 +40,13 @@ public class TestDefaultAuditLog extends UtilTestSuite {
         final ChangeType changeType = ChangeType.DELETE;
         final EntityAudit entityAudit = new EntityAudit(tableName, recordId, changeType);
 
+        final UUID tenantId = UUID.randomUUID();
         final String userName = UUID.randomUUID().toString();
         final CallOrigin callOrigin = CallOrigin.EXTERNAL;
         final UserType userType = UserType.CUSTOMER;
         final UUID userToken = UUID.randomUUID();
         final ClockMock clock = new ClockMock();
-        final CallContext callContext = new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
+        final CallContext callContext = new DefaultCallContext(tenantId, userName, callOrigin, userType, userToken, clock);
 
         final AuditLog auditLog = new DefaultAuditLog(entityAudit, callContext);
         Assert.assertEquals(auditLog.getChangeType(), changeType);
@@ -63,12 +64,13 @@ public class TestDefaultAuditLog extends UtilTestSuite {
         final ChangeType changeType = ChangeType.DELETE;
         final EntityAudit entityAudit = new EntityAudit(tableName, recordId, changeType);
 
+        final UUID tenantId = UUID.randomUUID();
         final String userName = UUID.randomUUID().toString();
         final CallOrigin callOrigin = CallOrigin.EXTERNAL;
         final UserType userType = UserType.CUSTOMER;
         final UUID userToken = UUID.randomUUID();
         final ClockMock clock = new ClockMock();
-        final CallContext callContext = new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
+        final CallContext callContext = new DefaultCallContext(tenantId, userName, callOrigin, userType, userToken, clock);
 
         final AuditLog auditLog = new DefaultAuditLog(entityAudit, callContext);
         Assert.assertEquals(auditLog, auditLog);
@@ -77,7 +79,7 @@ public class TestDefaultAuditLog extends UtilTestSuite {
         Assert.assertEquals(sameAuditLog, auditLog);
 
         clock.addMonths(1);
-        final CallContext otherCallContext = new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
+        final CallContext otherCallContext = new DefaultCallContext(tenantId, userName, callOrigin, userType, userToken, clock);
         final AuditLog otherAuditLog = new DefaultAuditLog(entityAudit, otherCallContext);
         Assert.assertNotEquals(otherAuditLog, auditLog);
     }
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java b/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
index 2364c2c..38ac2fc 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
@@ -24,13 +24,14 @@ import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 
+import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.bus.BusEvent.BusEventType;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
-import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
-import com.ning.billing.util.bus.BusEvent.BusEventType;
 
 public abstract class TestEventBusBase extends UtilTestSuiteWithEmbeddedDB {
     protected static final Logger log = LoggerFactory.getLogger(TestEventBusBase.class);
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
index 2fb937b..2b2251b 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
@@ -21,8 +21,6 @@ import org.skife.jdbi.v2.IDBI;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
@@ -32,6 +30,9 @@ import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+
 @Guice(modules = TestPersistentEventBus.PersistentBusModuleTest.class)
 public class TestPersistentEventBus extends TestEventBusBase {
     @Inject
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
index 2ecc629..99d1870 100644
--- a/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
@@ -23,10 +23,12 @@ import org.joda.time.DateTime;
 import com.ning.billing.util.clock.DefaultClock;
 
 public class TestCallContext implements CallContext {
+
     private final String userName;
     private final DateTime updatedDate;
     private final DateTime createdDate;
     private final UUID userToken;
+    private final UUID tenantId;
 
     public TestCallContext(final String userName) {
         this(userName, new DefaultClock().getUTCNow(), new DefaultClock().getUTCNow());
@@ -37,6 +39,7 @@ public class TestCallContext implements CallContext {
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
         this.userToken = UUID.randomUUID();
+        this.tenantId = UUID.randomUUID();
     }
 
     @Override
@@ -78,4 +81,9 @@ public class TestCallContext implements CallContext {
     public UUID getUserToken() {
         return userToken;
     }
+
+    @Override
+    public UUID getTenantId() {
+        return tenantId;
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestDefaultCallContext.java b/util/src/test/java/com/ning/billing/util/callcontext/TestDefaultCallContext.java
index c56b5f3..8d79422 100644
--- a/util/src/test/java/com/ning/billing/util/callcontext/TestDefaultCallContext.java
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestDefaultCallContext.java
@@ -32,13 +32,15 @@ public class TestDefaultCallContext extends UtilTestSuite {
 
     @Test(groups = "fast")
     public void testGetters() throws Exception {
+        final UUID tenantId = UUID.randomUUID();
         final String userName = UUID.randomUUID().toString();
         final DateTime createdDate = clock.getUTCNow();
         final String reasonCode = UUID.randomUUID().toString();
         final String comment = UUID.randomUUID().toString();
         final UUID userToken = UUID.randomUUID();
-        final DefaultCallContext callContext = new DefaultCallContext(userName, createdDate, reasonCode, comment, userToken);
+        final DefaultCallContext callContext = new DefaultCallContext(tenantId, userName, createdDate, reasonCode, comment, userToken);
 
+        Assert.assertEquals(callContext.getTenantId(), tenantId);
         Assert.assertEquals(callContext.getCreatedDate(), createdDate);
         Assert.assertNull(callContext.getCallOrigin());
         Assert.assertEquals(callContext.getComment(), comment);
@@ -51,19 +53,20 @@ public class TestDefaultCallContext extends UtilTestSuite {
 
     @Test(groups = "fast")
     public void testEquals() throws Exception {
+        final UUID tenantId = UUID.randomUUID();
         final String userName = UUID.randomUUID().toString();
         final DateTime createdDate = clock.getUTCNow();
         final String reasonCode = UUID.randomUUID().toString();
         final String comment = UUID.randomUUID().toString();
         final UUID userToken = UUID.randomUUID();
 
-        final DefaultCallContext callContext = new DefaultCallContext(userName, createdDate, reasonCode, comment, userToken);
+        final DefaultCallContext callContext = new DefaultCallContext(tenantId, userName, createdDate, reasonCode, comment, userToken);
         Assert.assertEquals(callContext, callContext);
 
-        final DefaultCallContext sameCallContext = new DefaultCallContext(userName, createdDate, reasonCode, comment, userToken);
+        final DefaultCallContext sameCallContext = new DefaultCallContext(tenantId, userName, createdDate, reasonCode, comment, userToken);
         Assert.assertEquals(sameCallContext, callContext);
 
-        final DefaultCallContext otherCallContext = new DefaultCallContext(UUID.randomUUID().toString(), createdDate, reasonCode, comment, userToken);
+        final DefaultCallContext otherCallContext = new DefaultCallContext(tenantId, UUID.randomUUID().toString(), createdDate, reasonCode, comment, userToken);
         Assert.assertNotEquals(otherCallContext, callContext);
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
index 0c3a5dd..707800f 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
@@ -16,14 +16,15 @@
 
 package com.ning.billing.util.config;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
+
 import org.testng.annotations.Test;
 import org.xml.sax.SAXException;
 
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
index fde04b0..8533f50 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
@@ -16,11 +16,12 @@
 
 package com.ning.billing.util.config;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
 import java.io.IOException;
 import java.io.InputStream;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
+
 import org.testng.annotations.Test;
 
 import com.ning.billing.util.UtilTestSuite;
diff --git a/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java b/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
index 0e46f0a..b785208 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
@@ -23,30 +23,33 @@ import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.dao.ObjectType;
 
 public class MockCustomFieldDao implements CustomFieldDao {
+
     private final Map<UUID, List<CustomField>> fields = new HashMap<UUID, List<CustomField>>();
 
     @Override
-    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType, final List<CustomField> entities, final CallContext context) {
+    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType,
+                                            final List<CustomField> entities, final InternalCallContext context) {
         fields.put(objectId, entities);
     }
 
     @Override
-    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<CustomField> entities, final CallContext context) {
+    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<CustomField> entities, final InternalCallContext context) {
         fields.put(objectId, entities);
     }
 
     @Override
-    public Map<String, CustomField> loadEntities(final UUID objectId, final ObjectType objectType) {
+    public Map<String, CustomField> loadEntities(final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
         return getMap(fields.get(objectId));
     }
 
     @Override
-    public Map<String, CustomField> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType) {
+    public Map<String, CustomField> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
         return getMap(fields.get(objectId));
     }
 
diff --git a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
index 6182629..d1f94b3 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
@@ -28,11 +28,6 @@ import org.testng.annotations.Test;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
@@ -44,7 +39,6 @@ import static org.testng.Assert.fail;
 public class TestFieldStore extends UtilTestSuiteWithEmbeddedDB {
     private final Logger log = LoggerFactory.getLogger(TestFieldStore.class);
     private final MysqlTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getMysqlTestingHelper();
-    private CallContext context;
     private IDBI dbi;
     private CustomFieldDao customFieldDao;
 
@@ -53,7 +47,6 @@ public class TestFieldStore extends UtilTestSuiteWithEmbeddedDB {
         try {
             dbi = helper.getDBI();
             customFieldDao = new AuditedCustomFieldDao(dbi);
-            context = new DefaultCallContextFactory(new ClockMock()).createCallContext("Fezzik", CallOrigin.TEST, UserType.TEST);
         } catch (Throwable t) {
             log.error("Setup failed", t);
             fail(t.toString());
@@ -72,21 +65,21 @@ public class TestFieldStore extends UtilTestSuiteWithEmbeddedDB {
         fieldStore1.setValue(fieldName, fieldValue);
 
         final CustomFieldSqlDao customFieldSqlDao = dbi.onDemand(CustomFieldSqlDao.class);
-        customFieldDao.saveEntitiesFromTransaction(customFieldSqlDao, id, objectType, fieldStore1.getEntityList(), context);
+        customFieldDao.saveEntitiesFromTransaction(customFieldSqlDao, id, objectType, fieldStore1.getEntityList(), internalCallContext);
 
         final FieldStore fieldStore2 = DefaultFieldStore.create(id, objectType);
-        fieldStore2.add(customFieldSqlDao.load(id.toString(), objectType));
+        fieldStore2.add(customFieldSqlDao.load(id.toString(), objectType, internalCallContext));
 
         assertEquals(fieldStore2.getValue(fieldName), fieldValue);
 
         fieldValue = "Cape Canaveral";
         fieldStore2.setValue(fieldName, fieldValue);
         assertEquals(fieldStore2.getValue(fieldName), fieldValue);
-        customFieldDao.saveEntitiesFromTransaction(customFieldSqlDao, id, objectType, fieldStore2.getEntityList(), context);
+        customFieldDao.saveEntitiesFromTransaction(customFieldSqlDao, id, objectType, fieldStore2.getEntityList(), internalCallContext);
 
         final FieldStore fieldStore3 = DefaultFieldStore.create(id, objectType);
         assertEquals(fieldStore3.getValue(fieldName), null);
-        fieldStore3.add(customFieldSqlDao.load(id.toString(), objectType));
+        fieldStore3.add(customFieldSqlDao.load(id.toString(), objectType, internalCallContext));
 
         assertEquals(fieldStore3.getValue(fieldName), fieldValue);
     }
diff --git a/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java b/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
index 4fe5198..d48cc32 100644
--- a/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
+++ b/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
@@ -22,12 +22,13 @@ import org.skife.config.ConfigurationObjectFactory;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.util.UtilTestSuite;
 import com.ning.billing.util.template.translation.DefaultCatalogTranslator;
 import com.ning.billing.util.template.translation.Translator;
 import com.ning.billing.util.template.translation.TranslatorConfig;
 
+import com.google.common.collect.ImmutableMap;
+
 import static org.testng.Assert.assertEquals;
 
 public class DefaultCatalogTranslationTest extends UtilTestSuite {
diff --git a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
index ed05f5f..3604a8f 100644
--- a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
+++ b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
@@ -28,14 +28,15 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.globallocker.GlobalLocker.LockerType;
 import com.ning.billing.util.io.IOUtils;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+
 @Guice(modules = TestMysqlGlobalLocker.TestMysqlGlobalLockerModule.class)
 public class TestMysqlGlobalLocker extends UtilTestSuiteWithEmbeddedDB {
     @Inject
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
index ba2232a..7026787 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
@@ -30,8 +30,6 @@ import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
@@ -40,6 +38,9 @@ import com.ning.billing.util.notificationq.Notification;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao.NotificationSqlMapper;
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueueEntryLifecycleState;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
@@ -80,11 +81,11 @@ public class TestNotificationSqlDao extends UtilTestSuiteWithEmbeddedDB {
         final String notificationKey = UUID.randomUUID().toString();
         final DateTime effDt = new DateTime();
         final Notification notif = new DefaultNotification("testBasic", hostname, notificationKey.getClass().getName(), notificationKey, accountId, effDt);
-        dao.insertNotification(notif);
+        dao.insertNotification(notif, internalCallContext);
 
         Thread.sleep(1000);
         final DateTime now = new DateTime();
-        final List<Notification> notifications = dao.getReadyNotifications(now.toDate(), hostname, 3, "testBasic");
+        final List<Notification> notifications = dao.getReadyNotifications(now.toDate(), hostname, 3, "testBasic", internalCallContext);
         assertNotNull(notifications);
         assertEquals(notifications.size(), 1);
 
@@ -96,9 +97,9 @@ public class TestNotificationSqlDao extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(notification.getNextAvailableDate(), null);
 
         final DateTime nextAvailable = now.plusMinutes(5);
-        final int res = dao.claimNotification(ownerId, nextAvailable.toDate(), notification.getId().toString(), now.toDate());
+        final int res = dao.claimNotification(ownerId, nextAvailable.toDate(), notification.getId().toString(), now.toDate(), internalCallContext);
         assertEquals(res, 1);
-        dao.insertClaimedHistory(ownerId, now.toDate(), notification.getId().toString());
+        dao.insertClaimedHistory(ownerId, now.toDate(), notification.getId().toString(), internalCallContext);
 
         notification = fetchNotification(notification.getId().toString());
         assertEquals(notification.getNotificationKey(), notificationKey);
@@ -107,7 +108,7 @@ public class TestNotificationSqlDao extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(notification.getProcessingState(), PersistentQueueEntryLifecycleState.IN_PROCESSING);
         validateDate(notification.getNextAvailableDate(), nextAvailable);
 
-        dao.clearNotification(notification.getId().toString(), ownerId);
+        dao.clearNotification(notification.getId().toString(), ownerId, internalCallContext);
 
         notification = fetchNotification(notification.getId().toString());
         assertEquals(notification.getNotificationKey(), notificationKey);
@@ -122,19 +123,19 @@ public class TestNotificationSqlDao extends UtilTestSuiteWithEmbeddedDB {
         final String notificationKey = UUID.randomUUID().toString();
         final DateTime effDt = new DateTime();
         final Notification notif1 = new DefaultNotification("testBasic1", hostname, notificationKey.getClass().getName(), notificationKey, accountId, effDt);
-        dao.insertNotification(notif1);
+        dao.insertNotification(notif1, internalCallContext);
 
         final Notification notif2 = new DefaultNotification("testBasic2", hostname, notificationKey.getClass().getName(), notificationKey, accountId, effDt);
-        dao.insertNotification(notif2);
+        dao.insertNotification(notif2, internalCallContext);
 
-        List<Notification> notifications = dao.getNotificationForAccountAndDate(accountId.toString(), effDt.toDate());
+        List<Notification> notifications = dao.getNotificationForAccountAndDate(accountId.toString(), effDt.toDate(), internalCallContext);
         assertEquals(notifications.size(), 2);
         for (final Notification cur : notifications) {
             Assert.assertEquals(cur.getProcessingState(), PersistentQueueEntryLifecycleState.AVAILABLE);
-            dao.removeNotification(cur.getId().toString());
+            dao.removeNotification(cur.getId().toString(), internalCallContext);
         }
 
-        notifications = dao.getNotificationForAccountAndDate(accountId.toString(), effDt.toDate());
+        notifications = dao.getNotificationForAccountAndDate(accountId.toString(), effDt.toDate(), internalCallContext);
         assertEquals(notifications.size(), 2);
         for (final Notification cur : notifications) {
             Assert.assertEquals(cur.getProcessingState(), PersistentQueueEntryLifecycleState.REMOVED);
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
index 259952c..8e4bd5c 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
@@ -26,12 +26,14 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ning.billing.config.NotificationConfig;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueueEntryLifecycleState;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 public class MockNotificationQueue extends NotificationQueueBase implements NotificationQueue {
     private static final ObjectMapper objectMapper = new ObjectMapper();
 
@@ -52,7 +54,8 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public void recordFutureNotification(final DateTime futureNotificationTime, final UUID accountId, final NotificationKey notificationKey) throws IOException {
+    public void recordFutureNotification(final DateTime futureNotificationTime, final UUID accountId,
+                                         final NotificationKey notificationKey, final InternalCallContext context) throws IOException {
         final String json = objectMapper.writeValueAsString(notificationKey);
         final Notification notification = new DefaultNotification("MockQueue", getHostname(), notificationKey.getClass().getName(), json, accountId, futureNotificationTime);
         synchronized (notifications) {
@@ -61,8 +64,9 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime futureNotificationTime, final UUID accountId, final NotificationKey notificationKey) throws IOException {
-        recordFutureNotification(futureNotificationTime, accountId, notificationKey);
+    public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime futureNotificationTime,
+                                                        final UUID accountId, final NotificationKey notificationKey, final InternalCallContext context) throws IOException {
+        recordFutureNotification(futureNotificationTime, accountId, notificationKey, context);
     }
 
     public List<Notification> getPendingEvents() {
@@ -118,7 +122,7 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public void removeNotificationsByKey(final NotificationKey key) {
+    public void removeNotificationsByKey(final NotificationKey key, final InternalCallContext context) {
         final List<Notification> toClearNotifications = new ArrayList<Notification>();
         for (final Notification notification : notifications) {
             if (notification.getNotificationKey().equals(key.toString())) {
@@ -134,15 +138,11 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public List<Notification> getNotificationForAccountAndDate(UUID accountId,
-            DateTime effectiveDate) {
-        // TODO Auto-generated method stub
+    public List<Notification> getNotificationForAccountAndDate(final UUID accountId, final DateTime effectiveDate, final InternalCallContext context) {
         return null;
     }
 
     @Override
-    public void removeNotification(UUID notificationId) {
-        // TODO Auto-generated method stub
-
+    public void removeNotification(final UUID notificationId, final InternalCallContext context) {
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
index 5cedbe3..8fd6c3b 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.util.notificationq;
 
-import com.google.inject.Inject;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.inject.Inject;
+
 public class MockNotificationQueueService extends NotificationQueueServiceBase {
 
     @Inject
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index 32fdc70..f45d417 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -37,23 +37,25 @@ import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.name.Names;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.name.Names;
+
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.MINUTES;
 import static org.testng.Assert.assertEquals;
@@ -143,7 +145,8 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                                                                     }
                                                                                 }
                                                                             },
-                                                                            getNotificationConfig(false, 100, 1, 10000));
+                                                                            getNotificationConfig(false, 100, 1, 10000),
+                                                                            new InternalCallContextFactory(dbi, clock));
 
         queue.startQueue();
 
@@ -162,8 +165,7 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                       final TransactionStatus status) throws Exception {
 
                 transactional.insertDummy(obj);
-                queue.recordFutureNotificationFromTransaction(transactional,
-                                                              readyTime, accountId, notificationKey);
+                queue.recordFutureNotificationFromTransaction(transactional, readyTime, accountId, notificationKey, internalCallContext);
                 log.info("Posted key: " + notificationKey);
 
                 return null;
@@ -199,7 +201,8 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                                                                     }
                                                                                 }
                                                                             },
-                                                                            getNotificationConfig(false, 100, 10, 10000));
+                                                                            getNotificationConfig(false, 100, 10, 10000),
+                                                                            new InternalCallContextFactory(dbi, clock));
 
         queue.startQueue();
 
@@ -222,8 +225,8 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                           final TransactionStatus status) throws Exception {
 
                     transactional.insertDummy(obj);
-                    queue.recordFutureNotificationFromTransaction(transactional,
-                                                                  now.plus((currentIteration + 1) * nextReadyTimeIncrementMs), accountId, notificationKey);
+                    queue.recordFutureNotificationFromTransaction(transactional, now.plus((currentIteration + 1) * nextReadyTimeIncrementMs),
+                                                                  accountId, notificationKey, internalCallContext);
                     return null;
                 }
             });
@@ -278,7 +281,7 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
         final Map<NotificationKey, Boolean> expectedNotificationsFred = new TreeMap<NotificationKey, Boolean>();
         final Map<NotificationKey, Boolean> expectedNotificationsBarney = new TreeMap<NotificationKey, Boolean>();
 
-        final NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
+        final NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock, new InternalCallContextFactory(dbi, clock));
 
         final NotificationConfig config = new NotificationConfig() {
             @Override
@@ -333,11 +336,9 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                       final TransactionStatus status) throws Exception {
 
                 transactional.insertDummy(obj);
-                queueFred.recordFutureNotificationFromTransaction(transactional,
-                                                                  readyTime, accountId, notificationKeyFred);
+                queueFred.recordFutureNotificationFromTransaction(transactional, readyTime, accountId, notificationKeyFred, internalCallContext);
                 log.info("posted key: " + notificationKeyFred.toString());
-                queueBarney.recordFutureNotificationFromTransaction(transactional,
-                                                                    readyTime, accountId, notificationKeyBarney);
+                queueBarney.recordFutureNotificationFromTransaction(transactional, readyTime, accountId, notificationKeyBarney, internalCallContext);
                 log.info("posted key: " + notificationKeyBarney.toString());
 
                 return null;
@@ -397,7 +398,8 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
                                                                                     }
                                                                                 }
                                                                             },
-                                                                            getNotificationConfig(false, 100, 10, 10000));
+                                                                            getNotificationConfig(false, 100, 10, 10000),
+                                                                            new InternalCallContextFactory(dbi, clock));
 
         queue.startQueue();
 
@@ -411,17 +413,14 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
             public Void inTransaction(final DummySqlTest transactional,
                                       final TransactionStatus status) throws Exception {
 
-                queue.recordFutureNotificationFromTransaction(transactional,
-                                                              start.plus(nextReadyTimeIncrementMs), accountId, notificationKey);
-                queue.recordFutureNotificationFromTransaction(transactional,
-                                                              start.plus(2 * nextReadyTimeIncrementMs), accountId, notificationKey);
-                queue.recordFutureNotificationFromTransaction(transactional,
-                                                              start.plus(3 * nextReadyTimeIncrementMs), accountId, notificationKey2);
+                queue.recordFutureNotificationFromTransaction(transactional, start.plus(nextReadyTimeIncrementMs), accountId, notificationKey, internalCallContext);
+                queue.recordFutureNotificationFromTransaction(transactional, start.plus(2 * nextReadyTimeIncrementMs), accountId, notificationKey, internalCallContext);
+                queue.recordFutureNotificationFromTransaction(transactional, start.plus(3 * nextReadyTimeIncrementMs), accountId, notificationKey2, internalCallContext);
                 return null;
             }
         });
 
-        queue.removeNotificationsByKey(notificationKey); // should remove 2 of the 3
+        queue.removeNotificationsByKey(notificationKey, internalCallContext); // should remove 2 of the 3
 
         // Move time in the future after the notification effectiveDate
         ((ClockMock) clock).setDeltaFromReality(4000000 + nextReadyTimeIncrementMs * 3);
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java
index 705966e..5a073e3 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.tag.dao;
 
-import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -24,34 +23,37 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
 
 public class MockTagDao implements TagDao {
+
     private final Map<UUID, List<Tag>> tagStore = new HashMap<UUID, List<Tag>>();
 
     @Override
     public void saveEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType,
-                                            final List<Tag> tags, final CallContext context) {
+                                            final List<Tag> tags, final InternalCallContext context) {
         tagStore.put(objectId, tags);
     }
 
     @Override
-    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<Tag> tags, final CallContext context) {
+    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<Tag> tags, final InternalCallContext context) {
         tagStore.put(objectId, tags);
     }
 
     @Override
-    public Map<String, Tag> loadEntities(final UUID objectId, final ObjectType objectType) {
+    public Map<String, Tag> loadEntities(final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
         return getMap(tagStore.get(objectId));
     }
 
     @Override
-    public Map<String, Tag> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType) {
+    public Map<String, Tag> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
         return getMap(tagStore.get(objectId));
     }
 
@@ -67,7 +69,7 @@ public class MockTagDao implements TagDao {
 
     @Override
     public void insertTag(final UUID objectId, final ObjectType objectType,
-                          final UUID tagDefinitionId, final CallContext context) {
+                          final UUID tagDefinitionId, final InternalCallContext context) {
         final Tag tag = new Tag() {
             private final UUID id = UUID.randomUUID();
 
@@ -91,7 +93,7 @@ public class MockTagDao implements TagDao {
 
     @Override
     public void deleteTag(final UUID objectId, final ObjectType objectType,
-                          final UUID tagDefinitionId, final CallContext context) {
+                          final UUID tagDefinitionId, final InternalCallContext context) {
         final List<Tag> tags = tagStore.get(objectId);
         if (tags != null) {
             final Iterator<Tag> tagIterator = tags.iterator();
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
index b1a1b5d..9c1c02e 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
@@ -24,26 +24,28 @@ import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.TagDefinition;
 
 public class MockTagDefinitionDao implements TagDefinitionDao {
+
     private final Map<String, TagDefinition> tags = new ConcurrentHashMap<String, TagDefinition>();
 
     @Override
-    public List<TagDefinition> getTagDefinitions() {
+    public List<TagDefinition> getTagDefinitions(final InternalTenantContext context) {
         return new ArrayList<TagDefinition>(tags.values());
     }
 
     @Override
-    public TagDefinition getByName(final String definitionName) {
+    public TagDefinition getByName(final String definitionName, final InternalTenantContext context) {
         return tags.get(definitionName);
     }
 
     @Override
     public TagDefinition create(final String definitionName, final String description,
-                                final CallContext context) throws TagDefinitionApiException {
+                                final InternalCallContext context) throws TagDefinitionApiException {
         final TagDefinition tag = new DefaultTagDefinition(definitionName, description, false);
 
         tags.put(tag.getId().toString(), tag);
@@ -51,17 +53,17 @@ public class MockTagDefinitionDao implements TagDefinitionDao {
     }
 
     @Override
-    public void deleteById(final UUID definitionId, final CallContext context) throws TagDefinitionApiException {
+    public void deleteById(final UUID definitionId, final InternalCallContext context) throws TagDefinitionApiException {
         tags.remove(definitionId.toString());
     }
 
     @Override
-    public TagDefinition getById(UUID definitionId) {
+    public TagDefinition getById(final UUID definitionId, final InternalTenantContext context) {
         return null;
     }
 
     @Override
-    public List<TagDefinition> getByIds(Collection<UUID> definitionIds) {
+    public List<TagDefinition> getByIds(final Collection<UUID> definitionIds, final InternalTenantContext context) {
         return null;
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
index 4f1f8ed..f6dc67d 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
@@ -34,10 +34,6 @@ import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusEvent;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
@@ -53,6 +49,7 @@ import static org.testng.Assert.assertEquals;
 
 @Guice(modules = MockTagStoreModuleSql.class)
 public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
+
     @Inject
     private MysqlTestingHelper helper;
 
@@ -68,12 +65,10 @@ public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
     @Inject
     private Bus bus;
 
-    private CallContext context;
     private EventsListener eventsListener;
 
     @BeforeClass(groups = "slow")
     public void setup() throws IOException {
-        context = new DefaultCallContextFactory(clock).createCallContext("Tag DAO test", CallOrigin.TEST, UserType.TEST, UUID.randomUUID());
         bus.start();
     }
 
@@ -88,75 +83,71 @@ public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
         bus.stop();
     }
 
-    @Test(groups= "slow")
+    @Test(groups = "slow")
     public void testGetByIds() throws TagDefinitionApiException {
         final List<UUID> uuids = new ArrayList<UUID>();
 
         // Check with a empty Collection first
-        List<TagDefinition> result = tagDefinitionDao.getByIds(uuids);
+        List<TagDefinition> result = tagDefinitionDao.getByIds(uuids, internalCallContext);
         assertEquals(result.size(), 0);
 
-        final TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", context);
+        final TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", internalCallContext);
         uuids.add(defYo.getId());
-        final TagDefinition defBah = tagDefinitionDao.create("bah", "defintion bah", context);
+        final TagDefinition defBah = tagDefinitionDao.create("bah", "defintion bah", internalCallContext);
         uuids.add(defBah.getId());
-        final TagDefinition defZoo = tagDefinitionDao.create("zoo", "defintion zoo", context);
+        final TagDefinition defZoo = tagDefinitionDao.create("zoo", "defintion zoo", internalCallContext);
         uuids.add(defZoo.getId());
 
-        result = tagDefinitionDao.getByIds(uuids);
+        result = tagDefinitionDao.getByIds(uuids, internalCallContext);
         assertEquals(result.size(), 3);
 
         // Add control tag and retry
         uuids.add(ControlTagType.AUTO_PAY_OFF.getId());
-        result = tagDefinitionDao.getByIds(uuids);
+        result = tagDefinitionDao.getByIds(uuids, internalCallContext);
         assertEquals(result.size(), 4);
 
-        result = tagDefinitionDao.getTagDefinitions();
+        result = tagDefinitionDao.getTagDefinitions(internalCallContext);
         assertEquals(result.size(), 3 + ControlTagType.values().length);
     }
 
-    @Test(groups= "slow")
+    @Test(groups = "slow")
     public void testGetById() throws TagDefinitionApiException {
-
         // User Tag
-        TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", context);
-        TagDefinition resDefYo = tagDefinitionDao.getById(defYo.getId());
+        final TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", internalCallContext);
+        final TagDefinition resDefYo = tagDefinitionDao.getById(defYo.getId(), internalCallContext);
         assertEquals(defYo, resDefYo);
 
         // Control Tag
         try {
-            tagDefinitionDao.create(ControlTagType.AUTO_INVOICING_OFF.name(), ControlTagType.AUTO_INVOICING_OFF.name(), context);
+            tagDefinitionDao.create(ControlTagType.AUTO_INVOICING_OFF.name(), ControlTagType.AUTO_INVOICING_OFF.name(), internalCallContext);
             Assert.fail("Should not be able to create a control tag");
         } catch (TagDefinitionApiException ignore) {
         }
-        TagDefinition resdef_AUTO_INVOICING_OFF = tagDefinitionDao.getById(ControlTagType.AUTO_INVOICING_OFF.getId());
+        final TagDefinition resdef_AUTO_INVOICING_OFF = tagDefinitionDao.getById(ControlTagType.AUTO_INVOICING_OFF.getId(), internalCallContext);
         assertEquals(resdef_AUTO_INVOICING_OFF.getId(), ControlTagType.AUTO_INVOICING_OFF.getId());
         assertEquals(resdef_AUTO_INVOICING_OFF.getName(), ControlTagType.AUTO_INVOICING_OFF.name());
         assertEquals(resdef_AUTO_INVOICING_OFF.getDescription(), ControlTagType.AUTO_INVOICING_OFF.getDescription());
     }
 
-    @Test(groups= "slow")
+    @Test(groups = "slow")
     public void testGetByName() throws TagDefinitionApiException {
-
         // User Tag
-        TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", context);
-        TagDefinition resDefYo = tagDefinitionDao.getByName(defYo.getName());
+        final TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", internalCallContext);
+        final TagDefinition resDefYo = tagDefinitionDao.getByName(defYo.getName(), internalCallContext);
         assertEquals(defYo, resDefYo);
 
         // Control Tag
         try {
-            tagDefinitionDao.create(ControlTagType.AUTO_PAY_OFF.name(), ControlTagType.AUTO_INVOICING_OFF.name(), context);
+            tagDefinitionDao.create(ControlTagType.AUTO_PAY_OFF.name(), ControlTagType.AUTO_INVOICING_OFF.name(), internalCallContext);
             Assert.fail("Should not be able to create a control tag");
         } catch (TagDefinitionApiException ignore) {
         }
-        TagDefinition resdef_AUTO_PAY_OFF = tagDefinitionDao.getByName(ControlTagType.AUTO_PAY_OFF.name());
+        final TagDefinition resdef_AUTO_PAY_OFF = tagDefinitionDao.getByName(ControlTagType.AUTO_PAY_OFF.name(), internalCallContext);
         assertEquals(resdef_AUTO_PAY_OFF.getId(), ControlTagType.AUTO_PAY_OFF.getId());
         assertEquals(resdef_AUTO_PAY_OFF.getName(), ControlTagType.AUTO_PAY_OFF.name());
         assertEquals(resdef_AUTO_PAY_OFF.getDescription(), ControlTagType.AUTO_PAY_OFF.getDescription());
     }
 
-
-
     @Test(groups = "slow")
     public void testCatchEventsOnCreateAndDelete() throws Exception {
         final String definitionName = UUID.randomUUID().toString().substring(0, 5);
@@ -169,15 +160,15 @@ public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(eventsListener.getTagEvents().size(), 0);
 
         // Create a tag definition
-        final TagDefinition createdTagDefinition = tagDefinitionDao.create(definitionName, description, context);
+        final TagDefinition createdTagDefinition = tagDefinitionDao.create(definitionName, description, internalCallContext);
         Assert.assertEquals(createdTagDefinition.getName(), definitionName);
         Assert.assertEquals(createdTagDefinition.getDescription(), description);
 
         // Make sure we can create a tag
-        tagDao.insertTag(objectId, objectType, createdTagDefinition.getId(), context);
+        tagDao.insertTag(objectId, objectType, createdTagDefinition.getId(), internalCallContext);
 
         // Make sure we can retrieve it via the DAO
-        final Map<String, Tag> foundTags = tagDao.loadEntities(objectId, objectType);
+        final Map<String, Tag> foundTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         Assert.assertEquals(foundTags.keySet().size(), 1);
         Assert.assertEquals(foundTags.values().iterator().next().getTagDefinitionId(), createdTagDefinition.getId());
 
@@ -191,13 +182,13 @@ public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(tagFirstEventReceived.getTagDefinition().getName(), createdTagDefinition.getName());
         Assert.assertEquals(tagFirstEventReceived.getTagDefinition().getDescription(), createdTagDefinition.getDescription());
         Assert.assertEquals(tagFirstEventReceived.getBusEventType(), BusEvent.BusEventType.USER_TAG_CREATION);
-        Assert.assertEquals(tagFirstEventReceived.getUserToken(), context.getUserToken());
+        Assert.assertEquals(tagFirstEventReceived.getUserToken(), internalCallContext.getUserToken());
 
         // Delete the tag
-        tagDao.deleteTag(objectId, objectType, createdTagDefinition.getId(), context);
+        tagDao.deleteTag(objectId, objectType, createdTagDefinition.getId(), internalCallContext);
 
         // Make sure the tag is deleted
-        Assert.assertEquals(tagDao.loadEntities(objectId, objectType).keySet().size(), 0);
+        Assert.assertEquals(tagDao.loadEntities(objectId, objectType, internalCallContext).keySet().size(), 0);
 
         // Verify we caught an event on the bus
         Assert.assertEquals(eventsListener.getEvents().size(), 3);
@@ -209,10 +200,11 @@ public class TestAuditedTagDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(tagSecondEventReceived.getTagDefinition().getName(), createdTagDefinition.getName());
         Assert.assertEquals(tagSecondEventReceived.getTagDefinition().getDescription(), createdTagDefinition.getDescription());
         Assert.assertEquals(tagSecondEventReceived.getBusEventType(), BusEvent.BusEventType.USER_TAG_DELETION);
-        Assert.assertEquals(tagSecondEventReceived.getUserToken(), context.getUserToken());
+        Assert.assertEquals(tagSecondEventReceived.getUserToken(), internalCallContext.getUserToken());
     }
 
     private static final class EventsListener {
+
         private final List<BusEvent> events = new ArrayList<BusEvent>();
         private final List<TagEvent> tagEvents = new ArrayList<TagEvent>();
 
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
index 90d1abc..f9283a2 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
@@ -28,25 +28,21 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Inject;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusEvent;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.MockTagStoreModuleSql;
 import com.ning.billing.util.tag.TagDefinition;
-import com.ning.billing.util.tag.TestTagStore;
 import com.ning.billing.util.tag.api.TagDefinitionEvent;
 
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+
 @Guice(modules = MockTagStoreModuleSql.class)
 public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
+
     @Inject
     private MysqlTestingHelper helper;
 
@@ -59,12 +55,10 @@ public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
     @Inject
     private Bus bus;
 
-    private CallContext context;
     private EventsListener eventsListener;
 
     @BeforeClass(groups = "slow")
     public void setup() throws IOException {
-        context = new DefaultCallContextFactory(clock).createCallContext("TagDefinition DAO test", CallOrigin.TEST, UserType.TEST, UUID.randomUUID());
         bus.start();
     }
 
@@ -89,12 +83,12 @@ public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(eventsListener.getTagDefinitionEvents().size(), 0);
 
         // Make sure we can create a tag definition
-        final TagDefinition createdTagDefinition = tagDefinitionDao.create(definitionName, description, context);
+        final TagDefinition createdTagDefinition = tagDefinitionDao.create(definitionName, description, internalCallContext);
         Assert.assertEquals(createdTagDefinition.getName(), definitionName);
         Assert.assertEquals(createdTagDefinition.getDescription(), description);
 
         // Make sure we can retrieve it via the DAO
-        final TagDefinition foundTagDefinition = tagDefinitionDao.getByName(definitionName);
+        final TagDefinition foundTagDefinition = tagDefinitionDao.getByName(definitionName, internalCallContext);
         Assert.assertEquals(foundTagDefinition, createdTagDefinition);
 
         // Verify we caught an event on the bus
@@ -105,13 +99,13 @@ public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(tagDefinitionFirstEventReceived.getTagDefinitionId(), createdTagDefinition.getId());
         Assert.assertEquals(tagDefinitionFirstEventReceived.getTagDefinition(), createdTagDefinition);
         Assert.assertEquals(tagDefinitionFirstEventReceived.getBusEventType(), BusEvent.BusEventType.USER_TAGDEFINITION_CREATION);
-        Assert.assertEquals(tagDefinitionFirstEventReceived.getUserToken(), context.getUserToken());
+        Assert.assertEquals(tagDefinitionFirstEventReceived.getUserToken(), internalCallContext.getUserToken());
 
         // Delete the tag definition
-        tagDefinitionDao.deleteById(foundTagDefinition.getId(), context);
+        tagDefinitionDao.deleteById(foundTagDefinition.getId(), internalCallContext);
 
         // Make sure the tag definition is deleted
-        Assert.assertNull(tagDefinitionDao.getByName(definitionName));
+        Assert.assertNull(tagDefinitionDao.getByName(definitionName, internalCallContext));
 
         // Verify we caught an event on the bus
         Assert.assertEquals(eventsListener.getEvents().size(), 2);
@@ -121,10 +115,11 @@ public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertEquals(tagDefinitionSecondEventReceived.getTagDefinitionId(), createdTagDefinition.getId());
         Assert.assertEquals(tagDefinitionSecondEventReceived.getTagDefinition(), createdTagDefinition);
         Assert.assertEquals(tagDefinitionSecondEventReceived.getBusEventType(), BusEvent.BusEventType.USER_TAGDEFINITION_DELETION);
-        Assert.assertEquals(tagDefinitionSecondEventReceived.getUserToken(), context.getUserToken());
+        Assert.assertEquals(tagDefinitionSecondEventReceived.getUserToken(), internalCallContext.getUserToken());
     }
 
     private static final class EventsListener {
+
         private final List<BusEvent> events = new ArrayList<BusEvent>();
         private final List<TagDefinitionEvent> tagDefinitionEvents = new ArrayList<TagDefinitionEvent>();
 
diff --git a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
index 36ecd36..9bb7802 100644
--- a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
+++ b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
@@ -26,7 +26,6 @@ import org.joda.time.DateTime;
 import org.joda.time.Seconds;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.tweak.HandleCallback;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterClass;
@@ -34,22 +33,18 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
-import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
+import com.google.inject.Inject;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
@@ -59,6 +54,7 @@ import static org.testng.Assert.fail;
 @Test(groups = {"slow"})
 @Guice(modules = MockTagStoreModuleSql.class)
 public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
+
     @Inject
     private MysqlTestingHelper helper;
 
@@ -80,16 +76,14 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
     private TagDefinition testTag;
 
     private final Logger log = LoggerFactory.getLogger(TestTagStore.class);
-    private CallContext context;
 
     @BeforeClass(groups = "slow")
     protected void setup() throws IOException {
         try {
-            context = new DefaultCallContextFactory(clock).createCallContext("Tag store test", CallOrigin.TEST, UserType.TEST);
             bus.start();
 
-            tagDefinitionDao.create("tag1", "First tag", context);
-            testTag = tagDefinitionDao.create("testTag", "Second tag", context);
+            tagDefinitionDao.create("tag1", "First tag", internalCallContext);
+            testTag = tagDefinitionDao.create("testTag", "Second tag", internalCallContext);
         } catch (Throwable t) {
             log.error("Failed to start tag store tests", t);
             fail(t.toString());
@@ -109,9 +103,9 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(testTag.getId());
         tagStore.add(tag);
 
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
-        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(savedTags.size(), 1);
 
         final Tag savedTag = savedTags.get(tag.getId().toString());
@@ -119,7 +113,6 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(savedTag.getId(), tag.getId());
     }
 
-
     @Test(groups = "slow")
     public void testControlTagCreation() {
         final UUID accountId = UUID.randomUUID();
@@ -130,12 +123,12 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(tagStore.generateInvoice(), false);
 
         final List<Tag> tagList = tagStore.getEntityList();
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagList, context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagList, internalCallContext);
 
         tagStore.clear();
         assertEquals(tagStore.getEntityList().size(), 0);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 1);
 
         assertEquals(tagMap.values().iterator().next().getTagDefinitionId(), ControlTagType.AUTO_INVOICING_OFF.getId());
@@ -149,7 +142,7 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final String definitionName = "SomeTestTag";
         TagDefinition tagDefinition = null;
         try {
-            tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", context);
+            tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", internalCallContext);
         } catch (TagDefinitionApiException e) {
             fail("Tag definition creation failed.", e);
         }
@@ -158,12 +151,12 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         tagStore.add(tag);
         assertEquals(tagStore.generateInvoice(), true);
 
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
         tagStore.clear();
         assertEquals(tagStore.getEntityList().size(), 0);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 1);
 
         assertEquals(tagMap.values().iterator().next().getTagDefinitionId(), tagDefinition.getId());
@@ -177,7 +170,7 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final String definitionName = "MixedTagTest";
         TagDefinition tagDefinition = null;
         try {
-            tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", context);
+            tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", internalCallContext);
         } catch (TagDefinitionApiException e) {
             fail("Tag definition creation failed.", e);
         }
@@ -190,12 +183,12 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         tagStore.add(controlTag);
         assertEquals(tagStore.generateInvoice(), false);
 
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
         tagStore.clear();
         assertEquals(tagStore.getEntityList().size(), 0);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 2);
 
         boolean found_AUTO_INVOICING_OFF_tag = false;
@@ -230,28 +223,28 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
     @Test(groups = "slow", expectedExceptions = TagDefinitionApiException.class)
     public void testTagDefinitionCreationWithControlTagName() throws TagDefinitionApiException {
         final String definitionName = ControlTagType.AUTO_PAY_OFF.toString();
-        tagDefinitionDao.create(definitionName, "This should break", context);
+        tagDefinitionDao.create(definitionName, "This should break", internalCallContext);
     }
 
     @Test(groups = "slow")
     public void testTagDefinitionDeletionForUnusedDefinition() throws TagDefinitionApiException {
         final String definitionName = "TestTag1234";
-        tagDefinitionDao.create(definitionName, "Some test tag", context);
+        tagDefinitionDao.create(definitionName, "Some test tag", internalCallContext);
 
-        TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
+        TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName, internalCallContext);
         assertNotNull(tagDefinition);
 
-        tagDefinitionDao.deleteById(tagDefinition.getId(), context);
-        tagDefinition = tagDefinitionDao.getByName(definitionName);
+        tagDefinitionDao.deleteById(tagDefinition.getId(), internalCallContext);
+        tagDefinition = tagDefinitionDao.getByName(definitionName, internalCallContext);
         assertNull(tagDefinition);
     }
 
     @Test(groups = "slow", expectedExceptions = TagDefinitionApiException.class)
     public void testTagDefinitionDeletionForDefinitionInUse() throws TagDefinitionApiException {
         final String definitionName = "TestTag12345";
-        tagDefinitionDao.create(definitionName, "Some test tag", context);
+        tagDefinitionDao.create(definitionName, "Some test tag", internalCallContext);
 
-        final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
+        final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName, internalCallContext);
         assertNotNull(tagDefinition);
 
         final UUID objectId = UUID.randomUUID();
@@ -259,24 +252,24 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(tagDefinition.getId());
         tagStore.add(tag);
 
-        tagDao.saveEntities(objectId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(objectId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(objectId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 1);
 
-        tagDefinitionDao.deleteById(tagDefinition.getId(), context);
+        tagDefinitionDao.deleteById(tagDefinition.getId(), internalCallContext);
     }
 
     @Test(groups = "slow")
     public void testDeleteTagBeforeDeleteTagDefinition() throws TagApiException {
         final String definitionName = "TestTag1234567";
         try {
-            tagDefinitionDao.create(definitionName, "Some test tag", context);
+            tagDefinitionDao.create(definitionName, "Some test tag", internalCallContext);
         } catch (TagDefinitionApiException e) {
             fail("Could not create tag definition", e);
         }
 
-        final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
+        final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName, internalCallContext);
         assertNotNull(tagDefinition);
 
         final UUID objectId = UUID.randomUUID();
@@ -284,17 +277,17 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(tagDefinition.getId());
         tagStore.add(tag);
 
-        tagDao.saveEntities(objectId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(objectId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
-        final Map<String, Tag> tagMap = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(objectId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMap.size(), 1);
 
-        tagDao.deleteTag(objectId, ObjectType.ACCOUNT, tagDefinition.getId(), context);
-        final Map<String, Tag> tagMapAfterDeletion = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
+        tagDao.deleteTag(objectId, ObjectType.ACCOUNT, tagDefinition.getId(), internalCallContext);
+        final Map<String, Tag> tagMapAfterDeletion = tagDao.loadEntities(objectId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(tagMapAfterDeletion.size(), 0);
 
         try {
-            tagDefinitionDao.deleteById(tagDefinition.getId(), context);
+            tagDefinitionDao.deleteById(tagDefinition.getId(), internalCallContext);
         } catch (TagDefinitionApiException e) {
             fail("Could not delete tag definition", e);
         }
@@ -302,7 +295,7 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testGetTagDefinitions() {
-        final List<TagDefinition> definitionList = tagDefinitionDao.getTagDefinitions();
+        final List<TagDefinition> definitionList = tagDefinitionDao.getTagDefinitions(internalCallContext);
         assertTrue(definitionList.size() >= ControlTagType.values().length);
     }
 
@@ -314,9 +307,9 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(testTag.getId());
         tagStore.add(tag);
 
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
-        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(savedTags.size(), 1);
 
         final Tag savedTag = savedTags.get(tag.getId().toString());
@@ -334,8 +327,8 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(result.get(0).get("change_type"), "INSERT");
         assertNotNull(result.get(0).get("change_date"));
         final DateTime changeDate = new DateTime(result.get(0).get("change_date"));
-        assertTrue(Seconds.secondsBetween(changeDate, context.getCreatedDate()).getSeconds() < 2);
-        assertEquals(result.get(0).get("changed_by"), context.getUserName());
+        assertTrue(Seconds.secondsBetween(changeDate, internalCallContext.getCreatedDate()).getSeconds() < 2);
+        assertEquals(result.get(0).get("changed_by"), internalCallContext.getUserName());
     }
 
     @Test
@@ -346,12 +339,12 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(testTag.getId());
         tagStore.add(tag);
 
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
         tagStore.remove(tag);
-        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), context);
+        tagDao.saveEntities(accountId, ObjectType.ACCOUNT, tagStore.getEntityList(), internalCallContext);
 
-        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, Tag> savedTags = tagDao.loadEntities(accountId, ObjectType.ACCOUNT, internalCallContext);
         assertEquals(savedTags.size(), 0);
 
         final Handle handle = dbi.open();
@@ -364,31 +357,31 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         assertEquals(result.size(), 1);
         assertNotNull(result.get(0).get("change_date"));
         final DateTime changeDate = new DateTime(result.get(0).get("change_date"));
-        assertTrue(Seconds.secondsBetween(changeDate, context.getUpdatedDate()).getSeconds() < 2);
-        assertEquals(result.get(0).get("changed_by"), context.getUserName());
+        assertTrue(Seconds.secondsBetween(changeDate, internalCallContext.getUpdatedDate()).getSeconds() < 2);
+        assertEquals(result.get(0).get("changed_by"), internalCallContext.getUserName());
     }
 
     @Test
     public void testAddTag() throws TagApiException, TagDefinitionApiException {
         final UUID objectId = UUID.randomUUID();
         final ObjectType objectType = ObjectType.INVOICE;
-        final TagDefinition tagDefinition = tagDefinitionDao.create("test tag", "test", context);
-        tagDao.insertTag(objectId, objectType, tagDefinition.getId(), context);
-        final Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType);
+        final TagDefinition tagDefinition = tagDefinitionDao.create("test tag", "test", internalCallContext);
+        tagDao.insertTag(objectId, objectType, tagDefinition.getId(), internalCallContext);
+        final Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         assertEquals(savedTags.size(), 1);
     }
 
     @Test
-    public void testRemoveTag() throws TagApiException, TagDefinitionApiException  {
+    public void testRemoveTag() throws TagApiException, TagDefinitionApiException {
         final UUID objectId = UUID.randomUUID();
         final ObjectType objectType = ObjectType.INVOICE;
-        final TagDefinition tagDefinition = tagDefinitionDao.create("test tag", "test", context);
-        tagDao.insertTag(objectId, objectType, tagDefinition.getId(), context);
-        Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType);
+        final TagDefinition tagDefinition = tagDefinitionDao.create("test tag", "test", internalCallContext);
+        tagDao.insertTag(objectId, objectType, tagDefinition.getId(), internalCallContext);
+        Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         assertEquals(savedTags.size(), 1);
 
-        tagDao.deleteTag(objectId, objectType, tagDefinition.getId(), context);
-        savedTags = tagDao.loadEntities(objectId, objectType);
+        tagDao.deleteTag(objectId, objectType, tagDefinition.getId(), internalCallContext);
+        savedTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         assertEquals(savedTags.size(), 0);
     }
 
@@ -401,17 +394,17 @@ public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
         tags.add(new DescriptiveTag(UUID.randomUUID()));
         tags.add(new DescriptiveTag(UUID.randomUUID()));
         tags.add(new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF));
-        tagDao.saveEntities(objectId, objectType, tags, context);
+        tagDao.saveEntities(objectId, objectType, tags, internalCallContext);
 
-        Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType);
+        Map<String, Tag> savedTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         assertEquals(savedTags.size(), 3);
 
         tags.remove(1);
         assertEquals(tags.size(), 2);
 
-        tagDao.saveEntities(objectId, objectType, tags, context);
+        tagDao.saveEntities(objectId, objectType, tags, internalCallContext);
 
-        savedTags = tagDao.loadEntities(objectId, objectType);
+        savedTags = tagDao.loadEntities(objectId, objectType, internalCallContext);
         assertEquals(savedTags.size(), 2);
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
index 9406f4d..eac5741 100644
--- a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
+++ b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
@@ -21,13 +21,11 @@ import java.util.Collection;
 
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.util.UtilTestSuite;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.globallocker.TestMysqlGlobalLocker;
 import com.ning.billing.util.io.IOUtils;