killbill-aplcache

Changes

Details

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 ed54ce2..2f50390 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
@@ -16,14 +16,14 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.entity.UpdatableEntity;
 import org.joda.time.DateTime;
 
+import com.ning.billing.catalog.api.overdue.Overdueable;
 import com.ning.billing.util.customfield.CustomizableEntity;
+import com.ning.billing.util.entity.UpdatableEntity;
 import com.ning.billing.util.tag.Taggable;
-import org.skife.jdbi.v2.Update;
 
-public interface Account extends AccountData, CustomizableEntity, UpdatableEntity, Taggable {
+public interface Account extends AccountData, CustomizableEntity, UpdatableEntity, Taggable, Overdueable {
     public DateTime getCreatedDate();
 
     public DateTime getUpdatedDate();
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Catalog.java b/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
index 2b3609a..694fdf1 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
@@ -18,6 +18,9 @@ package com.ning.billing.catalog.api;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+
 public interface Catalog {
 	//
     // Simple getters
@@ -74,7 +77,5 @@ public interface Catalog {
 			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
 
     public abstract boolean canCreatePlan(PlanSpecifier specifier, DateTime requestedDate) throws CatalogApiException;
-	
-	
-	
+		
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingState.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingState.java
index d1c30a1..b13a56f 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingState.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingState.java
@@ -23,7 +23,7 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.util.tag.Tag;
 
-public class BillingState {
+public class BillingState<T extends Overdueable> {
 	private final UUID objectId;
 	private final int numberOfUnpaidInvoices;
 	private final BigDecimal balanceOfUnpaidInvoices;
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingStateBundle.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingStateBundle.java
index e640f61..a637241 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingStateBundle.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/BillingStateBundle.java
@@ -22,33 +22,32 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PriceList;
 import com.ning.billing.catalog.api.Product;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.tag.Tag;
 
-public class BillingStateBundle extends BillingState {
-	private final BillingState accountState;
+public class BillingStateBundle extends BillingState<SubscriptionBundle> {
     private final Product basePlanProduct;
     private final BillingPeriod basePlanBillingPeriod;
     private final PriceList basePlanPriceList;
+    private final PhaseType basePlanPhaseType;
     
-	public BillingStateBundle(UUID id, BillingState accountState, int numberOfUnpaidInvoices, BigDecimal unpaidInvoiceBalance,
+	public BillingStateBundle(UUID id, int numberOfUnpaidInvoices, BigDecimal unpaidInvoiceBalance,
 			DateTime dateOfEarliestUnpaidInvoice,
 			PaymentResponse responseForLastFailedPayment,
 			Tag[] tags, 
 			Product basePlanProduct,
 			BillingPeriod basePlanBillingPeriod, 
-			PriceList basePlanPriceList) {
+			PriceList basePlanPriceList, PhaseType basePlanPhaseType) {
 		super(id, numberOfUnpaidInvoices, unpaidInvoiceBalance, 
 				dateOfEarliestUnpaidInvoice, responseForLastFailedPayment, tags);
-		this.accountState = accountState;
+		
 		this.basePlanProduct = basePlanProduct;
 		this.basePlanBillingPeriod = basePlanBillingPeriod;
 		this.basePlanPriceList = basePlanPriceList;
-	}
-	
-	public BillingState getAccountState() {
-		return accountState;
+		this.basePlanPhaseType = basePlanPhaseType;
 	}
 	
 	public Product getBasePlanProduct() {
@@ -62,4 +61,8 @@ public class BillingStateBundle extends BillingState {
 	public PriceList getBasePlanPriceList() {
 		return basePlanPriceList;
 	}
+
+    public PhaseType getBasePlanPhaseType() {
+        return basePlanPhaseType;
+    }
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/Overdueable.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/Overdueable.java
new file mode 100644
index 0000000..3bf94d3
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/Overdueable.java
@@ -0,0 +1,24 @@
+/*
+ * 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.catalog.api.overdue;
+
+import java.util.UUID;
+
+public interface Overdueable {
+
+    public UUID getId();
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueError.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueError.java
new file mode 100644
index 0000000..0219e37
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueError.java
@@ -0,0 +1,33 @@
+/*
+ * 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.catalog.api.overdue;
+
+import com.ning.billing.BillingExceptionBase;
+import com.ning.billing.ErrorCode;
+
+public class OverdueError extends BillingExceptionBase {
+    private static final long serialVersionUID = 1L;
+
+    public OverdueError(Throwable cause, ErrorCode code, Object... args) {
+        super(cause, code, args);
+    }
+
+    public OverdueError(ErrorCode code, Object... args) {
+        super(code, args);
+    }
+
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
index 48c044a..d4faaff 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
@@ -16,34 +16,13 @@
 
 package com.ning.billing.catalog.api.overdue;
 
-import java.util.UUID;
 
-public class OverdueState {
-	private final UUID id;
-	private final String stageName;
-	private final String externalMessage;
-	private final boolean cancel;
-	
-	public OverdueState(UUID id, String stageName, String externalMessage, boolean cancel) {
-		this.id = id;
-		this.stageName = stageName;
-		this.externalMessage = externalMessage;
-		this.cancel = cancel;
-	}
+public interface OverdueState<T extends Overdueable> {
 
-	public UUID getId() {
-		return id;
-	}
+    public String getName();
 
-	public boolean cancel() {
-		return cancel;
-	}
-	
-	public String getStageName() {
-		return stageName;
-	}
-	public String getExternalMessage() {
-		return externalMessage;
-	}
+    public String getExternalMessage();
 
-}
+    public boolean applyCancel();
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
new file mode 100644
index 0000000..50bf592
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
@@ -0,0 +1,29 @@
+/*
+ * 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.catalog.api.overdue;
+
+import org.joda.time.DateTime;
+
+public interface OverdueStateSet<T extends Overdueable> {
+
+    public abstract OverdueState<T> findClearState();
+
+    public abstract OverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now);
+
+    public abstract DateTime dateOfNextCheck(BillingState<T> billingState, DateTime now);
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
index c93fde8..e1ee020 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
@@ -18,6 +18,13 @@ package com.ning.billing.catalog.api;
 
 import java.util.Date;
 
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.overdue.BillingStateBundle;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+
 
 public interface StaticCatalog {
     //
@@ -51,7 +58,7 @@ public interface StaticCatalog {
     public abstract PlanPhase findCurrentPhase(String name) throws CatalogApiException;
     
     //
-    // Rules
+    //  
     //
 	public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
 			PlanSpecifier to) throws CatalogApiException;
@@ -71,6 +78,6 @@ public interface StaticCatalog {
 
     public abstract boolean canCreatePlan(PlanSpecifier specifier) throws CatalogApiException;
 
+    public abstract OverdueStateSet<SubscriptionBundle> currentBundleOverdueStateSet() throws CatalogApiException;
 
-	
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
index f7c2e84..baa6843 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
@@ -16,11 +16,13 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 
-import java.util.UUID;
+import com.ning.billing.catalog.api.overdue.Overdueable;
 
-public interface SubscriptionBundle {
+public interface SubscriptionBundle extends Overdueable {
 
     public UUID getAccountId();
 
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index baaa3c4..4cd4d9f 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -143,7 +143,17 @@ public enum ErrorCode {
     INVOICE_INVALID_TRANSITION(4002, "Transition did not contain a subscription id."),
     INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID(4003, "No account id was retrieved for subscription id %s"),
     INVOICE_INVALID_DATE_SEQUENCE(4004, "Date sequence was invalid. Start Date: %s; End Date: %s; Target Date: %s"),
-    INVOICE_TARGET_DATE_TOO_FAR_IN_THE_FUTURE(4005, "The target date was too far in the future. Target Date: %s")
+    INVOICE_TARGET_DATE_TOO_FAR_IN_THE_FUTURE(4005, "The target date was too far in the future. Target Date: %s"),
+    
+    /*
+     * 
+     * Range 5000: Overdue system
+     * 
+     */
+    OVERDUE_OVERDUEABLE_NOT_SUPPORTED(5001, "The Overdueable type '%s' is not supported"), 
+    OVERDUE_CAT_ERROR_ENCOUNTERED(5002,"Catalog error encountered when attempting to refresh the state of Overdueable: id='%s', type='%s'")
+    
+    
     ;
 
     private int code;
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueService.java b/api/src/main/java/com/ning/billing/overdue/OverdueService.java
new file mode 100644
index 0000000..068bc63
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueService.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue;
+
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.lifecycle.KillbillService;
+
+public interface OverdueService extends KillbillService {
+    public String getName();
+
+    public OverdueUserApi getUserApi();
+    
+    public <T extends Overdueable> OverdueState<T> refresh(T overdueable) throws OverdueError;
+}
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
new file mode 100644
index 0000000..e2ead75
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
@@ -0,0 +1,31 @@
+/*
+ * 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.overdue;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public interface OverdueUserApi {
+
+    public <T extends Overdueable> OverdueState<T>  getOverdueStateFor(T overdueable) throws OverdueError;
+
+    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError;
+
+    public <T extends Overdueable> void setOverrideBillingStateForAccount(T overdueable, BillingState<T> state) throws OverdueError;
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/BundleCondition.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/BundleCondition.java
index fb8e985..445550e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/BundleCondition.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/BundleCondition.java
@@ -26,14 +26,13 @@ import org.joda.time.DateTime;
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.overdue.BillingState;
 import com.ning.billing.catalog.api.overdue.BillingStateBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class BundleCondition extends Condition {
-	@XmlElement(required=false, name="accountConditions")
-	private Condition accountCondition;
-	
+public class BundleCondition extends DefaultCondition<SubscriptionBundle> {
 	@XmlElement(required=false, name="basePlanProduct")
     @XmlIDREF
     private DefaultProduct basePlanProduct;
@@ -44,18 +43,17 @@ public class BundleCondition extends Condition {
     @XmlElement(required=false, name="basePlanPriceList")
     @XmlIDREF
     private DefaultPriceList basePlanPriceList;
+    
+    @XmlElement(required=false)
+    private PhaseType basePlanPhaseType;    
+
 
 	public boolean evaluate(BillingStateBundle state, DateTime now) {
 		return super.evaluate((BillingState)state, now) &&
-				(accountCondition      == null || accountCondition.evaluate(state.getAccountState(), now)) &&
 				(basePlanProduct       == null || basePlanProduct.equals(state.getBasePlanProduct())) &&
 				(basePlanBillingPeriod == null || basePlanBillingPeriod.equals(state.getBasePlanBillingPeriod())) &&
-				(basePlanPriceList     == null || basePlanPriceList.equals(state.getBasePlanPriceList()));				
-	}
-
-	protected BundleCondition setAccountCondition(Condition accountCondition) {
-		this.accountCondition = accountCondition;
-		return this;
+                (basePlanPriceList     == null || basePlanPriceList.equals(state.getBasePlanPriceList())) &&              
+                (basePlanPhaseType     == null || basePlanPhaseType.equals(state.getBasePlanPhaseType()));              
 	}
 
 	protected BundleCondition setBasePlanProduct(DefaultProduct basePlanProduct) {
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/Condition.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/Condition.java
index c45c7b0..04ff711 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/Condition.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/Condition.java
@@ -16,74 +16,14 @@
 
 package com.ning.billing.catalog.overdue;
 
-import java.math.BigDecimal;
-import java.net.URI;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-
 import org.joda.time.DateTime;
 
-import com.ning.billing.catalog.DefaultDuration;
-import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.api.overdue.BillingState;
-import com.ning.billing.catalog.api.overdue.PaymentResponse;
-import com.ning.billing.util.config.ValidatingConfig;
-import com.ning.billing.util.config.ValidationErrors;
-import com.ning.billing.util.tag.ControlTagType;
-import com.ning.billing.util.tag.Tag;
-
-@XmlAccessorType(XmlAccessType.NONE)
-public class Condition extends ValidatingConfig<StandaloneCatalog> {
-	@XmlElement(required=false, name="numberOfUnpaidInvoicesEqualsOrExceeds")
-	private Integer numberOfUnpaidInvoicesEqualsOrExceeds;
-
-	@XmlElement(required=false, name="totalUnpaidInvoiceBalanceEqualsOrExceeds")
-	private BigDecimal totalUnpaidInvoiceBalanceEqualsOrExceeds;
-
-	@XmlElement(required=false, name="timeSinceEarliestUnpaidInvoiceEqualsOrExceeds")
-	private DefaultDuration timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
-
-	@XmlElementWrapper(required=false, name="responseForLastFailedPaymentIn")
-	@XmlElement(required=false, name="response")
-	private PaymentResponse[] responseForLastFailedPayment;
+import com.ning.billing.catalog.api.overdue.Overdueable;
 
-	@XmlElement(required=false, name="controlTag")
-	private ControlTagType controlTag;
-	
-	public boolean evaluate(BillingState state, DateTime now) {
-		return 
-				(numberOfUnpaidInvoicesEqualsOrExceeds == null || state.getNumberOfUnpaidInvoices() >= numberOfUnpaidInvoicesEqualsOrExceeds.intValue() ) &&
-				(totalUnpaidInvoiceBalanceEqualsOrExceeds == null || totalUnpaidInvoiceBalanceEqualsOrExceeds.compareTo(state.getBalanceOfUnpaidInvoices()) <= 0) &&
-				(timeSinceEarliestUnpaidInvoiceEqualsOrExceeds == null || !timeSinceEarliestUnpaidInvoiceEqualsOrExceeds.addToDateTime(state.getDateOfEarliestUnpaidInvoice()).isAfter(now)) &&
-				(responseForLastFailedPayment == null || responseIsIn(state.getResponseForLastFailedPayment(), responseForLastFailedPayment)) &&
-				(controlTag == null || isTagIn(controlTag, state.getTags()));
-	}
-	
-	private boolean responseIsIn(PaymentResponse actualResponse,
-			PaymentResponse[] responseForLastFailedPayment) {
-		for(PaymentResponse response: responseForLastFailedPayment) {
-			if(response.equals(actualResponse)) return true;
-		}
-		return false;
-	}
 
-	private boolean isTagIn(ControlTagType tag, Tag[] tags) {
-		for(Tag t : tags) {
-			if (t.getTagDefinitionName().equals(tag.toString())) return true;
-		}
-		return false;
-	}
+public interface Condition<T extends Overdueable> {
 
-	@Override
-	public ValidationErrors validate(StandaloneCatalog root,
-			ValidationErrors errors) {
-		return errors;
-	}
+    public boolean evaluate(BillingState state, DateTime now);
 
-	@Override
-	public void initialize(StandaloneCatalog root, URI uri) {
-	}
-}
+}
\ No newline at end of file
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultCondition.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultCondition.java
new file mode 100644
index 0000000..32c50b8
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultCondition.java
@@ -0,0 +1,94 @@
+/*
+ * 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.catalog.overdue;
+
+import java.math.BigDecimal;
+import java.net.URI;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.DefaultDuration;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.catalog.api.overdue.PaymentResponse;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class DefaultCondition<T extends Overdueable> extends ValidatingConfig<StandaloneCatalog> implements Condition<T> {
+	@XmlElement(required=false, name="numberOfUnpaidInvoicesEqualsOrExceeds")
+	private Integer numberOfUnpaidInvoicesEqualsOrExceeds;
+
+	@XmlElement(required=false, name="totalUnpaidInvoiceBalanceEqualsOrExceeds")
+	private BigDecimal totalUnpaidInvoiceBalanceEqualsOrExceeds;
+
+	@XmlElement(required=false, name="timeSinceEarliestUnpaidInvoiceEqualsOrExceeds")
+	private DefaultDuration timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
+
+	@XmlElementWrapper(required=false, name="responseForLastFailedPaymentIn")
+	@XmlElement(required=false, name="response")
+	private PaymentResponse[] responseForLastFailedPayment;
+
+	@XmlElement(required=false, name="controlTag")
+	private ControlTagType controlTag;
+	
+	/* (non-Javadoc)
+     * @see com.ning.billing.catalog.overdue.Condition#evaluate(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
+     */
+	@Override
+    public boolean evaluate(BillingState state, DateTime now) {
+		return 
+				(numberOfUnpaidInvoicesEqualsOrExceeds == null || state.getNumberOfUnpaidInvoices() >= numberOfUnpaidInvoicesEqualsOrExceeds.intValue() ) &&
+				(totalUnpaidInvoiceBalanceEqualsOrExceeds == null || totalUnpaidInvoiceBalanceEqualsOrExceeds.compareTo(state.getBalanceOfUnpaidInvoices()) <= 0) &&
+				(timeSinceEarliestUnpaidInvoiceEqualsOrExceeds == null || !timeSinceEarliestUnpaidInvoiceEqualsOrExceeds.addToDateTime(state.getDateOfEarliestUnpaidInvoice()).isAfter(now)) &&
+				(responseForLastFailedPayment == null || responseIsIn(state.getResponseForLastFailedPayment(), responseForLastFailedPayment)) &&
+				(controlTag == null || isTagIn(controlTag, state.getTags()));
+	}
+	
+	private boolean responseIsIn(PaymentResponse actualResponse,
+			PaymentResponse[] responseForLastFailedPayment) {
+		for(PaymentResponse response: responseForLastFailedPayment) {
+			if(response.equals(actualResponse)) return true;
+		}
+		return false;
+	}
+
+	private boolean isTagIn(ControlTagType tag, Tag[] tags) {
+		for(Tag t : tags) {
+			if (t.getTagDefinitionName().equals(tag.toString())) return true;
+		}
+		return false;
+	}
+
+	@Override
+	public ValidationErrors validate(StandaloneCatalog root,
+			ValidationErrors errors) {
+		return errors;
+	}
+
+	@Override
+	public void initialize(StandaloneCatalog root, URI uri) {
+	}
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java
new file mode 100644
index 0000000..1781242
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java
@@ -0,0 +1,64 @@
+/*
+ * 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.catalog.overdue;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public abstract class DefaultOverdueStateSet<T extends Overdueable> implements OverdueStateSet<T> {
+    private DefaultOverdueState<T> clearState;
+    
+    protected abstract DefaultOverdueState<T>[] getStates();
+    
+    protected abstract DefaultOverdueState<T> getClearState();
+    
+    
+    /* (non-Javadoc)
+     * @see com.ning.billing.catalog.overdue.OverdueBillingState#findClearState()
+     */
+    @Override
+    public DefaultOverdueState<T> findClearState() {
+        if (clearState != null) {
+            clearState = getClearState();
+        }
+        return clearState;
+    }
+    
+    /* (non-Javadoc)
+     * @see com.ning.billing.catalog.overdue.OverdueBillingState#calculateOverdueState(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
+     */
+    @Override
+    public DefaultOverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now) {         
+            for(DefaultOverdueState<T> overdueState : getStates()) {
+                if(overdueState.getCondition().evaluate(billingState, now)) {   
+                    return overdueState;
+                }
+            }
+            return  findClearState();
+    }
+
+    @Override
+    public DateTime dateOfNextCheck(BillingState<T> billingState, DateTime now) {
+        throw new NotImplementedException();
+    }
+        
+      
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
new file mode 100644
index 0000000..1258ac9
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
@@ -0,0 +1,38 @@
+/*
+ * 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.catalog.overdue;
+
+import javax.xml.bind.annotation.XmlElement;
+
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+
+public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBundle>{
+    @XmlElement(required=false, name="bundleOverdueStages")
+    private DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates;
+
+    @Override
+    protected DefaultOverdueState<SubscriptionBundle>[] getStates() {
+        return bundleOverdueStates;
+    }
+
+    @Override
+    protected DefaultOverdueState<SubscriptionBundle> getClearState() {
+        return null;
+    }
+    
+
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
index 029cdcd..3aa1420 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
@@ -17,7 +17,6 @@
 package com.ning.billing.catalog;
 
 import java.net.URI;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
 
@@ -42,7 +41,10 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.StaticCatalog;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.catalog.overdue.OverdueRules;
 import com.ning.billing.catalog.rules.PlanRules;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
@@ -69,12 +71,15 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
 	@XmlElement(name="rules", required=true)
 	private PlanRules planRules;
 
+    @XmlElement(name="overdueRules", required=true)
+    private OverdueRules overdueRules;
+
 	@XmlElementWrapper(name="plans", required=true)
 	@XmlElement(name="plan", required=true)
 	private DefaultPlan[] plans;
 
-	@XmlElement(name="priceLists", required=true)
-	private DefaultPriceListSet priceLists;
+    @XmlElement(name="priceLists", required=true)
+    private DefaultPriceListSet priceLists;
 
 	public StandaloneCatalog() {}
 
@@ -303,4 +308,13 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
 				(!plan.isRetired()) &&
 				(!priceList.isRetired());
 	}
+
+    @Override
+    public OverdueStateSet<SubscriptionBundle> currentBundleOverdueStateSet()
+            throws CatalogApiException {
+         return overdueRules.getBundleStateSet();
+    }
+
+
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
index ef9b125..5718d35 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
@@ -48,6 +48,8 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.StaticCatalog;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
@@ -424,8 +426,12 @@ public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implem
 		return versionForDate(clock.getUTCNow()).canCreatePlan(specifier);
 	}
 
-	
-
+    @Override
+    public OverdueStateSet<SubscriptionBundle> currentBundleOverdueStateSet()
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).currentBundleOverdueStateSet();
+    }
 
  
+ 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestBundleCondition.java b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestBundleCondition.java
index 823112e..f2dc477 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestBundleCondition.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestBundleCondition.java
@@ -16,13 +16,9 @@
 
 package com.ning.billing.catalog.overdue;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -32,62 +28,20 @@ import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.MockPriceList;
 import com.ning.billing.catalog.MockProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.overdue.BillingStateBundle;
 import com.ning.billing.catalog.api.overdue.PaymentResponse;
-import com.ning.billing.util.config.XMLLoader;
-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;
 
 public class TestBundleCondition {
 
-	@XmlRootElement(name="conditions")
-	private static class MockBundleCondition extends BundleCondition {}
-
-	@Test(groups={"fast"}, enabled=true)
-	public void testAccountState() throws Exception {
-		String xml = 
-				"<conditions>" +
-				"	<accountConditions>" +
-				"		<controlTag>OVERDUE_ENFORCEMENT_OFF</controlTag>" +
-				"	</accountConditions>" +
-				"</conditions>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		BundleCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockBundleCondition.class);
-
-		DateTime now = new DateTime();
-		
-		BillingState accountState0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
-		BillingState accountState1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		BillingState accountState2 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), 
-				PaymentResponse.DO_NOT_HONOR, 
-				new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF), 
-						  new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),
-						  new DescriptiveTag(null, "Tag", "Martin", now)});
-		
-		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), accountState0, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createBicycle(), BillingPeriod.MONTHLY, new MockPriceList() );
-		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), accountState1, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createBicycle(), BillingPeriod.MONTHLY, new MockPriceList() );
-		BillingStateBundle state2 = new BillingStateBundle(new UUID(0L,1L), accountState2, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createBicycle(), BillingPeriod.MONTHLY, new MockPriceList() );
-		
-		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
-		Assert.assertTrue(c.evaluate(state1, new DateTime()));
-		Assert.assertTrue(c.evaluate(state2, new DateTime()));
-	}
-	
 	@Test(groups={"fast"}, enabled=true)
 	public void testProduct() throws Exception {
 		DefaultProduct prod = MockProduct.createBicycle();
 		BundleCondition c = new BundleCondition().setBasePlanProduct(prod);
-
-		DateTime now = new DateTime();
-		
-		BillingState accountState0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
-		BillingState accountState1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
 		
-		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), accountState0, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList() );
-		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), accountState1, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, prod, BillingPeriod.MONTHLY, new MockPriceList() );
+    	BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList(), PhaseType.EVERGREEN);
+		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, prod, BillingPeriod.MONTHLY, new MockPriceList(), PhaseType.EVERGREEN);
 
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -98,13 +52,8 @@ public class TestBundleCondition {
 	public void testBillingPeriod() throws Exception {
 		BundleCondition c = new BundleCondition().setBasePlanBillingPeriod(BillingPeriod.ANNUAL);
 
-		DateTime now = new DateTime();
-		
-		BillingState accountState0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
-		BillingState accountState1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		
-		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), accountState0, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList() );
-		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), accountState1, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.ANNUAL, new MockPriceList() );
+		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList(), PhaseType.EVERGREEN);
+		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.ANNUAL, new MockPriceList(), PhaseType.EVERGREEN);
 
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -115,13 +64,8 @@ public class TestBundleCondition {
 		DefaultPriceList pl = new MockPriceList().setName("test");
 		BundleCondition c = new BundleCondition().setBasePlanPriceList(pl);
 
-		DateTime now = new DateTime();
-		
-		BillingState accountState0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
-		BillingState accountState1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		
-		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), accountState0, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList() );
-		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), accountState1, 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{},  MockProduct.createJet(), BillingPeriod.MONTHLY, pl );
+		BillingStateBundle state0 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{}, MockProduct.createJet(), BillingPeriod.MONTHLY, new MockPriceList(), PhaseType.EVERGREEN);
+		BillingStateBundle state1 = new BillingStateBundle(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{},  MockProduct.createJet(), BillingPeriod.MONTHLY, pl, PhaseType.EVERGREEN);
 
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
diff --git a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
index 79dad9f..0bfd0d0 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+00 * 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
@@ -28,6 +28,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
 import com.ning.billing.catalog.api.overdue.PaymentResponse;
 import com.ning.billing.util.config.XMLLoader;
 import com.ning.billing.util.tag.ControlTagType;
@@ -38,7 +39,7 @@ import com.ning.billing.util.tag.Tag;
 public class TestCondition {
 	
 	@XmlRootElement(name="condition")
-	private static class MockCondition extends Condition {}
+	private static class MockCondition extends DefaultCondition<Overdueable> {}
 
 	@Test(groups={"fast"}, enabled=true)
 	public void testNumberOfUnpaidInvoicesEqualsOrExceeds() throws Exception {
@@ -49,9 +50,9 @@ public class TestCondition {
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
 		
-		BillingState state0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state1 = new BillingState(new UUID(0L,1L), 1, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state2 = new BillingState(new UUID(0L,1L), 2, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 2, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -67,9 +68,9 @@ public class TestCondition {
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
 		
-		BillingState state0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state2 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("200.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -88,9 +89,9 @@ public class TestCondition {
 		
 		DateTime now = new DateTime();
 		
-		BillingState state0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state2 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, now));
 		Assert.assertTrue(c.evaluate(state1, now));
@@ -108,9 +109,9 @@ public class TestCondition {
 		
 		DateTime now = new DateTime();
 		
-		BillingState state0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
-		BillingState state1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState state2 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.DO_NOT_HONOR , new Tag[]{});
+		BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
+		BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.DO_NOT_HONOR , new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, now));
 		Assert.assertTrue(c.evaluate(state1, now));
@@ -128,9 +129,9 @@ public class TestCondition {
 		
 		DateTime now = new DateTime();
 		
-		BillingState state0 = new BillingState(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
-		BillingState state1 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		BillingState state2 = new BillingState(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), 
+		BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
+		BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
+		BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), 
 				PaymentResponse.DO_NOT_HONOR, 
 				new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF), 
 						  new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
new file mode 100644
index 0000000..97fab0b
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -0,0 +1,57 @@
+/*
+ * 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.overdue.api;
+
+import org.apache.commons.lang.NotImplementedException;
+
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.overdue.OverdueService;
+import com.ning.billing.overdue.OverdueUserApi;
+import com.ning.billing.overdue.dao.OverdueDao;
+
+public class DefaultOverdueUserApi implements OverdueUserApi{
+
+    private OverdueDao dao;
+    private OverdueService service;
+
+    @Inject
+    public DefaultOverdueUserApi(OverdueDao dao, OverdueService service) {
+        this.dao = dao;
+        this.service = service;
+    }
+    
+    @Override
+    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable) {
+        return dao.getOverdueStateFor(overdueable);
+    }
+
+    @Override
+    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError {
+        return service.refresh(overdueable);     
+    } 
+
+    @Override
+    public <T extends Overdueable> void setOverrideBillingStateForAccount(
+            T overdueable, BillingState<T> state) {
+        throw new NotImplementedException();
+    }
+    
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
new file mode 100644
index 0000000..d49d0e6
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -0,0 +1,27 @@
+/*
+ * 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.overdue.applicator;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public interface OverdueStateApplicator<T extends Overdueable>{
+
+    public void apply(T overdueable, OverdueState<T> previousOverdueState, OverdueState<T> nextOverdueState, DateTime timeOfNextCheck);
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java
new file mode 100644
index 0000000..8f16dc0
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java
@@ -0,0 +1,40 @@
+/*
+ * 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.overdue.applicator;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+
+public class OverdueStateApplicatorBundle implements OverdueStateApplicator<SubscriptionBundle>{
+
+    @Override
+    public void apply(SubscriptionBundle overdueable,
+            OverdueState<SubscriptionBundle> previousOverdueState,
+            OverdueState<SubscriptionBundle> nextOverdueState, DateTime timeOfNextCheck) {
+        //  Create immediate notification with this data
+        //  Make changes to apply the state
+        //  Record new state in DAO
+        // Create notification for future check
+        
+        //If new state is clear state reset next events and override table
+        throw new NotImplementedException();
+    }
+
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
new file mode 100644
index 0000000..c2e5efd
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
@@ -0,0 +1,25 @@
+/*
+ * 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.overdue.calculator;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public interface BillingStateCalculator<T extends Overdueable> {
+
+    public BillingState<T> calculateBillingState(T overdueable);
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
new file mode 100644
index 0000000..1abe865
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -0,0 +1,31 @@
+/*
+ * 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.overdue.calculator;
+
+import org.apache.commons.lang.NotImplementedException;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+
+public class BillingStateCalculatorBundle  implements BillingStateCalculator<SubscriptionBundle>{
+
+    @Override
+    public BillingState<SubscriptionBundle> calculateBillingState(SubscriptionBundle overdueable) {
+        throw new NotImplementedException();
+    }
+
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/dao/DefaultOverdueDao.java b/overdue/src/main/java/com/ning/billing/overdue/dao/DefaultOverdueDao.java
new file mode 100644
index 0000000..8b8c551
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/dao/DefaultOverdueDao.java
@@ -0,0 +1,38 @@
+/*
+ * 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.overdue.dao;
+
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public class DefaultOverdueDao implements OverdueDao {
+
+    @Override
+    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(
+            T overdueable) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends Overdueable> void setOverdueStateForBundle(T overdueable,
+            OverdueState<T> newOverdueState) {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java
new file mode 100644
index 0000000..610aab0
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java
@@ -0,0 +1,28 @@
+/*
+ * 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.overdue.dao;
+
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public interface OverdueDao {
+
+    <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable);
+
+    <T extends Overdueable> void  setOverdueStateForBundle(T overdueable, OverdueState<T> newOverdueState);
+
+}
\ No newline at end of file
diff --git a/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
new file mode 100644
index 0000000..78fc37d
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
@@ -0,0 +1,54 @@
+/*
+ * 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.overdue.service;
+
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.overdue.OverdueService;
+import com.ning.billing.overdue.OverdueUserApi;
+import com.ning.billing.overdue.wrapper.OverdueWrapper;
+import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
+
+public class DefaultOverdueService implements OverdueService {
+    public static final String OVERDUE_SERVICE_NAME = "overdue-service";
+    
+    private final OverdueWrapperFactory factory;
+
+    @Inject
+    public DefaultOverdueService(OverdueWrapperFactory factory) {
+        this.factory = factory;
+    }
+    
+    @Override
+    public String getName() {
+        return OVERDUE_SERVICE_NAME;
+    }
+
+    @Override
+    public OverdueUserApi getUserApi() {
+        return null;
+    }
+
+    @Override
+    public <T extends Overdueable> OverdueState<T> refresh(T overdueable) throws OverdueError {
+        OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
+        return wrapper.refresh();
+    } 
+ 
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
new file mode 100644
index 0000000..f2258bd
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -0,0 +1,59 @@
+/*
+ * 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.overdue.wrapper;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.overdue.applicator.OverdueStateApplicator;
+import com.ning.billing.overdue.calculator.BillingStateCalculator;
+import com.ning.billing.overdue.dao.OverdueDao;
+import com.ning.billing.util.clock.Clock;
+
+public class OverdueWrapper<T extends Overdueable> {
+    private final T overdueable;
+    private final OverdueDao dao;
+    private final Clock clock;
+    private final OverdueStateSet<T> overdueStateSet;
+    private final BillingStateCalculator<T> billingStateCalcuator;
+    private final OverdueStateApplicator<T> overdueStateApplicator;
+
+    public OverdueWrapper(T overdueable, OverdueDao dao,
+            OverdueStateSet<T> overdueStateSet,
+            Clock clock,
+            BillingStateCalculator<T> billingStateCalcuator,
+            OverdueStateApplicator<T> overdueStateApplicator) {
+        this.overdueable = overdueable;
+        this.overdueStateSet = overdueStateSet;
+        this.dao = dao;
+        this.clock = clock;
+        this.billingStateCalcuator = billingStateCalcuator;
+        this.overdueStateApplicator = overdueStateApplicator;
+    }
+
+    public OverdueState<T> refresh() throws OverdueError {
+        BillingState<T> billingState = billingStateCalcuator.calculateBillingState(overdueable);
+        OverdueState<T> previousOverdueStateName = dao.getOverdueStateFor(overdueable);
+        OverdueState<T> nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
+        if(!previousOverdueStateName.equals(nextOverdueState.getName())) {
+            overdueStateApplicator.apply(overdueable, nextOverdueState, nextOverdueState, overdueStateSet.dateOfNextCheck(billingState, clock.getUTCNow())); 
+        }
+        return nextOverdueState;
+    }
+}
\ No newline at end of file
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
new file mode 100644
index 0000000..594c606
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -0,0 +1,65 @@
+/*
+ * 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.overdue.wrapper;
+
+import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.overdue.OverdueError;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.overdue.applicator.OverdueStateApplicatorBundle;
+import com.ning.billing.overdue.calculator.BillingStateCalculatorBundle;
+import com.ning.billing.overdue.dao.OverdueDao;
+import com.ning.billing.util.clock.Clock;
+
+public class OverdueWrapperFactory {
+
+    private final CatalogService catalogService;
+    private final BillingStateCalculatorBundle billingStateCalcuatorBundle;
+    private final OverdueStateApplicatorBundle overdueStateApplicatorBundle;
+    private final OverdueDao dao;
+    private final Clock clock;
+
+    @Inject
+    public OverdueWrapperFactory(OverdueDao dao, CatalogService catalogService, Clock clock, BillingStateCalculatorBundle billingStateCalcuatorBundle, OverdueStateApplicatorBundle overdueStateApplicatorBundle) {
+        this.billingStateCalcuatorBundle = billingStateCalcuatorBundle;
+        this.overdueStateApplicatorBundle = overdueStateApplicatorBundle;
+        this.catalogService = catalogService;
+        this.dao = dao;
+        this.clock = clock;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public <T extends Overdueable> OverdueWrapper<T> createOverdueWrapperFor(T overdueable) throws OverdueError {
+        try {
+            if(overdueable instanceof SubscriptionBundle) {
+                return (OverdueWrapper<T>)new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle)overdueable, dao, catalogService.getCurrentCatalog().currentBundleOverdueStateSet(), 
+                        clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle );
+            } else {
+                throw new OverdueError(ErrorCode.OVERDUE_OVERDUEABLE_NOT_SUPPORTED, overdueable.getClass());
+            }
+
+        } catch (CatalogApiException e) {
+            throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, overdueable.getId().toString(), overdueable.getClass().toString());
+        }
+    }
+
+
+}