killbill-aplcache

Merge branch 'integration' of github.com:ning/killbill

3/30/2012 7:10:16 PM

Changes

.travis.yml 6(+6 -0)

account/pom.xml 27(+6 -21)

analytics/pom.xml 25(+10 -15)

api/pom.xml 1(+0 -1)

beatrix/pom.xml 25(+4 -21)

catalog/pom.xml 2(+1 -1)

entitlement/pom.xml 59(+11 -48)

entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadAccount.java 228(+0 -228)

entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadAccountUserApi.java 82(+0 -82)

invoice/pom.xml 36(+15 -21)

payment/pom.xml 18(+9 -9)

pom.xml 73(+52 -21)

util/pom.xml 42(+17 -25)

Details

.travis.yml 6(+6 -0)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..93b1a6e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: java
+script: mvn clean install -Ptravis
+
+notifications:
+  email:
+    - ri-dev@ning.com

account/pom.xml 27(+6 -21)

diff --git a/account/pom.xml b/account/pom.xml
index 28c7a7a..c48b8b2 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -25,14 +25,6 @@
             <artifactId>jdbi</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ning.jdbi</groupId>
-            <artifactId>jdbi-metrics</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
             <scope>provided</scope>
@@ -77,18 +69,18 @@
             <artifactId>guava</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj-db-files</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -101,13 +93,6 @@
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <groups>setup,fast</groups>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <executions>
                     <execution>
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
index 31f0a37..a22491b 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
@@ -26,11 +26,6 @@ import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.customfield.CustomizableEntityBase;
-import com.ning.billing.util.tag.DefaultTagStore;
-import com.ning.billing.util.tag.DescriptiveTag;
-import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
 
 import javax.annotation.Nullable;
 
@@ -89,25 +84,27 @@ public class DefaultAccount extends ExtendedEntityBase implements Account {
 	}
 
 	/**
-	 * This call is used for testing 
-	 * @param id UUID system-generated account id
-	 * @param externalKey String key for external systems
-	 * @param email String account owner's e-mail address
-	 * @param name String account owner's name
-	 * @param firstNameLength String the length of the account owner's first name
-	 * @param currency Currency the currency for billing for the account
-	 * @param billCycleDay int the day of the month upon which invoices should be generated for this account
-	 * @param paymentProviderName String payment provider name
-	 * @param timeZone String the name of the time zone to be used for invoice generation
-	 * @param locale String the locale for internationalization
-	 * @param address1 String address information for the account owner
-	 * @param address2 String (optional) more address information for the account owner
-	 * @param companyName String (optional) the company of the account owner
-	 * @param city String the city of the account owner
-	 * @param stateOrProvince String the state or province of the account owner
-	 * @param country String the country of the account owner
-	 * @param postalCode String the postal code of the account owner
-	 * @param phone String the phone number of the account owner
+	 * This call is used for testing and update from an existing account
+	 * @param id
+	 * @param externalKey
+	 * @param email
+	 * @param name
+	 * @param firstNameLength
+	 * @param currency
+	 * @param billCycleDay
+	 * @param paymentProviderName
+	 * @param timeZone
+	 * @param locale
+	 * @param address1
+	 * @param address2
+	 * @param companyName
+	 * @param city
+	 * @param stateOrProvince
+	 * @param country
+	 * @param postalCode
+	 * @param phone
+	 * @param createdDate
+	 * @param updatedDate
 	 */
 	public DefaultAccount(final UUID id, final String externalKey, final String email,
                           final String name, final int firstNameLength,
@@ -256,6 +253,11 @@ public class DefaultAccount extends ExtendedEntityBase implements Account {
 		return phone;
 	}
 
+    @Override
+	public MutableAccountData toMutableAccountData() {
+	    return new MutableAccountData(this);
+	}
+    
 	@Override
 	public String toString() {
 		return "DefaultAccount [externalKey=" + externalKey +
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 8552f21..6fb31b5 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
@@ -26,6 +26,7 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.account.api.MigrationAccountData;
+import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
@@ -87,15 +88,10 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
             throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
         }
     }
-
+    
     @Override
-    public void updateAccount(final String externalKey, final AccountData accountData,
-                              final CallContext context) throws AccountApiException {
-    	UUID accountId = getIdFromKey(externalKey);
-    	if(accountId == null) {
-    		throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
-    	}
-
+    public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context)
+            throws AccountApiException {
         Account account = new DefaultAccount(accountId, accountData);
 
         try {
@@ -103,8 +99,19 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
         } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
         }
+  
     }
 
+    @Override
+    public void updateAccount(final String externalKey, final AccountData accountData, final CallContext context) throws AccountApiException {
+    	UUID accountId = getIdFromKey(externalKey);
+    	if(accountId == null) {
+    		throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
+    	}
+
+    	updateAccount(accountId, accountData, context);
+     }
+
 	@Override
 	public void deleteAccountByKey(final String externalKey, final CallContext context) throws AccountApiException {
 		dao.deleteByKey(externalKey, context);
@@ -127,4 +134,6 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
 
         return account;
 	}
+
+
 }
diff --git a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
index a56b4b8..265b933 100644
--- a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
+++ b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
@@ -127,8 +127,14 @@ public class MockAccountUserApi implements AccountUserApi {
 	}
 
 	@Override
-	public void updateAccount(String key, AccountData accountData, final CallContext context)
+	public void updateAccount(final String key, final AccountData accountData, final CallContext context)
 			throws AccountApiException {
 		throw new UnsupportedOperationException();
 	}
+
+    @Override
+    public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context)
+            throws AccountApiException {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
index e2fb351..10d904f 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
@@ -18,6 +18,7 @@ package com.ning.billing.account.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 static org.testng.Assert.fail;
 
@@ -373,7 +374,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
         accountDao.update(updatedAccount, context);
     }
 
-    @Test(groups={"slow"},enabled=true)
+    @Test
     public void testDelete() throws AccountApiException, EntityPersistenceException {
 
         Account a = createTestAccountBuilder().build();
@@ -387,8 +388,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
         accountDao.deleteByKey(key, context);
         
         Account s = accountDao.getAccountByKey(key);
-        assertTrue(s==null);
-
+        assertNull(s);
     }
 
 }

analytics/pom.xml 25(+10 -15)

diff --git a/analytics/pom.xml b/analytics/pom.xml
index 8a655ca..d5fff4c 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -31,16 +31,6 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
@@ -54,11 +44,6 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
             <groupId>org.antlr</groupId>
             <artifactId>stringtemplate</artifactId>
             <scope>runtime</scope>
@@ -108,6 +93,16 @@
             <type>test-jar</type>
             <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>
     </dependencies>
     <build>
     </build>
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index dc488fb..1aafa7c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -19,6 +19,8 @@ package com.ning.billing.analytics;
 import com.ning.billing.invoice.glue.InvoiceModule;
 import com.ning.billing.payment.setup.PaymentModule;
 import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
 import org.skife.jdbi.v2.IDBI;
 import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.analytics.setup.AnalyticsModule;
@@ -32,6 +34,8 @@ import com.ning.billing.util.glue.ClockModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.TagStoreModule;
 
+import java.lang.reflect.Field;
+
 public class AnalyticsTestModule extends AnalyticsModule
 {
     @Override
@@ -42,6 +46,8 @@ public class AnalyticsTestModule extends AnalyticsModule
         // Need to configure a few more things for the EventBus
         install(new ClockModule());
         install(new CallContextModule());
+        install(new FieldStoreModule());
+        install(new TagStoreModule());
         install(new AccountModule());
         install(new CatalogModule());
         install(new BusModule());
@@ -56,5 +62,7 @@ public class AnalyticsTestModule extends AnalyticsModule
         bind(MysqlTestingHelper.class).toInstance(helper);
         final IDBI dbi = helper.getDBI();
         bind(IDBI.class).toInstance(dbi);
+
+        bind(TagDefinitionSqlDao.class).toInstance(dbi.onDemand(TagDefinitionSqlDao.class));
     }
 }
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 22c667f..fde6a1a 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
@@ -26,6 +26,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 
+import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.UserType;
@@ -247,13 +248,14 @@ public class TestAnalyticsService {
     private void createInvoiceAndPaymentCreationEvents(final Account account) {
         final DefaultInvoice invoice = new DefaultInvoice(account.getId(), clock.getUTCNow(), clock.getUTCNow(), ACCOUNT_CURRENCY);
         final FixedPriceInvoiceItem invoiceItem = new FixedPriceInvoiceItem(
-                UUID.randomUUID(), account.getId(), invoice.getId(), UUID.randomUUID(), "somePlan", "somePhase", clock.getUTCNow(), clock.getUTCNow().plusDays(1),
+                UUID.randomUUID(), invoice.getId(), account.getId(), UUID.randomUUID(), "somePlan", "somePhase", clock.getUTCNow(), clock.getUTCNow().plusDays(1),
                 INVOICE_AMOUNT, ACCOUNT_CURRENCY, context.getUserName(), clock.getUTCNow());
         invoice.addInvoiceItem(invoiceItem);
 
         invoiceDao.create(invoice, context);
-        Assert.assertEquals(invoiceDao.getInvoicesByAccount(account.getId()).size(), 1);
-        Assert.assertEquals(invoiceDao.getInvoicesByAccount(account.getId()).get(0).getInvoiceItems().size(), 1);
+        List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId());
+        Assert.assertEquals(invoices.size(), 1);
+        Assert.assertEquals(invoices.get(0).getInvoiceItems().size(), 1);
 
         // It doesn't really matter what the events contain - the listener will go back to the db
         invoiceCreationNotification = new DefaultInvoiceCreationNotification(invoice.getId(), account.getId(),
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 e31d562..b7613cc 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
@@ -118,13 +118,13 @@ public class TestAnalyticsDao
         }
     }
 
-    @AfterClass(alwaysRun = true)
+    @AfterClass(groups = "slow")
     public void stopMysql()
     {
         helper.stopMysql();
     }
 
-    @BeforeMethod
+    @BeforeMethod(groups = "slow")
     public void cleanup() throws Exception
     {
         helper.cleanupTable("bst");
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
index 8e30784..4942118 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -24,6 +24,7 @@ import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
 import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.tag.Tag;
@@ -242,4 +243,10 @@ public class MockAccount implements Account
     public DateTime getUpdatedDate() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public MutableAccountData toMutableAccountData() {
+        throw new UnsupportedOperationException();
+    }
+
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
index 2e318f3..85ec378 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
@@ -19,6 +19,8 @@ package com.ning.billing.analytics;
 import java.util.List;
 import java.util.UUID;
 
+import org.apache.commons.lang.NotImplementedException;
+
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
@@ -91,4 +93,10 @@ public class MockIAccountUserApi implements AccountUserApi
 			throws AccountApiException {
 		throw new UnsupportedOperationException();
 	}
+
+    @Override
+    public void updateAccount(UUID accountId, AccountData accountData, CallContext context)
+            throws AccountApiException {
+        throw new NotImplementedException();
+    }
 }

api/pom.xml 1(+0 -1)

diff --git a/api/pom.xml b/api/pom.xml
index de14404..ac7f6c9 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -58,7 +58,6 @@
             <groupId>commons-lang</groupId>
             <artifactId>commons-lang</artifactId>
         </dependency>
-
     </dependencies>
     <build>
     </build>
diff --git a/api/src/main/java/com/ning/billing/account/api/Account.java b/api/src/main/java/com/ning/billing/account/api/Account.java
index 3ffcf94..3f1e383 100644
--- a/api/src/main/java/com/ning/billing/account/api/Account.java
+++ b/api/src/main/java/com/ning/billing/account/api/Account.java
@@ -23,4 +23,6 @@ import com.ning.billing.util.tag.Taggable;
 
 public interface Account extends AccountData, Customizable, UpdatableEntity, Taggable {
     public static String ObjectType = "account";
+    
+    public MutableAccountData toMutableAccountData();    
 }
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 b6cfd23..2ab04dc 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
@@ -42,6 +42,8 @@ public interface AccountUserApi {
 
     public void updateAccount(String key, AccountData accountData, CallContext context) throws AccountApiException;
 
+    public void updateAccount(UUID accountId, AccountData accountData, CallContext context) throws AccountApiException;
+
     public Account getAccountByKey(String key);
 
     public Account getAccountById(UUID accountId);
diff --git a/api/src/main/java/com/ning/billing/account/api/MutableAccountData.java b/api/src/main/java/com/ning/billing/account/api/MutableAccountData.java
new file mode 100644
index 0000000..2909b2d
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/account/api/MutableAccountData.java
@@ -0,0 +1,197 @@
+/*
+ * 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.account.api;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.tag.TagStore;
+
+public class MutableAccountData implements AccountData {
+    private String externalKey;
+    private String email;
+    private String name;
+    private int firstNameLength;
+    private Currency currency;
+    private int billCycleDay;
+    private String paymentProviderName;
+    private DateTimeZone timeZone;
+    private String locale;
+    private String address1;
+    private String address2;
+    private String companyName;
+    private String city;
+    private String stateOrProvince;
+    private String country;
+    private String postalCode;
+    private String phone;
+    
+    public MutableAccountData(String externalKey, String email, String name,
+            int firstNameLength, Currency currency, int billCycleDay,
+            String paymentProviderName, TagStore tags, DateTimeZone timeZone,
+            String locale, String address1, String address2,
+            String companyName, String city, String stateOrProvince,
+            String country, String postalCode, String phone,
+            DateTime createdDate, DateTime updatedDate) {
+        super();
+        this.externalKey = externalKey;
+        this.email = email;
+        this.name = name;
+        this.firstNameLength = firstNameLength;
+        this.currency = currency;
+        this.billCycleDay = billCycleDay;
+        this.paymentProviderName = paymentProviderName;
+        this.timeZone = timeZone;
+        this.locale = locale;
+        this.address1 = address1;
+        this.address2 = address2;
+        this.companyName = companyName;
+        this.city = city;
+        this.stateOrProvince = stateOrProvince;
+        this.country = country;
+        this.postalCode = postalCode;
+        this.phone = phone;
+    }
+    
+    public MutableAccountData(AccountData accountData) {
+        super();
+        this.externalKey = accountData.getExternalKey();
+        this.email = accountData.getEmail();
+        this.name = accountData.getName();
+        this.firstNameLength = accountData.getFirstNameLength();
+        this.currency = accountData.getCurrency();
+        this.billCycleDay = accountData.getBillCycleDay();
+        this.paymentProviderName = accountData.getPaymentProviderName();
+        this.timeZone = accountData.getTimeZone();
+        this.locale = accountData.getLocale();
+        this.address1 = accountData.getAddress1();
+        this.address2 = accountData.getAddress2();
+        this.companyName = accountData.getCompanyName();
+        this.city = accountData.getCity();
+        this.stateOrProvince = accountData.getStateOrProvince();
+        this.country = accountData.getCountry();
+        this.postalCode = accountData.getPostalCode();
+        this.phone = accountData.getPhone();
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+    public String getEmail() {
+        return email;
+    }
+    public String getName() {
+        return name;
+    }
+    public int getFirstNameLength() {
+        return firstNameLength;
+    }
+    public Currency getCurrency() {
+        return currency;
+    }
+    public int getBillCycleDay() {
+        return billCycleDay;
+    }
+    public String getPaymentProviderName() {
+        return paymentProviderName;
+    }
+    public DateTimeZone getTimeZone() {
+        return timeZone;
+    }
+    public String getLocale() {
+        return locale;
+    }
+    public String getAddress1() {
+        return address1;
+    }
+    public String getAddress2() {
+        return address2;
+    }
+    public String getCompanyName() {
+        return companyName;
+    }
+    public String getCity() {
+        return city;
+    }
+    public String getStateOrProvince() {
+        return stateOrProvince;
+    }
+    public String getCountry() {
+        return country;
+    }
+    public String getPostalCode() {
+        return postalCode;
+    }
+    public String getPhone() {
+        return phone;
+    }
+    
+    public void setExternalKey(String externalKey) {
+        this.externalKey = externalKey;
+    }
+    public void setEmail(String email) {
+        this.email = email;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setFirstNameLength(int firstNameLength) {
+        this.firstNameLength = firstNameLength;
+    }
+    public void setCurrency(Currency currency) {
+        this.currency = currency;
+    }
+    public void setBillCycleDay(int billCycleDay) {
+        this.billCycleDay = billCycleDay;
+    }
+    public void setPaymentProviderName(String paymentProviderName) {
+        this.paymentProviderName = paymentProviderName;
+    }
+    public void setTimeZone(DateTimeZone timeZone) {
+        this.timeZone = timeZone;
+    }
+    public void setLocale(String locale) {
+        this.locale = locale;
+    }
+    public void setAddress1(String address1) {
+        this.address1 = address1;
+    }
+    public void setAddress2(String address2) {
+        this.address2 = address2;
+    }
+    public void setCompanyName(String companyName) {
+        this.companyName = companyName;
+    }
+    public void setCity(String city) {
+        this.city = city;
+    }
+    public void setStateOrProvince(String stateOrProvince) {
+        this.stateOrProvince = stateOrProvince;
+    }
+    public void setCountry(String country) {
+        this.country = country;
+    }
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+
+}
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 7423d0c..57ea8d9 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -131,6 +131,8 @@ public enum ErrorCode {
     TAG_DEFINITION_ALREADY_EXISTS(3901, "The tag definition name already exists (name: %s)"),
     TAG_DEFINITION_DOES_NOT_EXIST(3902, "The tag definition name does not exist (name: %s)"),
     TAG_DEFINITION_IN_USE(3903, "The tag definition name is currently in use (name: %s)"),
+    
+    CONTROL_TAG_DOES_NOT_EXIST(3904, "The control tag does not exist (name: %s)"),
 
    /*
     *
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 57c76a0..3b593fd 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
@@ -53,7 +53,7 @@ public interface PaymentApi {
 
     List<PaymentInfo> getPaymentInfo(List<String> invoiceIds);
 
-    PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId);
+    List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId);
 
     PaymentInfo getPaymentInfoForPaymentAttemptId(String paymentAttemptId);
 
diff --git a/api/src/main/java/com/ning/billing/util/api/TagDefinitionApiException.java b/api/src/main/java/com/ning/billing/util/api/TagDefinitionApiException.java
index 81750cb..a67f1ad 100644
--- a/api/src/main/java/com/ning/billing/util/api/TagDefinitionApiException.java
+++ b/api/src/main/java/com/ning/billing/util/api/TagDefinitionApiException.java
@@ -20,6 +20,8 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class TagDefinitionApiException extends BillingExceptionBase {
+    private static final long serialVersionUID = 1L;
+
     public TagDefinitionApiException(Throwable cause, int code, final String msg) {
         super(cause, code, msg);
     }
diff --git a/api/src/main/java/com/ning/billing/util/api/TagDefinitionService.java b/api/src/main/java/com/ning/billing/util/api/TagDefinitionService.java
index 1434f8f..37a1020 100644
--- a/api/src/main/java/com/ning/billing/util/api/TagDefinitionService.java
+++ b/api/src/main/java/com/ning/billing/util/api/TagDefinitionService.java
@@ -19,5 +19,5 @@ package com.ning.billing.util.api;
 import com.ning.billing.lifecycle.KillbillService;
 
 public interface TagDefinitionService extends KillbillService {
-    public TagDefinitionUserApi getTagDefinitionUserApi();
+    public TagUserApi getTagDefinitionUserApi();
 }

beatrix/pom.xml 25(+4 -21)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 032ae4a..28f478f 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -68,11 +68,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.ning.jdbi</groupId>
-            <artifactId>jdbi-metrics</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.jdbi</groupId>
             <artifactId>jdbi</artifactId>
             <scope>test</scope>
@@ -94,32 +89,20 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <scope>runtime</scope>
+            <artifactId>mysql-connector-mxj-db-files</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <groups>fast,slow, stress</groups>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <executions>
                     <execution>
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
index 1253bb4..304cb0b 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
@@ -23,6 +23,8 @@ import java.net.URL;
 import java.util.Set;
 
 import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.glue.TagStoreModule;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
@@ -84,6 +86,8 @@ public class MockModule extends AbstractModule {
         install(new GlobalLockerModule());
         install(new BusModule());
         install(new NotificationQueueModule());
+        install(new TagStoreModule());
+        install(new FieldStoreModule());
         install(new AccountModule());
         install(new CatalogModule());
         install(new EntitlementModule());
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 70c4598..1d81006 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
@@ -79,6 +79,7 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.bus.BusService;
 
+@Test(groups = "slow")
 @Guice(modules = {MockModule.class})
 public class TestIntegration {
     private static final int NUMBER_OF_DECIMALS = 4;
@@ -143,7 +144,7 @@ public class TestIntegration {
         helper.initDb(utilDdl);
     }
 
-    @BeforeSuite(alwaysRun = true)
+    @BeforeSuite(groups = "slow")
     public void setup() throws Exception{
 
         setupMySQL();
@@ -168,7 +169,7 @@ public class TestIntegration {
         accountUserApi = accountService.getAccountUserApi();
     }
 
-    @AfterSuite(alwaysRun = true)
+    @AfterSuite(groups = "slow")
     public void tearDown() throws Exception {
         lifecycle.fireShutdownSequencePriorEventUnRegistration();
         busService.getBus().unregister(busHandler);
@@ -177,7 +178,7 @@ public class TestIntegration {
     }
 
 
-    @BeforeMethod(alwaysRun = true)
+    @BeforeMethod(groups = "slow")
     public void setupTest() {
 
         log.warn("\n");
@@ -187,7 +188,7 @@ public class TestIntegration {
         cleanupData();
     }
 
-    @AfterMethod(alwaysRun = true)
+    @AfterMethod(groups = "slow")
     public void cleanupTest() {
         log.warn("DONE WITH TEST\n");
     }
@@ -280,7 +281,7 @@ public class TestIntegration {
         Thread.sleep(600000);
     }
 
-    @Test(groups = "stress", enabled = false)
+    @Test(groups = {"slow", "stress"}, enabled = false)
     public void stressTest() throws Exception {
         final int maxIterations = 7;
         for (int curIteration = 0; curIteration < maxIterations; curIteration++) {

catalog/pom.xml 2(+1 -1)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index bf0d550..dee138d 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -27,7 +27,7 @@
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-api</artifactId>
-        </dependency> 
+        </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
index fbc99df..fb61be7 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
@@ -49,7 +49,7 @@ public class TestVersionedCatalog {
 	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
 	private VersionedCatalog vc;
 	
-	@BeforeClass(groups={"setup"})
+	@BeforeClass(groups={"fast"})
 	public void setUp() throws ServiceException {
 		vc = loader.load(Resources.getResource("versionedCatalog").toString());
 	}

entitlement/pom.xml 59(+11 -48)

diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 5347c18..cccf568 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -25,10 +25,6 @@
             <artifactId>jdbi</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ning.jdbi</groupId>
-            <artifactId>jdbi-metrics</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
@@ -52,12 +48,7 @@
             <artifactId>killbill-catalog</artifactId>
             <scope>test</scope>
         </dependency>
-        <!-- Should be in test scope , but broken right now -->
-        <dependency>
-            <groupId>com.ning.billing</groupId>
-            <artifactId>killbill-account</artifactId>
-        </dependency>
-        <dependency>
+         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
             <type>test-jar</type>
@@ -72,16 +63,6 @@
             <artifactId>commons-io</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
-            <scope>test</scope>
-        </dependency>
         <!-- Same here, this is really debatable whether or not we should keep that here -->
         <dependency>
             <groupId>com.ning.billing</groupId>
@@ -89,12 +70,6 @@
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
-
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <scope>runtime</scope>
-        </dependency>
         <dependency>
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
@@ -133,18 +108,21 @@
             <artifactId>stringtemplate</artifactId>
             <scope>runtime</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>
     </dependencies>
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <groups>fast,slow</groups>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <executions>
                     <execution>
@@ -156,19 +134,4 @@
             </plugin>
         </plugins>
     </build>
-    <profiles>
-        <profile>
-            <id>test-stress</id>
-            <build>
-                <plugins>
-                    <plugin>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <groups>stress</groups>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
 </project>
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 5730399..b354348 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
@@ -194,7 +194,8 @@ public class MigrationPlanAligner {
 
     private boolean isSamePlan(PlanPhaseSpecifier plan0, PlanPhaseSpecifier plan1) {
         if (plan0.getPriceListName().equals(plan1.getPriceListName()) &&
-                plan0.getProductName().equals(plan1.getProductName())) {
+                plan0.getProductName().equals(plan1.getProductName()) &&
+                plan0.getBillingPeriod() == plan1.getBillingPeriod()) {
             return true;
         }
         return false;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
index 339645a..a00f11f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
@@ -38,11 +38,12 @@ 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.DefaultAccount;
+import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.catalog.api.BillingAlignment;
 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.Currency;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -162,29 +163,11 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
         } catch (CatalogApiException e) {
             log.error("Unexpected catalog error encountered when updating BCD",e);
         }
+        
+        MutableAccountData modifiedData = account.toMutableAccountData();
+        modifiedData.setBillCycleDay(result);
 
-
-        Account modifiedAccount = new DefaultAccount(
-                account.getId(),
-                account.getExternalKey(),
-                account.getEmail(),
-                account.getName(),
-                account.getFirstNameLength(),
-                account.getCurrency(),
-                result,
-                account.getPaymentProviderName(),
-                account.getTimeZone(),
-                account.getLocale(),
-                account.getAddress1(),
-                account.getAddress2(),
-                account.getCompanyName(),
-                account.getCity(),
-                account.getStateOrProvince(),
-                account.getCountry(),
-                account.getPostalCode(),
-                account.getPhone(),
-                null, null, null, null);
-        accountApi.updateAccount(modifiedAccount, context);
+        accountApi.updateAccount(account.getExternalKey(), modifiedData, context);
         return result;
     }
 
@@ -225,4 +208,6 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
             }
         }
     }
+    
+ 
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
index 704b765..6217d83 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
@@ -35,17 +35,12 @@ import com.ning.billing.entitlement.engine.core.Engine;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.EntitlementSqlDao;
 
-
-
 public class EntitlementModule extends AbstractModule {
-
-
     protected void installConfig() {
         final EntitlementConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EntitlementConfig.class);
         bind(EntitlementConfig.class).toInstance(config);
     }
 
-
     protected void installEntitlementDao() {
         bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index 3ebc064..6e583ed 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -27,6 +27,7 @@ import java.util.UUID;
 
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.glue.CallContextModule;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
@@ -78,16 +79,17 @@ public class TestDefaultEntitlementBillingApi {
 
 	private Clock clock;
 	private SubscriptionData subscription;
+    private CallContextFactory factory;
 	private DateTime subscriptionStartDate;
 
 	@BeforeSuite(alwaysRun=true)
 	public void setup() throws ServiceException {
 		TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
-        final Injector g = Guice.createInjector(Stage.PRODUCTION, new CatalogModule(), new ClockModule());
-
+        final Injector g = Guice.createInjector(Stage.PRODUCTION, new CatalogModule(), new ClockModule(), new CallContextModule());
 
         catalogService = g.getInstance(CatalogService.class);
         clock = g.getInstance(Clock.class);
+        factory = g.getInstance(CallContextFactory.class);
 
         ((DefaultCatalogService)catalogService).loadCatalog();
 	}
@@ -153,24 +155,13 @@ public class TestDefaultEntitlementBillingApi {
 				zeroId, oneId, twoId, EventType.API_USER, ApiEventType.CREATE, then, now, null, null, null, null, SubscriptionState.ACTIVE, nextPlan, nextPhase, nextPriceList, 1, true);
 		transitions.add(t);
 
-		AccountUserApi accountApi = new BrainDeadAccountUserApi(){
-
-			@Override
-			public Account getAccountById(UUID accountId) {
-				return new BrainDeadAccount(){
-                    @Override
-                    public int getBillCycleDay() {
-                        return 32;
-                    }
-
-                    @Override
-                    public Currency getCurrency() {
-                        return Currency.USD;
-                    }
-                };
-			}} ;
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao,accountApi,catalogService);
+        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl)account).addResult("getBillCycleDay", 32);
+        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl)accountApi).addResult("getAccountById", account);
+		       
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
@@ -211,24 +202,13 @@ public class TestDefaultEntitlementBillingApi {
 				zeroId, oneId, twoId, EventType.API_USER, ApiEventType.CREATE, then, now, null, null, null, null, SubscriptionState.ACTIVE, nextPlan, nextPhase, nextPriceList, 1, true);
 		transitions.add(t);
 
-		AccountUserApi accountApi = new BrainDeadAccountUserApi(){
-
-			@Override
-			public Account getAccountById(UUID accountId) {
-				return new BrainDeadAccount(){
-                    @Override
-				    public int getBillCycleDay() {
-					    return 32;
-				    }
-
-                    @Override
-                    public Currency getCurrency() {
-                        return Currency.USD;
-                    }
-                };
-			}} ;
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
+        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl)account).addResult("getBillCycleDay", 32);
+        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl)accountApi).addResult("getAccountById", account);
+
+        DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao,accountApi,catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
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 e0de602..6ea53bc 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
@@ -23,6 +23,7 @@ import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
+@Test(groups = "fast")
 public class TestMigrationMemory extends TestMigration {
     @Override
     protected Injector getInjector() {
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 c395fed..587ca46 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
@@ -23,6 +23,7 @@ import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+@Test(groups = "slow")
 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 31d8e8d..59121c9 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
@@ -116,7 +116,7 @@ public abstract class TestApiBase {
 
     protected abstract Injector getInjector();
 
-    @AfterClass(alwaysRun=true)
+    @AfterClass(alwaysRun = true)
     public void tearDown() {
         try {
             ((DefaultBusService) busService).stopBus();
@@ -129,7 +129,7 @@ public abstract class TestApiBase {
         //if(helper != null) { helper.stopMysql(); }
     }
 
-    @BeforeClass(alwaysRun=true)
+    @BeforeClass(alwaysRun = true)
     public void setup() {
 
         loadSystemPropertiesFromClasspath("/entitlement.properties");
@@ -183,7 +183,7 @@ public abstract class TestApiBase {
         migrationApi = entitlementService.getMigrationApi();
     }
 
-    @BeforeMethod(alwaysRun=true)
+    @BeforeMethod(alwaysRun = true)
     public void setupTest() {
 
         log.warn("RESET TEST FRAMEWORK\n\n");
@@ -204,7 +204,7 @@ public abstract class TestApiBase {
         ((Engine)entitlementService).start();
     }
 
-    @AfterMethod(alwaysRun=true)
+    @AfterMethod(alwaysRun = true)
     public void cleanupTest() {
         try {
             busService.getBus().unregister(testListener);
@@ -215,11 +215,6 @@ public abstract class TestApiBase {
         log.warn("DONE WITH TEST\n");
     }
 
-    @AfterMethod
-    public void am(ITestResult result) {
-      System.out.println("CURRENT METHOD NAME :" + result.getMethod().getMethodName());
-    }
-
     protected SubscriptionData createSubscription(final String productName, final BillingPeriod term, final String planSet) throws EntitlementUserApiException {
         return createSubscriptionWithBundle(bundle.getId(), productName, term, planSet);
     }
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 7fceab9..3fd8a7c 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
@@ -136,7 +136,7 @@ public class TestUserApiDemos extends TestApiBase {
             /* STEP 7.  MOVE TO NEXT PHASE */
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.addDeltaFromReality(currentPhase.getDuration());
-            assertTrue(testListener.isCompleted(3000));
+            assertTrue(testListener.isCompleted(5000));
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             currentPlan = subscription.getCurrentPlan();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
index 24d7bdd..acb1a2a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
@@ -16,8 +16,9 @@
 
 package com.ning.billing.entitlement.glue;
 
-import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.glue.CatalogModule;
+import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.util.clock.MockClockModule;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.CallContextModule;
@@ -29,7 +30,7 @@ public class MockEngineModule extends EntitlementModule {
         super.configure();
         install(new BusModule());
         install(new CatalogModule());
-        install(new AccountModuleWithMocks());
+        bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
         install(new MockClockModule());
         install(new CallContextModule());
     }
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 c452c3b..f774e58 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
@@ -23,6 +23,7 @@ import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.MockEntitlementDaoSql;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.glue.FieldStoreModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 
 import org.skife.config.ConfigurationObjectFactory;
@@ -53,6 +54,7 @@ public class MockEngineModuleSql extends MockEngineModule {
     protected void configure() {
         installDBI();
         install(new NotificationQueueModule());
+        install(new FieldStoreModule());
         super.configure();
     }
 }

invoice/pom.xml 36(+15 -21)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index 90a72e5..ccef93e 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -54,27 +54,19 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-account</artifactId>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -87,23 +79,25 @@
             <scope>runtime</scope>
         </dependency>
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</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>
     </dependencies>
     <build>
     </build>
diff --git a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
index f74a72f..fd15171 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
@@ -27,14 +27,15 @@ import com.ning.billing.invoice.notification.MockNextBillingDateNotifier;
 import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
 import com.ning.billing.invoice.notification.NextBillingDateNotifier;
 import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.glue.CallContextModule;
 import com.ning.billing.util.glue.FieldStoreModule;
 import com.ning.billing.util.glue.GlobalLockerModule;
 import com.ning.billing.util.glue.TagStoreModule;
 import org.skife.jdbi.v2.IDBI;
-import com.ning.billing.account.glue.AccountModule;
+
+import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.glue.EntitlementModule;
@@ -97,7 +98,8 @@ public class InvoiceModuleWithEmbeddedDb extends InvoiceModule {
         install(new TagStoreModule());
 
         installNotificationQueue();
-        install(new AccountModule());
+//      install(new AccountModule());
+        bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
         install(new CatalogModule());
         install(new EntitlementModule());
         install(new GlobalLockerModule());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
index 73f3b7b..fe4feb4 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
@@ -64,6 +64,6 @@ public class InvoiceModuleWithMocks extends InvoiceModule {
         super.configure();
 
         install(new FieldStoreModule());
-        install(new TagStoreModule());
+        //install(new TagStoreModule());
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
index a3d2e5f..99f12b4 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
@@ -24,13 +24,14 @@ import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
 import com.google.inject.AbstractModule;
-import com.ning.billing.account.glue.AccountModule;
+import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.glue.EntitlementModule;
 import com.ning.billing.invoice.glue.InvoiceModule;
+import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.BusModule;
@@ -56,13 +57,15 @@ public class MockModule extends AbstractModule {
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
             bind(DbiConfig.class).toInstance(config);
         } else {
-            final IDBI dbi = helper.getDBI();
+            final IDBI dbi = helper.getDBI(); 
             bind(IDBI.class).toInstance(dbi);
         }
 
         install(new GlobalLockerModule());
         install(new NotificationQueueModule());
-        install(new AccountModule());
+//        install(new AccountModule());
+        bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
+
         installEntitlementModule();
         install(new CatalogModule());
         install(new BusModule());
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 6e1e9b2..adc78b7 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
@@ -25,9 +25,7 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.account.api.user.DefaultAccountUserApi;
-import com.ning.billing.account.dao.AccountDao;
-import com.ning.billing.account.dao.AuditedAccountDao;
+import com.ning.billing.account.api.MockAccountUserApi;
 import com.ning.billing.entitlement.api.billing.DefaultEntitlementBillingApi;
 import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
 import com.ning.billing.invoice.InvoiceDispatcher;
@@ -37,8 +35,12 @@ import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
 import com.ning.billing.invoice.model.InvoiceGenerator;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
+import com.ning.billing.util.tag.dao.AuditedTagDao;
+import com.ning.billing.util.tag.dao.TagDao;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
@@ -109,7 +111,8 @@ public class TestNextBillingDateNotifier {
 
 	}
 
-	@BeforeClass(groups={"setup"})
+
+	@BeforeClass(groups={"slow"})
 	public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
 		//TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
         final Injector g = Guice.createInjector(Stage.PRODUCTION,  new AbstractModule() {
@@ -128,13 +131,14 @@ public class TestNextBillingDateNotifier {
                 bind(MysqlTestingHelper.class).toInstance(helper);
                 IDBI dbi = helper.getDBI();
                 bind(IDBI.class).toInstance(dbi);
+                bind(TagDao.class).to(AuditedTagDao.class).asEagerSingleton();
+                bind(CustomFieldDao.class).to(AuditedCustomFieldDao.class).asEagerSingleton();
                 bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
                 bind(GlobalLocker.class).to(MySqlGlobalLocker.class).asEagerSingleton();
                 bind(InvoiceGenerator.class).to(DefaultInvoiceGenerator.class).asEagerSingleton();
                 bind(InvoiceDao.class).to(DefaultInvoiceDao.class);
                 bind(NextBillingDatePoster.class).to(DefaultNextBillingDatePoster.class).asEagerSingleton();
-                bind(AccountDao.class).to(AuditedAccountDao.class).asEagerSingleton();
-                bind(AccountUserApi.class).to(DefaultAccountUserApi.class).asEagerSingleton();
+                bind(AccountUserApi.class).to(MockAccountUserApi.class).asEagerSingleton();
                 bind(EntitlementBillingApi.class).to(DefaultEntitlementBillingApi.class).asEagerSingleton();
 			}
         });
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 5342dd8..7008c90 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -66,6 +66,7 @@ import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+@Test(groups = "slow")
 @Guice(modules = {MockModule.class})
 public class TestInvoiceDispatcher {
 	private Logger log = LoggerFactory.getLogger(TestInvoiceDispatcher.class);
@@ -96,21 +97,17 @@ public class TestInvoiceDispatcher {
 
     private CallContext context;
 
-	@BeforeSuite(alwaysRun = true)
-	public void setup() throws IOException
-	{
-		final String accountDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
+    @BeforeSuite(groups = "slow")
+    public void setup() throws IOException
+    {
 		final String entitlementDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
 		final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
-		//        final String paymentDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
 		final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
 
 		helper.startMysql();
 
-		helper.initDb(accountDdl);
 		helper.initDb(entitlementDdl);
 		helper.initDb(invoiceDdl);
-		//        helper.initDb(paymentDdl);
 		helper.initDb(utilDdl);
 		notifier.initialize();
 		notifier.start();
@@ -129,16 +126,16 @@ public class TestInvoiceDispatcher {
 		} catch (Exception e) {
 			log.warn("Failed to tearDown test properly ", e);
 		}
-
-	}
-
-	@Test(groups={"fast"}, enabled=true)
-	public void testDryRunInvoice() throws InvoiceApiException {
-		UUID accountId = UUID.randomUUID();
-		UUID subscriptionId = UUID.randomUUID();
+    }
+	    
+    @Test(groups={"slow"}, enabled=true)
+    public void testDryRunInvoice() throws InvoiceApiException {
+        UUID accountId = UUID.randomUUID();
+        UUID subscriptionId = UUID.randomUUID();
 
 		AccountUserApi accountUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
 		Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+
 		((ZombieControl)accountUserApi).addResult("getAccountById", account);
 		((ZombieControl)account).addResult("getCurrency", Currency.USD);
 		((ZombieControl)account).addResult("getId", accountId);

payment/pom.xml 18(+9 -9)

diff --git a/payment/pom.xml b/payment/pom.xml
index 398a6cc..fc660f7 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -102,14 +102,14 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-             <groupId>com.mysql</groupId>
-             <artifactId>management</artifactId>
-             <scope>test</scope>
-         </dependency>
-         <dependency>
-             <groupId>com.mysql</groupId>
-             <artifactId>management-dbfiles</artifactId>
-             <scope>test</scope>
-         </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>
     </dependencies>
 </project>
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 63bc87e..e12d963 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
@@ -315,8 +315,8 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
-        return paymentDao.getPaymentAttemptForInvoiceId(invoiceId);
+    public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId) {
+        return paymentDao.getPaymentAttemptsForInvoiceId(invoiceId);
     }
 
     @Override
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
index 00cdb31..e090a94 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
@@ -44,8 +44,8 @@ public class DefaultPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
-        return sqlDao.getPaymentAttemptForInvoiceId(invoiceId);
+    public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId) {
+        return sqlDao.getPaymentAttemptsForInvoiceId(invoiceId);
     }
 
     @Override
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 2c9ee06..2184841 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
@@ -35,7 +35,7 @@ public interface PaymentDao {
 
     void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId);
 
-    PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId);
+    List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId);
 
     void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry);
 
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 7ca3727..8994109 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
@@ -61,7 +61,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
 
     @SqlQuery
     @Mapper(PaymentAttemptMapper.class)
-    PaymentAttempt getPaymentAttemptForInvoiceId(@Bind("invoice_id") String invoiceId);
+    List<PaymentAttempt> getPaymentAttemptsForInvoiceId(@Bind("invoice_id") String invoiceId);
 
     @SqlQuery
     @Mapper(PaymentAttemptMapper.class)
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 91eeb22..55c3efa 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
@@ -55,7 +55,7 @@ getPaymentAttemptsForInvoiceIds(invoiceIds) ::= <<
      WHERE invoice_id in (<invoiceIds>)
 >>
 
-getPaymentAttemptForInvoiceId() ::= <<
+getPaymentAttemptsForInvoiceId() ::= <<
     SELECT <paymentAttemptFields()>
       FROM payment_attempts
      WHERE invoice_id = :invoice_id
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 e2ec321..9225a60 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
@@ -26,7 +26,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.entity.EntityPersistenceException;
 import org.apache.commons.lang.RandomStringUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -44,6 +43,7 @@ import com.ning.billing.invoice.model.RecurringInvoiceItem;
 import com.ning.billing.payment.TestHelper;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.entity.EntityPersistenceException;
 
 public abstract class TestPaymentApi {
     @Inject
@@ -118,8 +118,8 @@ public abstract class TestPaymentApi {
         assertEquals(paymentInfo.getPaymentMethodId(), paymentInfoFromGet.getPaymentMethodId());
         assertEquals(paymentInfo.getEffectiveDate(), paymentInfoFromGet.getEffectiveDate());
 
-        PaymentAttempt paymentAttemptFromGet = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
-        assertEquals(paymentAttempt, paymentAttemptFromGet);
+        List<PaymentAttempt> paymentAttemptsFromGet = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
+        assertEquals(paymentAttempt, paymentAttemptsFromGet.get(0));
 
     }
 
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 b4bfb51..c1ba1db 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
@@ -17,11 +17,13 @@
 package com.ning.billing.payment.dao;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
@@ -74,13 +76,14 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
-        for (PaymentAttempt paymentAttempt : paymentAttempts.values()) {
-            if (invoiceId.equals(paymentAttempt.getInvoiceId().toString())) {
-                return paymentAttempt;
-            }
-        }
-        return null;
+    public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(final String invoiceId) {
+        Collection<PaymentAttempt> attempts =  Collections2.filter(paymentAttempts.values(), new Predicate<PaymentAttempt>() {
+                @Override
+                public boolean apply(PaymentAttempt input) {
+                    return invoiceId.equals(input.getInvoiceId().toString());
+                }
+            });
+        return new ArrayList<PaymentAttempt>(attempts);
     }
 
     @Override
@@ -118,9 +121,9 @@ public class MockPaymentDao implements PaymentDao {
     public List<PaymentAttempt> getPaymentAttemptsForInvoiceIds(List<String> invoiceIds) {
         List<PaymentAttempt> paymentAttempts = new ArrayList<PaymentAttempt>(invoiceIds.size());
         for (String invoiceId : invoiceIds) {
-            PaymentAttempt attempt = getPaymentAttemptForInvoiceId(invoiceId);
-            if (attempt != null) {
-                paymentAttempts.add(attempt);
+            List<PaymentAttempt> attempts = getPaymentAttemptsForInvoiceId(invoiceId);
+            if (CollectionUtils.isNotEmpty(attempts)) {
+                paymentAttempts.addAll(attempts);
             }
         }
         return paymentAttempts;
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 70708eb..a97786d 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
@@ -18,6 +18,7 @@ package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
 import java.util.Arrays;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -103,9 +104,9 @@ public abstract class TestPaymentDao {
 
         PaymentAttempt attempt = paymentDao.createPaymentAttempt(originalPaymenAttempt);
 
-        PaymentAttempt attempt2 = paymentDao.getPaymentAttemptForInvoiceId(invoiceId.toString());
+        List<PaymentAttempt> attemptsFromGet = paymentDao.getPaymentAttemptsForInvoiceId(invoiceId.toString());
 
-        Assert.assertEquals(attempt, attempt2);
+        Assert.assertEquals(attempt, attemptsFromGet.get(0));
 
         PaymentAttempt attempt3 = paymentDao.getPaymentAttemptsForInvoiceIds(Arrays.asList(invoiceId.toString())).get(0);
 
diff --git a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
index 9231263..8b71c10 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
@@ -26,6 +26,7 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.concurrent.Callable;
 
+import com.ning.billing.account.glue.AccountModuleWithMocks;
 import com.ning.billing.util.glue.CallContextModule;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
@@ -100,7 +101,7 @@ public class TestPaymentInvoiceIntegration {
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws EventBusException {
         Injector injector = Guice.createInjector(new PaymentTestModuleWithEmbeddedDb(),
-                                                 new AccountModule(),
+                                                 new AccountModuleWithMocks(),
                                                  new InvoiceModuleWithMocks(),
                                                  new CallContextModule(),
                                                  new MockClockModule(),
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 9c319ec..f8278f8 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -25,8 +25,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.ClockMock;
 import org.joda.time.DateTime;
 import org.joda.time.Days;
 import org.testng.annotations.AfterMethod;
@@ -54,6 +52,8 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.payment.setup.PaymentConfig;
 import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
 import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.notificationq.MockNotificationQueue;
 import com.ning.billing.util.notificationq.Notification;
 import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -135,12 +135,12 @@ public class TestRetryService {
         assertEquals(pendingNotifications.size(), 1);
 
         Notification notification = pendingNotifications.get(0);
-        PaymentAttempt paymentAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
+        List<PaymentAttempt> paymentAttempts = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
 
-        assertNotNull(paymentAttempt);
-        assertEquals(notification.getNotificationKey(), paymentAttempt.getPaymentAttemptId().toString());
+        assertNotNull(paymentAttempts);
+        assertEquals(notification.getNotificationKey(), paymentAttempts.get(0).getPaymentAttemptId().toString());
 
-        DateTime expectedRetryDate = paymentAttempt.getPaymentAttemptDate().plusDays(paymentConfig.getPaymentRetryDays().get(0));
+        DateTime expectedRetryDate = paymentAttempts.get(0).getPaymentAttemptDate().plusDays(paymentConfig.getPaymentRetryDays().get(0));
 
         assertEquals(notification.getEffectiveDate(), expectedRetryDate);
     }
@@ -185,8 +185,8 @@ public class TestRetryService {
         PaymentInfo paymentInfo = paymentInfoList.get(0);
         assertEquals(paymentInfo.getStatus(), PaymentStatus.Processed.toString());
 
-        PaymentAttempt updatedAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
-        assertEquals(paymentInfo.getPaymentId(), updatedAttempt.getPaymentId());
+        List<PaymentAttempt> updatedAttempts = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
+        assertEquals(paymentInfo.getPaymentId(), updatedAttempts.get(0).getPaymentId());
 
     }
 }

pom.xml 73(+52 -21)

diff --git a/pom.xml b/pom.xml
index 9a6662e..c0c46a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,7 @@
                 <artifactId>killbill-api</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -71,6 +72,7 @@
                 <artifactId>killbill-account</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -82,6 +84,7 @@
                 <artifactId>killbill-entitlement</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -93,6 +96,7 @@
                 <artifactId>killbill-payment</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -104,6 +108,7 @@
                 <artifactId>killbill-catalog</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -115,6 +120,7 @@
                 <artifactId>killbill-invoice</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
@@ -126,6 +132,7 @@
                 <artifactId>killbill-util</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
+                <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>org.codehaus.jackson</groupId>
@@ -177,33 +184,18 @@
                 <version>1.2.0</version>
             </dependency>
             <dependency>
-                <groupId>com.mysql</groupId>
-                <artifactId>management</artifactId>
-                <version>5.0.11</version>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-mxj</artifactId>
+                <version>5.0.12</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
-                <groupId>com.mysql</groupId>
-                <artifactId>management-dbfiles</artifactId>
-                <version>5.0.11</version>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-mxj-db-files</artifactId>
+                <version>5.0.12</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
-                <groupId>com.yammer.metrics</groupId>
-                <artifactId>metrics-core</artifactId>
-                <version>2.0.0-BETA17</version>
-            </dependency>
-            <dependency>
-                <groupId>com.yammer.metrics</groupId>
-                <artifactId>metrics-guice</artifactId>
-                <version>2.0.0-BETA17</version>
-            </dependency>
-            <dependency>
-                <groupId>com.ning.jdbi</groupId>
-                <artifactId>jdbi-metrics</artifactId>
-                <version>1.0.1</version>
-            </dependency>
-            <dependency>
                 <groupId>commons-io</groupId>
                 <artifactId>commons-io</artifactId>
                 <version>2.0.1</version>
@@ -403,6 +395,7 @@
                                 <exclude>**/*.dont-let-git-remove-this-directory</exclude>
                                 <exclude>**/test-output/**</exclude>
                                 <exclude>**/bin/**</exclude>
+                                <exclude>.travis.yml</exclude>
                             </excludes>
                         </configuration>
                     </execution>
@@ -440,6 +433,7 @@
                 <version>2.11</version>
                 <configuration>
                     <useManifestOnlyJar>false</useManifestOnlyJar>
+                    <groups>fast,slow</groups>
                     <systemPropertyVariables>
                         <log4j.configuration>file:${project.basedir}/src/test/resources/log4j.xml</log4j.configuration>
                     </systemPropertyVariables>
@@ -480,11 +474,14 @@
                         <artifactId>maven-surefire-plugin</artifactId>
                         <version>2.11</version>
                         <configuration>
+                            <groups>fast,slow</groups>
                             <useManifestOnlyJar>false</useManifestOnlyJar>
                             <systemPropertyVariables>
                                 <log4j.configuration>file:${project.basedir}/src/test/resources/log4j.xml</log4j.configuration>
                                 <com.ning.billing.dbi.test.useLocalDb>true</com.ning.billing.dbi.test.useLocalDb>
                                 <com.ning.billing.dbi.jdbc.url>jdbc:mysql://127.0.0.1:3306/test_killbill</com.ning.billing.dbi.jdbc.url>
+                                <file.encoding>UTF-8</file.encoding>
+                                <user.timezone>GMT</user.timezone>
                             </systemPropertyVariables>
                         </configuration>
                     </plugin>
@@ -492,6 +489,40 @@
             </build>
         </profile>
         <profile>
+            <id>travis</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <version>2.11</version>
+                        <configuration>
+                            <groups>fast</groups>
+                            <systemPropertyVariables>
+                                <file.encoding>UTF-8</file.encoding>
+                                <user.timezone>GMT</user.timezone>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>test-stress</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <version>2.11</version>
+                        <configuration>
+                            <groups>stress</groups>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
             <id>sonatype-oss-release</id>
             <build>
                 <plugins>

util/pom.xml 42(+17 -25)

diff --git a/util/pom.xml b/util/pom.xml
index 10cb192..dc5c251 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -8,7 +8,8 @@
     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">
+<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>
@@ -33,44 +34,35 @@
             <artifactId>jdbi</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.skife.config</groupId>
-            <artifactId>config-magic</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>joda-time</groupId>
-            <artifactId>joda-time</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.ning.jdbi</groupId>
-            <artifactId>jdbi-metrics</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
+            <artifactId>mysql-connector-mxj-db-files</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
-            <scope>runtime</scope>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <scope>test</scope>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <scope>test</scope>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
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 a1c746e..47e5412 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
@@ -17,12 +17,14 @@
 package com.ning.billing.util.glue;
 
 import com.google.inject.AbstractModule;
-import com.ning.billing.util.api.TagDefinitionUserApi;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.tag.api.DefaultTagDefinitionUserApi;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 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.ning.billing.util.tag.dao.TagDefinitionSqlDao;
+
 public class TagStoreModule extends AbstractModule
 {
     protected void installDaos() {
@@ -34,6 +36,6 @@ public class TagStoreModule extends AbstractModule
     protected void configure()
     {
         installDaos();
-        bind(TagDefinitionUserApi.class).to(DefaultTagDefinitionUserApi.class).asEagerSingleton();
+        bind(TagUserApi.class).to(DefaultTagDefinitionUserApi.class).asEagerSingleton();
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionService.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionService.java
index 0e1f99e..d24ac9a 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionService.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionService.java
@@ -18,19 +18,19 @@ package com.ning.billing.util.tag.api;
 
 import com.google.inject.Inject;
 import com.ning.billing.util.api.TagDefinitionService;
-import com.ning.billing.util.api.TagDefinitionUserApi;
+import com.ning.billing.util.api.TagUserApi;
 
 public class DefaultTagDefinitionService implements TagDefinitionService {
     private static final String TAG_DEFINITION_SERVICE_NAME = "tag-service";
-    private final TagDefinitionUserApi api;
+    private final TagUserApi api;
 
     @Inject
-    public DefaultTagDefinitionService(final TagDefinitionUserApi api) {
+    public DefaultTagDefinitionService(final TagUserApi api) {
         this.api = api;
     }
 
     @Override
-    public TagDefinitionUserApi getTagDefinitionUserApi() {
+    public TagUserApi getTagDefinitionUserApi() {
         return api;
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
index 0337619..53d8841 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
@@ -17,14 +17,22 @@
 package com.ning.billing.util.tag.api;
 
 import java.util.List;
+
+import org.joda.time.DateTime;
+
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.api.TagDefinitionUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.DefaultControlTag;
+import com.ning.billing.util.tag.DescriptiveTag;
+import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
-public class DefaultTagDefinitionUserApi implements TagDefinitionUserApi {
+public class DefaultTagDefinitionUserApi implements TagUserApi {
     private TagDefinitionDao dao;
 
     @Inject
@@ -58,4 +66,26 @@ public class DefaultTagDefinitionUserApi implements TagDefinitionUserApi {
 			throws TagDefinitionApiException {
 		return dao.getByName(name);
 	}
+
+    @Override
+    public Tag createControlTag(String controlTagName) throws TagDefinitionApiException {
+        ControlTagType type = null;
+        for(ControlTagType t : ControlTagType.values()) {
+            if(t.toString().equals(controlTagName)) {
+                type = t;
+            }
+        }
+        
+        if(type == null) {
+            throw new TagDefinitionApiException(ErrorCode.CONTROL_TAG_DOES_NOT_EXIST, controlTagName);
+        }
+        return new DefaultControlTag(type);
+    }
+
+    @Override
+    public Tag createDescriptiveTag(String tagDefinitionName) throws TagDefinitionApiException {
+        TagDefinition tagDefinition = getTagDefinition(tagDefinitionName);
+        
+        return new DescriptiveTag(tagDefinition);
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
index 68566d2..1f22d5d 100644
--- a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
+++ b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
@@ -20,10 +20,6 @@ import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.jolbox.bonecp.BoneCPConfig;
 import com.jolbox.bonecp.BoneCPDataSource;
-import com.ning.jdbi.metrics.JdbiGroupStrategy;
-import com.ning.jdbi.metrics.MetricsTimingCollector;
-import com.ning.jdbi.metrics.SqlJdbiGroupStrategy;
-import com.yammer.metrics.core.MetricsRegistry;
 import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.TimingCollector;
@@ -34,13 +30,11 @@ import java.util.concurrent.TimeUnit;
 
 public class DBIProvider implements Provider<IDBI>
 {
-    private final MetricsRegistry metricsRegistry;
     private final DbiConfig config;
 
     @Inject
-    public DBIProvider(final MetricsRegistry metricsRegistry, final DbiConfig config)
+    public DBIProvider(final DbiConfig config)
     {
-        this.metricsRegistry = metricsRegistry;
         this.config = config;
     }
 
@@ -64,10 +58,6 @@ public class DBIProvider implements Provider<IDBI>
         final SQLLog log = new Log4JLog();
         dbi.setSQLLog(log);
 
-        final JdbiGroupStrategy jdbiGroupStrategy = new SqlJdbiGroupStrategy();
-        final TimingCollector timingCollector = new MetricsTimingCollector(metricsRegistry, jdbiGroupStrategy, TimeUnit.MILLISECONDS, TimeUnit.SECONDS);
-        dbi.setTimingCollector(timingCollector);
-
         return dbi;
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java b/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
index 85849c5..2310f1c 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
@@ -31,13 +31,13 @@ public class TestEventBus {
     private Bus eventBus;
 
 
-    @BeforeClass
+    @BeforeClass(groups = "slow")
     public void setup() {
         eventBus = new InMemoryBus();
         eventBus.start();
     }
 
-    @AfterClass
+    @AfterClass(groups = "slow")
     public void tearDown() {
         eventBus.stop();
     }
@@ -97,7 +97,7 @@ public class TestEventBus {
         }
     }
 
-    @Test
+    @Test(groups = "slow")
     public void testSimple() {
         try {
 
@@ -116,7 +116,7 @@ public class TestEventBus {
         }
     }
 
-    @Test
+    @Test(groups = "slow")
     public void testDifferentType() {
         try {
 
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 568c974..8a2385b 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
@@ -44,7 +44,7 @@ import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
-@Test(groups={"util"})
+@Test(groups = {"util", "slow"})
 public class TestFieldStore {
     Logger log = LoggerFactory.getLogger(TestFieldStore.class);
     private final MysqlTestingHelper helper = new MysqlTestingHelper();
@@ -52,7 +52,7 @@ public class TestFieldStore {
     private IDBI dbi;
     private CustomFieldDao customFieldDao;
 
-    @BeforeClass(alwaysRun = true)
+    @BeforeClass(groups = {"util", "slow"})
     protected void setup() throws IOException {
         // Health check test to make sure MySQL is setup properly
         try {
@@ -76,7 +76,7 @@ public class TestFieldStore {
         }
     }
 
-    @AfterClass(alwaysRun = true)
+    @AfterClass(groups = {"util", "slow"})
     public void stopMysql()
     {
         helper.stopMysql();
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 9f60162..6f2facd 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
@@ -39,6 +39,7 @@ import com.ning.billing.util.globallocker.LockFailedException;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
 import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
 
+@Test(groups = "slow")
 @Guice(modules=TestMysqlGlobalLocker.TestMysqlGlobalLockerModule.class)
 public class TestMysqlGlobalLocker {
 
@@ -48,14 +49,14 @@ public class TestMysqlGlobalLocker {
     @Inject
     private MysqlTestingHelper helper;
 
-    @BeforeClass(alwaysRun=true)
+    @BeforeClass(groups = "slow")
     public void setup() throws IOException  {
         final String testDdl = IOUtils.toString(TestMysqlGlobalLocker.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
         helper.startMysql();
         helper.initDb(testDdl);
     }
 
-    @AfterClass(alwaysRun=true)
+    @AfterClass(groups = "slow")
     public void tearDown() {
         helper.stopMysql();
     }
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 4c812cb..891cadf 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
@@ -45,6 +45,7 @@ import com.ning.billing.util.notificationq.dao.NotificationSqlDao.NotificationSq
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
+@Test(groups = "slow")
 @Guice(modules = TestNotificationSqlDao.TestNotificationSqlDaoModule.class)
 public class TestNotificationSqlDao {
 
@@ -64,7 +65,7 @@ public class TestNotificationSqlDao {
         helper.initDb(ddl);
     }
 
-    @BeforeSuite(alwaysRun = true)
+    @BeforeSuite(groups = "slow")
     public void setup()  {
         try {
             startMysql();
@@ -74,14 +75,14 @@ public class TestNotificationSqlDao {
         }
     }
 
-    @AfterSuite(alwaysRun = true)
+    @AfterSuite(groups = "slow")
     public void stopMysql()
     {
         helper.stopMysql();
     }
 
 
-    @BeforeTest
+    @BeforeTest(groups = "slow")
     public void cleanupDb() {
         dbi.withHandle(new HandleCallback<Void>() {
 
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 9c12792..fefbcdb 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
@@ -56,120 +56,122 @@ import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 
+@Test(groups = "slow")
 @Guice(modules = TestNotificationQueue.TestNotificationQueueModule.class)
 public class TestNotificationQueue {
-	Logger log = LoggerFactory.getLogger(TestNotificationQueue.class);
+    Logger log = LoggerFactory.getLogger(TestNotificationQueue.class);
     @Inject
     private IDBI dbi;
 
-	@Inject
-	MysqlTestingHelper helper;
+    @Inject
+    MysqlTestingHelper helper;
 
-	@Inject
-	private Clock clock;
+    @Inject
+    private Clock clock;
 
-	private DummySqlTest dao;
+    private DummySqlTest dao;
 
-	private int eventsReceived;
+    private int eventsReceived;
 
-	// private NotificationQueue queue;
+    // private NotificationQueue queue;
 
-	private void startMysql() throws IOException, ClassNotFoundException, SQLException {
-		final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
-		final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
-		helper.startMysql();
-		helper.initDb(ddl);
-		helper.initDb(testDdl);
-	}
+    private void startMysql() throws IOException, ClassNotFoundException, SQLException {
+        final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+        final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
+        helper.startMysql();
+        helper.initDb(ddl);
+        helper.initDb(testDdl);
+    }
 
-	@BeforeSuite(alwaysRun = true)
-	public void setup() throws Exception {
-		startMysql();
-		dao = dbi.onDemand(DummySqlTest.class);
-	}
-	
-    @AfterClass(alwaysRun = true)
+    @BeforeSuite(groups="slow")
+    public void setup() throws Exception {
+        startMysql();
+        dao = dbi.onDemand(DummySqlTest.class);
+    }
+
+    @AfterClass(groups="slow")
     public void tearDown() {
+        helper.stopMysql();
+    }
+
+    @BeforeTest(groups="slow")
+    public void beforeTest() {
+        dbi.withHandle(new HandleCallback<Void>() {
 
-    	helper.stopMysql();
+            @Override
+            public Void withHandle(Handle handle) throws Exception {
+                handle.execute("delete from notifications");
+                handle.execute("delete from claimed_notifications");
+                handle.execute("delete from dummy");
+                return null;
+            }
+        });
+        // Reset time to real value
+        ((ClockMock) clock).resetDeltaFromReality();
     }
 
-	@BeforeTest
-	public void beforeTest() {
-		dbi.withHandle(new HandleCallback<Void>() {
 
-			@Override
-			public Void withHandle(Handle handle) throws Exception {
-				handle.execute("delete from notifications");
-				handle.execute("delete from claimed_notifications");
-				handle.execute("delete from dummy");
-				return null;
-			}
-		});
-		// Reset time to real value
-		((ClockMock) clock).resetDeltaFromReality();
-	}
 
-	/**
-	 * Test that we can post a notification in the future from a transaction and get the notification
-	 * callback with the correct key when the time is ready
-	 * @throws Exception
-	 */
-	@Test(groups={"fast"}, enabled = true)
-	public void testSimpleNotification() throws Exception {
-
-		final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
-
-		final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "foo",
-				new NotificationQueueHandler() {
-			@Override
-			public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
-				synchronized (expectedNotifications) {
-	            	log.info("Handler received key: " + notificationKey);
-
-					expectedNotifications.put(notificationKey.toString(), Boolean.TRUE);
-					expectedNotifications.notify();
-				}
-			}
-		},
-		getNotificationConfig(false, 100, 1, 10000));
+    /**
+     * Test that we can post a notification in the future from a transaction and get the notification
+     * callback with the correct key when the time is ready
+     * @throws Exception
+     */
+    @Test(groups={"slow"}, enabled = true)
+    public void testSimpleNotification() throws Exception {
 
+        final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
 
-		queue.startQueue();
+        final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "foo",
+                new NotificationQueueHandler() {
+            @Override
+            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+                synchronized (expectedNotifications) {
+                    log.info("Handler received key: " + notificationKey);
 
-		final UUID key = UUID.randomUUID();
-		final DummyObject obj = new DummyObject("foo", key);
-		final DateTime now = new DateTime();
-		final DateTime readyTime = now.plusMillis(2000);
-		final NotificationKey notificationKey = new NotificationKey() {
-			@Override
-			public String toString() {
-				return key.toString();
-			}
-		};
-		expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+                    expectedNotifications.put(notificationKey.toString(), Boolean.TRUE);
+                    expectedNotifications.notify();
+                }
+            }
+        },
+        getNotificationConfig(false, 100, 1, 10000));
 
 
-		// Insert dummy to be processed in 2 sec'
-		dao.inTransaction(new Transaction<Void, DummySqlTest>() {
-			@Override
-			public Void inTransaction(DummySqlTest transactional,
-					TransactionStatus status) throws Exception {
+        queue.startQueue();
 
-				transactional.insertDummy(obj);
-				queue.recordFutureNotificationFromTransaction(transactional,
-						readyTime, notificationKey);
-            	log.info("Posted key: " + notificationKey);
+        final UUID key = UUID.randomUUID();
+        final DummyObject obj = new DummyObject("foo", key);
+        final DateTime now = new DateTime();
+        final DateTime readyTime = now.plusMillis(2000);
+        final NotificationKey notificationKey = new NotificationKey() {
+            @Override
+            public String toString() {
+                return key.toString();
+            }
+        };
+        expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
 
-				return null;
-			}
-		});
 
-		// Move time in the future after the notification effectiveDate
-		((ClockMock) clock).setDeltaFromReality(3000);
+        // Insert dummy to be processed in 2 sec'
+        dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+            @Override
+            public Void inTransaction(DummySqlTest transactional,
+                    TransactionStatus status) throws Exception {
+
+                transactional.insertDummy(obj);
+                queue.recordFutureNotificationFromTransaction(transactional,
+                        readyTime, notificationKey);
+                log.info("Posted key: " + notificationKey);
 
-		// Notification should have kicked but give it at least a sec' for thread scheduling
-	    await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+                return null;
+            }
+        });
+
+        // Move time in the future after the notification effectiveDate
+        ((ClockMock) clock).setDeltaFromReality(3000);
+
+        // Notification should have kicked but give it at least a sec' for thread scheduling
+        await().atMost(1, MINUTES).until(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
                 return expectedNotifications.get(notificationKey.toString());
@@ -180,75 +182,75 @@ public class TestNotificationQueue {
 	    Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
 	}
 
-	@Test(groups={"fast"}, enabled = true)
-	public void testManyNotifications() throws InterruptedException {
-		final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
-
-		final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
-				new NotificationQueueHandler() {
-			@Override
-			public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
-				synchronized (expectedNotifications) {
-					expectedNotifications.put(notificationKey, Boolean.TRUE);
-					expectedNotifications.notify();
-				}
-			}
-		},
-		getNotificationConfig(false, 100, 10, 10000));
+    @Test(groups="slow")
+    public void testManyNotifications() throws InterruptedException {
+        final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
 
+        final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
+                new NotificationQueueHandler() {
+            @Override
+            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+                synchronized (expectedNotifications) {
+                    expectedNotifications.put(notificationKey, Boolean.TRUE);
+                    expectedNotifications.notify();
+                }
+            }
+        },
+        getNotificationConfig(false, 100, 10, 10000));
 
-		queue.startQueue();
 
-		final DateTime now = clock.getUTCNow();
-		final int MAX_NOTIFICATIONS = 100;
-		for (int i = 0; i < MAX_NOTIFICATIONS; i++) {
+        queue.startQueue();
 
-			final int nextReadyTimeIncrementMs = 1000;
+        final DateTime now = clock.getUTCNow();
+        final int MAX_NOTIFICATIONS = 100;
+        for (int i = 0; i < MAX_NOTIFICATIONS; i++) {
 
-			final UUID key = UUID.randomUUID();
-			final DummyObject obj = new DummyObject("foo", key);
-			final int currentIteration = i;
+            final int nextReadyTimeIncrementMs = 1000;
 
-			final NotificationKey notificationKey = new NotificationKey() {
-				@Override
-				public String toString() {
-					return key.toString();
-				}
-			};
-			expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
-
-			dao.inTransaction(new Transaction<Void, DummySqlTest>() {
-				@Override
-				public Void inTransaction(DummySqlTest transactional,
-						TransactionStatus status) throws Exception {
-
-					transactional.insertDummy(obj);
-					queue.recordFutureNotificationFromTransaction(transactional,
-							now.plus((currentIteration + 1) * nextReadyTimeIncrementMs), notificationKey);
-					return null;
-				}
-			});
+            final UUID key = UUID.randomUUID();
+            final DummyObject obj = new DummyObject("foo", key);
+            final int currentIteration = i;
 
-			// Move time in the future after the notification effectiveDate
-			if (i == 0) {
-				((ClockMock) clock).setDeltaFromReality(nextReadyTimeIncrementMs);
-			} else {
-				((ClockMock) clock).addDeltaFromReality(nextReadyTimeIncrementMs);
-			}
-		}
+            final NotificationKey notificationKey = new NotificationKey() {
+                @Override
+                public String toString() {
+                    return key.toString();
+                }
+            };
+            expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+
+            dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+                @Override
+                public Void inTransaction(DummySqlTest transactional,
+                        TransactionStatus status) throws Exception {
+
+                    transactional.insertDummy(obj);
+                    queue.recordFutureNotificationFromTransaction(transactional,
+                            now.plus((currentIteration + 1) * nextReadyTimeIncrementMs), notificationKey);
+                    return null;
+                }
+            });
 
-		// Wait a little longer since there are a lot of callback that need to happen
-		int nbTry = MAX_NOTIFICATIONS + 1;
-		boolean success = false;
-		do {
-			synchronized(expectedNotifications) {
+            // Move time in the future after the notification effectiveDate
+            if (i == 0) {
+                ((ClockMock) clock).setDeltaFromReality(nextReadyTimeIncrementMs);
+            } else {
+                ((ClockMock) clock).addDeltaFromReality(nextReadyTimeIncrementMs);
+            }
+        }
+
+        // Wait a little longer since there are a lot of callback that need to happen
+        int nbTry = MAX_NOTIFICATIONS + 1;
+        boolean success = false;
+        do {
+            synchronized(expectedNotifications) {
 
-				Collection<Boolean> completed =  Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
-					@Override
-					public boolean apply(Boolean input) {
-						return input;
-					}
-				});
+                Collection<Boolean> completed =  Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
+                    @Override
+                    public boolean apply(Boolean input) {
+                        return input;
+                    }
+                });
 
 				if (completed.size() == MAX_NOTIFICATIONS) {
 					success = true;
@@ -263,20 +265,20 @@ public class TestNotificationQueue {
 		assertEquals(success, true);
 	}
 
-	/**
-	 * Test that we can post a notification in the future from a transaction and get the notification
-	 * callback with the correct key when the time is ready
-	 * @throws Exception
-	 */
-	@Test(groups={"fast"}, enabled = true)
-	public void testMultipleHandlerNotification() throws Exception {
+    /**
+     * Test that we can post a notification in the future from a transaction and get the notification
+     * callback with the correct key when the time is ready
+     * @throws Exception
+     */
+    @Test(groups={"slow"}, enabled = true)
+    public void testMultipleHandlerNotification() throws Exception {
 
-		final Map<String, Boolean> expectedNotificationsFred = new TreeMap<String, Boolean>();
-		final Map<String, Boolean> expectedNotificationsBarney = new TreeMap<String, Boolean>();
+        final Map<String, Boolean> expectedNotificationsFred = new TreeMap<String, Boolean>();
+        final Map<String, Boolean> expectedNotificationsBarney = new TreeMap<String, Boolean>();
 
-		NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi,  clock);
+        NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi,  clock);
 
-		NotificationConfig config=new NotificationConfig() {
+        NotificationConfig config=new NotificationConfig() {
             @Override
             public boolean isNotificationProcessingOff() {
                 return false;
@@ -293,138 +295,138 @@ public class TestNotificationQueue {
             public long getDaoClaimTimeMs() {
                 return 60000;
             }
-		};
+        };
 
 
-		final NotificationQueue queueFred = notificationQueueService.createNotificationQueue("UtilTest", "Fred", new NotificationQueueHandler() {
-                @Override
-                public void handleReadyNotification(String notificationKey, DateTime eventDateTime)  {
-                	log.info("Fred received key: " + notificationKey);
-                	expectedNotificationsFred.put(notificationKey, Boolean.TRUE);
-                	eventsReceived++;
-                }
-            },
-            config);
+        final NotificationQueue queueFred = notificationQueueService.createNotificationQueue("UtilTest", "Fred", new NotificationQueueHandler() {
+            @Override
+            public void handleReadyNotification(String notificationKey, DateTime eventDateTime)  {
+                log.info("Fred received key: " + notificationKey);
+                expectedNotificationsFred.put(notificationKey, Boolean.TRUE);
+                eventsReceived++;
+            }
+        },
+        config);
 
-		final NotificationQueue queueBarney = notificationQueueService.createNotificationQueue("UtilTest", "Barney", new NotificationQueueHandler() {
+        final NotificationQueue queueBarney = notificationQueueService.createNotificationQueue("UtilTest", "Barney", new NotificationQueueHandler() {
             @Override
             public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
-             	log.info("Barney received key: " + notificationKey);
-            	expectedNotificationsBarney.put(notificationKey, Boolean.TRUE);
-            	eventsReceived++;
+                log.info("Barney received key: " + notificationKey);
+                expectedNotificationsBarney.put(notificationKey, Boolean.TRUE);
+                eventsReceived++;
             }
         },
         config);
 
-		queueFred.startQueue();
-//		We don't start Barney so it can never pick up notifications
+        queueFred.startQueue();
+        //		We don't start Barney so it can never pick up notifications
 
 
-		final UUID key = UUID.randomUUID();
-		final DummyObject obj = new DummyObject("foo", key);
-		final DateTime now = new DateTime();
-		final DateTime readyTime = now.plusMillis(2000);
-		final NotificationKey notificationKeyFred = new NotificationKey() {
-			@Override
-			public String toString() {
-				return "Fred" ;
-			}
-		};
+        final UUID key = UUID.randomUUID();
+        final DummyObject obj = new DummyObject("foo", key);
+        final DateTime now = new DateTime();
+        final DateTime readyTime = now.plusMillis(2000);
+        final NotificationKey notificationKeyFred = new NotificationKey() {
+            @Override
+            public String toString() {
+                return "Fred" ;
+            }
+        };
 
 
-		final NotificationKey notificationKeyBarney = new NotificationKey() {
-			@Override
-			public String toString() {
-				return "Barney" ;
-			}
-		};
+        final NotificationKey notificationKeyBarney = new NotificationKey() {
+            @Override
+            public String toString() {
+                return "Barney" ;
+            }
+        };
 
-		expectedNotificationsFred.put(notificationKeyFred.toString(), Boolean.FALSE);
-		expectedNotificationsFred.put(notificationKeyBarney.toString(), Boolean.FALSE);
+        expectedNotificationsFred.put(notificationKeyFred.toString(), Boolean.FALSE);
+        expectedNotificationsFred.put(notificationKeyBarney.toString(), Boolean.FALSE);
 
 
-		// Insert dummy to be processed in 2 sec'
-		dao.inTransaction(new Transaction<Void, DummySqlTest>() {
-			@Override
-			public Void inTransaction(DummySqlTest transactional,
-					TransactionStatus status) throws Exception {
+        // Insert dummy to be processed in 2 sec'
+        dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+            @Override
+            public Void inTransaction(DummySqlTest transactional,
+                    TransactionStatus status) throws Exception {
+
+                transactional.insertDummy(obj);
+                queueFred.recordFutureNotificationFromTransaction(transactional,
+                        readyTime, notificationKeyFred);
+                log.info("posted key: " + notificationKeyFred.toString());
+                queueBarney.recordFutureNotificationFromTransaction(transactional,
+                        readyTime, notificationKeyBarney);
+                log.info("posted key: " + notificationKeyBarney.toString());
+
+                return null;
+            }
+        });
 
-				transactional.insertDummy(obj);
-				queueFred.recordFutureNotificationFromTransaction(transactional,
-						readyTime, notificationKeyFred);
-				log.info("posted key: " + notificationKeyFred.toString());
-				queueBarney.recordFutureNotificationFromTransaction(transactional,
-						readyTime, notificationKeyBarney);
-				log.info("posted key: " + notificationKeyBarney.toString());
+        // Move time in the future after the notification effectiveDate
+        ((ClockMock) clock).setDeltaFromReality(3000);
 
-				return null;
-			}
-		});
-
-		// Move time in the future after the notification effectiveDate
-		((ClockMock) clock).setDeltaFromReality(3000);
-
-		// Note the timeout is short on this test, but expected behaviour is that it times out.
-		// We are checking that the Fred queue does not pick up the Barney event
-		try {
-			await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
-				@Override
-				public Boolean call() throws Exception {
-					return eventsReceived >= 2;
-				}
-			});
-			Assert.fail("There should only have been one event for the queue to pick up - it got more than that");
-		} catch (Exception e) {
-			// expected behavior
-		}
+        // Note the timeout is short on this test, but expected behaviour is that it times out.
+        // We are checking that the Fred queue does not pick up the Barney event
+        try {
+            await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return eventsReceived >= 2;
+                }
+            });
+            Assert.fail("There should only have been one event for the queue to pick up - it got more than that");
+        } catch (Exception e) {
+            // expected behavior
+        }
 
         queueFred.stopQueue();
 		Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
 		Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
 	}
 
-	NotificationConfig getNotificationConfig(final boolean off,
-			final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
-		return new NotificationConfig() {
-			@Override
-			public boolean isNotificationProcessingOff() {
-				return off;
-			}
-			@Override
-			public long getNotificationSleepTimeMs() {
-				return sleepTime;
-			}
-			@Override
-			public int getDaoMaxReadyEvents() {
-				return maxReadyEvents;
-			}
-			@Override
-			public long getDaoClaimTimeMs() {
-				return claimTimeMs;
-			}
-		};
-	}
+    NotificationConfig getNotificationConfig(final boolean off,
+            final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
+        return new NotificationConfig() {
+            @Override
+            public boolean isNotificationProcessingOff() {
+                return off;
+            }
+            @Override
+            public long getNotificationSleepTimeMs() {
+                return sleepTime;
+            }
+            @Override
+            public int getDaoMaxReadyEvents() {
+                return maxReadyEvents;
+            }
+            @Override
+            public long getDaoClaimTimeMs() {
+                return claimTimeMs;
+            }
+        };
+    }
 
 
-	public static class TestNotificationQueueModule extends AbstractModule {
-		@Override
-		protected void configure() {
+    public static class TestNotificationQueueModule extends AbstractModule {
+        @Override
+        protected void configure() {
 
-			bind(Clock.class).to(ClockMock.class);
+            bind(Clock.class).to(ClockMock.class);
 
-			final MysqlTestingHelper helper = new MysqlTestingHelper();
-			bind(MysqlTestingHelper.class).toInstance(helper);
-			IDBI dbi = helper.getDBI();
-			bind(IDBI.class).toInstance(dbi);
-			IDBI otherDbi = helper.getDBI();
-			bind(IDBI.class).annotatedWith(Names.named("global-lock")).toInstance(otherDbi);
-			/*
+            final MysqlTestingHelper helper = new MysqlTestingHelper();
+            bind(MysqlTestingHelper.class).toInstance(helper);
+            IDBI dbi = helper.getDBI();
+            bind(IDBI.class).toInstance(dbi);
+            IDBI otherDbi = helper.getDBI();
+            bind(IDBI.class).annotatedWith(Names.named("global-lock")).toInstance(otherDbi);
+            /*
             bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
             bind(DbiConfig.class).toInstance(config);
-			 */
-		}
-	}
+             */
+        }
+    }
 
 
 }
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 6213a2d..1e51e57 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
@@ -54,7 +54,6 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-
 @Test(groups={"slow"})
 @Guice(modules = MockTagStoreModuleSql.class)
 public class TestTagStore {
@@ -79,7 +78,7 @@ public class TestTagStore {
     private final Logger log = LoggerFactory.getLogger(TestTagStore.class);
     private CallContext context;
 
-    @BeforeClass(alwaysRun = true)
+    @BeforeClass(groups="slow")
     protected void setup() throws IOException {
         // Health check test to make sure MySQL is setup properly
         try {
@@ -101,7 +100,7 @@ public class TestTagStore {
         }
     }
 
-    @AfterClass(alwaysRun = true)
+    @AfterClass(groups="slow")
     public void stopMysql()
     {
         helper.stopMysql();
@@ -122,7 +121,7 @@ public class TestTagStore {
         } catch (Throwable ignore) {
         }
     }
-    @Test
+    @Test(groups="slow")
     public void testTagCreationAndRetrieval() {
         UUID accountId = UUID.randomUUID();
 
@@ -140,7 +139,8 @@ public class TestTagStore {
         assertEquals(savedTag.getId(), tag.getId());
     }
 
-    @Test
+
+    @Test(groups="slow")
     public void testControlTagCreation() {
         UUID accountId = UUID.randomUUID();
         TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
@@ -162,7 +162,7 @@ public class TestTagStore {
         assertEquals(tagStore.generateInvoice(), false);
     }
 
-    @Test
+    @Test(groups="slow")
     public void testDescriptiveTagCreation() {
         UUID accountId = UUID.randomUUID();
         TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
@@ -191,7 +191,7 @@ public class TestTagStore {
         assertEquals(tagStore.generateInvoice(), true);
     }
 
-    @Test
+    @Test(groups="slow")
     public void testMixedTagCreation() {
         UUID accountId = UUID.randomUUID();
         TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
@@ -224,7 +224,7 @@ public class TestTagStore {
         assertEquals(tagStore.generateInvoice(), false);
     }
 
-    @Test
+    @Test(groups="slow")
     public void testControlTags() {
         UUID accountId = UUID.randomUUID();
         TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
@@ -242,13 +242,13 @@ public class TestTagStore {
         assertEquals(tagStore.processPayment(), false);
     }
 
-    @Test(expectedExceptions = TagDefinitionApiException.class)
+    @Test(groups="slow", expectedExceptions = TagDefinitionApiException.class)
     public void testTagDefinitionCreationWithControlTagName() throws TagDefinitionApiException {
         String definitionName = ControlTagType.AUTO_PAY_OFF.toString();
         tagDefinitionDao.create(definitionName, "This should break", context);
     }
 
-    @Test
+    @Test(groups="slow")
     public void testTagDefinitionDeletionForUnusedDefinition() throws TagDefinitionApiException {
         String definitionName = "TestTag1234";
         tagDefinitionDao.create(definitionName, "Some test tag", context);
@@ -261,7 +261,7 @@ public class TestTagStore {
         assertNull(tagDefinition);
     }
 
-    @Test(expectedExceptions = TagDefinitionApiException.class)
+    @Test(groups="slow", expectedExceptions = TagDefinitionApiException.class)
     public void testTagDefinitionDeletionForDefinitionInUse() throws TagDefinitionApiException {
         String definitionName = "TestTag12345";
         tagDefinitionDao.create(definitionName, "Some test tag", context);
@@ -282,7 +282,7 @@ public class TestTagStore {
         tagDefinitionDao.deleteTagDefinition(definitionName, context);
     }
 
-    @Test
+    @Test(groups="slow")
     public void testDeleteAllTagsForDefinitionInUse() {
         String definitionName = "TestTag1234567";
         try {
@@ -317,7 +317,7 @@ public class TestTagStore {
         }
     }
 
-    @Test
+    @Test(groups="slow")
     public void testDeleteAllTagsForDefinitionNotInUse() {
         String definitionName = "TestTag4321";
         try {
@@ -342,7 +342,7 @@ public class TestTagStore {
         }
     }
 
-    @Test(expectedExceptions = TagDefinitionApiException.class)
+    @Test(groups="slow", expectedExceptions = TagDefinitionApiException.class)
     public void testDeleteAllTagsForDefinitionWithWrongName() throws TagDefinitionApiException {
         String definitionName = "TestTag654321";
         String wrongDefinitionName = "TestTag564321";
@@ -364,7 +364,7 @@ public class TestTagStore {
         }
     }
 
-    @Test
+    @Test(groups="slow")
     public void testGetTagDefinitions() {
         List<TagDefinition> definitionList = tagDefinitionDao.getTagDefinitions();
         assertTrue(definitionList.size() >= ControlTagType.values().length);
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 bb7ac85..1848950 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
@@ -41,8 +41,8 @@ public class TestValidationManager {
     private static final String TABLE_NAME = "validation_test";
 
     private ValidationManager vm;
-
-    @BeforeClass(alwaysRun = true)
+    
+    @BeforeClass(groups = "slow")
     public void setup() throws IOException {
         setupDatabase();
         setupDao();
@@ -61,7 +61,7 @@ public class TestValidationManager {
         helper.initDb(testDdl);
     }
 
-    @AfterClass(alwaysRun = true)
+    @AfterClass(groups = "slow")
     public void tearDown() {
         stopDatabase();
     }
@@ -70,7 +70,7 @@ public class TestValidationManager {
         helper.stopMysql();
     }
 
-    @Test
+    @Test(groups = "slow")
     public void testRetrievingColumnInfo() {
         Collection<ColumnInfo> columnInfoList = vm.getTableInfo(TABLE_NAME);
         assertEquals(columnInfoList.size(), 4);
@@ -83,7 +83,7 @@ public class TestValidationManager {
         assertEquals(numericColumnInfo.getPrecision(), 10);
     }
 
-    @Test
+    @Test(groups = "slow")
     public void testSimpleConfiguration() {
         String STRING_FIELD_2 = "column2";
         String STRING_FIELD_2_PROPERTY = "stringField2";