killbill-aplcache

Changes

bin/db-helper 2(+2 -0)

bin/start-server 33(+33 -0)

jaxrs/pom.xml 97(+97 -0)

pom.xml 35(+31 -4)

server/pom.xml 470(+470 -0)

Details

bin/db-helper 2(+2 -0)

diff --git a/bin/db-helper b/bin/db-helper
new file mode 100644
index 0000000..3134267
--- /dev/null
+++ b/bin/db-helper
@@ -0,0 +1,2 @@
+#!/bin/bash -eu
+

bin/start-server 33(+33 -0)

diff --git a/bin/start-server b/bin/start-server
new file mode 100755
index 0000000..8b87f3d
--- /dev/null
+++ b/bin/start-server
@@ -0,0 +1,33 @@
+#! /usr/bin/env bash
+
+HERE=`cd \`dirname $0\`; pwd`
+TOP=$HERE/..
+SERVER=$TOP/server
+
+PROPERTIES="$SERVER/src/main/resources/killbill-server.properties"
+
+#DEBUG_OPTS_ECLIPSE=
+DEBUG_OPTS_ECLIPSE=" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=12345 "
+OPTS_ECLIPSE=" -Xmx2048m  -XX:+UseConcMarkSweepGC -XX:MaxPermSize=128m  "
+
+LOG="$SERVER/src/main/resources/log4j.xml"
+
+PORT=8080
+
+OPTS=
+for PROP in `cat  $PROPERTIES | grep =`; do
+    K=`echo $PROP | awk '  BEGIN {FS="="} { print $1 }'`
+    V=`echo $PROP | awk 'BEGIN {FS="="} { print $2 }'`
+    OPTS="$OPTS -D$K=$V"
+done
+
+
+START_CMD="mvn $OPTS -Dlog4j.configuration=file://$LOG -Dning.jmx.http.port=$PORT -Dxn.host.external.port=$PORT -DjettyPort=$PORT -Dxn.server.port=$PORT jetty:run"
+
+echo "Starting IRS:"
+echo "$START_CMD"
+
+export MAVEN_OPTS=" -Duser.timezone=UTC $OPTS_ECLIPSE $DEBUG_OPTS_ECLIPSE"
+
+cd $SERVER
+$START_CMD

jaxrs/pom.xml 97(+97 -0)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
new file mode 100644
index 0000000..0701aa2
--- /dev/null
+++ b/jaxrs/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ning.billing</groupId>
+        <artifactId>killbill</artifactId>
+        <version>0.1.8-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>killbill-jaxrs</artifactId>
+    <name>killbill-jaxrs</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+            <!-- WHY DO WE NEED VESRION HERE ?? -->
+            <version>1.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
new file mode 100644
index 0000000..da10dab
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
@@ -0,0 +1,234 @@
+/*
+ * 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.jaxrs.json;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountData;
+import com.ning.billing.catalog.api.Currency;
+
+public class AccountJson {
+
+    // Missing city, locale, postalCode from https://home.ninginc.com:8443/display/REVINFRA/Killbill+1.0+APIs
+
+    private final String acountId;
+    private final String name;
+    private final Integer length;
+    private final String externalKey;
+    private final String email;
+    private final Integer billCycleDay;
+    private final String currency;
+    private final String paymentProvider;
+    private final String timeZone;
+    private final String address1;
+    private final String address2;
+    private final String company;
+    private final String state;
+    private final String country;
+    private final String phone;
+
+
+    public AccountJson(Account account) {
+        this.acountId = account.getId().toString();
+        this.name = account.getName();
+        this.length = account.getFirstNameLength();
+        this.externalKey = account.getExternalKey();
+        this.email = account.getEmail();
+        this.billCycleDay = account.getBillCycleDay();
+        this.currency = account.getCurrency().toString();
+        this.paymentProvider = account.getPaymentProviderName();
+        this.timeZone = account.getTimeZone().toString();
+        this.address1 = account.getAddress1();
+        this.address2 = account.getAddress2();
+        this.company = account.getCompanyName();
+        this.state = account.getStateOrProvince();
+        this.country = account.getCountry();
+        this.phone = account.getPhone();
+    }
+
+    public AccountData toAccountData() {
+        return new AccountData() {
+            @Override
+            public DateTimeZone getTimeZone() {
+                return (timeZone != null) ? DateTimeZone.forID(timeZone) : null;
+            }
+            @Override
+            public String getStateOrProvince() {
+                return state;
+            }
+            @Override
+            public String getPostalCode() {
+                return null;
+            }
+            @Override
+            public String getPhone() {
+                return phone;
+            }
+            @Override
+            public String getPaymentProviderName() {
+                return paymentProvider;
+            }
+            @Override
+            public String getName() {
+                return name;
+            }
+            @Override
+            public String getLocale() {
+                return null;
+            }
+            @Override
+            public int getFirstNameLength() {
+                return length;
+            }
+            @Override
+            public String getExternalKey() {
+                return externalKey;
+            }
+            @Override
+            public String getEmail() {
+                return email;
+            }
+            @Override
+            public Currency getCurrency() {
+                Currency result =  (currency != null) ? Currency.valueOf(currency) : Currency.USD;
+                return result;
+            }
+            @Override
+            public String getCountry() {
+                return country;
+            }
+            @Override
+            public String getCompanyName() {
+                return company;
+            }
+            @Override
+            public String getCity() {
+                return null;
+            }
+            @Override
+            public int getBillCycleDay() {
+                return billCycleDay;
+            }
+            @Override
+            public String getAddress2() {
+                return address2;
+            }
+            @Override
+            public String getAddress1() {
+                return address1;
+            }
+        };
+    }
+
+
+    @JsonCreator
+    public AccountJson(@JsonProperty("account_id") String acountId,
+            @JsonProperty("name") String name,
+            @JsonProperty("first_name_length") Integer length,
+            @JsonProperty("external_key") String externalKey,
+            @JsonProperty("email") String email,
+            @JsonProperty("billing_day") Integer billCycleDay,
+            @JsonProperty("currency") String currency,
+            @JsonProperty("payment_provider") String paymentProvider,
+            @JsonProperty("timezone") String timeZone,
+            @JsonProperty("address1") String address1,
+            @JsonProperty("address2") String address2,
+            @JsonProperty("company") String company,
+            @JsonProperty("state") String state,
+            @JsonProperty("country") String country,
+            @JsonProperty("phone") String phone) {
+        super();
+        this.acountId = acountId;
+        this.name = name;
+        this.length = length;
+        this.externalKey = externalKey;
+        this.email = email;
+        this.billCycleDay = billCycleDay;
+        this.currency = currency;
+        this.paymentProvider = paymentProvider;
+        this.timeZone = timeZone;
+        this.address1 = address1;
+        this.address2 = address2;
+        this.company = company;
+        this.state = state;
+        this.country = country;
+        this.phone = phone;
+    }
+
+    public String getAcountId() {
+        return acountId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getLength() {
+        return length;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public Integer getBillCycleDay() {
+        return billCycleDay;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public String getPaymentProvider() {
+        return paymentProvider;
+    }
+
+    public String getTimeZone() {
+        return timeZone;
+    }
+
+    public String getAddress1() {
+        return address1;
+    }
+
+    public String getAddress2() {
+        return address2;
+    }
+
+    public String getCompany() {
+        return company;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+ }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJson.java
new file mode 100644
index 0000000..226c365
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJson.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jaxrs.json;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonView;
+
+public class BundleJson {
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String bundleId;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String accountId;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String externalKey;
+
+    @JsonView(BundleTimelineViews.Timeline.class)
+    private final List<SubscriptionJson> subscriptions;
+
+    @JsonCreator
+    public BundleJson(@JsonProperty("bundle_id") String bundleId,
+            @JsonProperty("account_id") String accountId,
+            @JsonProperty("external_key") String externalKey,
+            @JsonProperty("subscriptions") List<SubscriptionJson> subscriptions) {
+        super();
+        this.bundleId = bundleId;
+        this.accountId = accountId;
+        this.externalKey = externalKey;
+        this.subscriptions = subscriptions;
+    }
+
+    public String getBundleId() {
+        return bundleId;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public List<SubscriptionJson> getSubscriptions() {
+        return subscriptions;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java
new file mode 100644
index 0000000..61761a7
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java
@@ -0,0 +1,74 @@
+/*
+ * 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.jaxrs.json;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonView;
+
+public class BundleTimelineJson {
+
+    @JsonView(BundleTimelineViews.Timeline.class)
+    private final String viewId;
+
+    @JsonView(BundleTimelineViews.Timeline.class)
+    private final BundleJson bundle;
+
+    @JsonView(BundleTimelineViews.ReadTimeline.class)
+    private final List<PaymentJson> payments;
+
+    @JsonView(BundleTimelineViews.ReadTimeline.class)
+    private final List<InvoiceJson> invoices;
+
+    @JsonView(BundleTimelineViews.WriteTimeline.class)
+    private final String resonForChange;
+
+    @JsonCreator
+    public BundleTimelineJson(@JsonProperty("view_id") String viewId,
+            @JsonProperty("bundle") BundleJson bundle,
+            @JsonProperty("payments") List<PaymentJson> payments,
+            @JsonProperty("invoices") List<InvoiceJson> invoices,
+            @JsonProperty("reason_for_change") String reason) {
+        this.viewId = viewId;
+        this.bundle = bundle;
+        this.payments = payments;
+        this.invoices = invoices;
+        this.resonForChange = reason;
+    }
+
+    public String getViewId() {
+        return viewId;
+    }
+
+    public BundleJson getBundle() {
+        return bundle;
+    }
+
+    public List<PaymentJson> getPayments() {
+        return payments;
+    }
+
+    public List<InvoiceJson> getInvoices() {
+        return invoices;
+    }
+
+    public String getResonForChange() {
+        return resonForChange;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineViews.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineViews.java
new file mode 100644
index 0000000..020764e
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineViews.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.jaxrs.json;
+
+
+public class BundleTimelineViews {
+    static class Base {};
+    static class Timeline extends Base {};
+    static class ReadTimeline extends Timeline {};
+    static class WriteTimeline extends Timeline {};
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
new file mode 100644
index 0000000..b13bdee
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.joda.time.DateTime;
+
+public class InvoiceJson {
+
+    private final BigDecimal amount;
+    private final String invoiceId;
+    private final DateTime requestedDate;
+    private final String invoiceNumber;
+    private final BigDecimal balance;
+
+    @JsonCreator
+    public InvoiceJson(@JsonProperty("amount") BigDecimal amount,
+            @JsonProperty("invoice_id") String invoiceId,
+            @JsonProperty("requested_dt") DateTime requestedDate,
+            @JsonProperty("invoice_number") String invoiceNumber,
+            @JsonProperty("balance") BigDecimal balance) {
+        super();
+        this.amount = amount;
+        this.invoiceId = invoiceId;
+        this.requestedDate = requestedDate;
+        this.invoiceNumber = invoiceNumber;
+        this.balance = balance;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public String getInvoiceId() {
+        return invoiceId;
+    }
+
+    public DateTime getRequestedDate() {
+        return requestedDate;
+    }
+
+    public String getInvoiceNumber() {
+        return invoiceNumber;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java
new file mode 100644
index 0000000..1f932d4
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java
@@ -0,0 +1,75 @@
+/*
+ * 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.joda.time.DateTime;
+
+import com.ning.billing.util.clock.DefaultClock;
+
+public class PaymentJson {
+
+    private final BigDecimal paidAmount;
+    private final String invoiceId;
+    private final String paymentId;
+    private final DateTime requestedDate;
+    private final DateTime effectiveDate;
+    private final String status;
+
+    @JsonCreator
+    public PaymentJson(@JsonProperty("paid_amount") BigDecimal paidAmount,
+            @JsonProperty("invoice_id") String invoiceId,
+            @JsonProperty("payment_id") String paymentId,
+            @JsonProperty("requested_dt") DateTime requestedDate,
+            @JsonProperty("effective_dt") DateTime effectiveDate,
+            @JsonProperty("status") String status) {
+        super();
+        this.paidAmount = paidAmount;
+        this.invoiceId = invoiceId;
+        this.paymentId = paymentId;
+        this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
+        this.effectiveDate = DefaultClock.toUTCDateTime(effectiveDate);
+        this.status = status;
+    }
+
+    public BigDecimal getPaidAmount() {
+        return paidAmount;
+    }
+
+    public String getInvoiceId() {
+        return invoiceId;
+    }
+
+    public String getPaymentId() {
+        return paymentId;
+    }
+
+    public DateTime getRequestedDate() {
+        return DefaultClock.toUTCDateTime(requestedDate);
+    }
+
+    public DateTime getEffectiveDate() {
+        return DefaultClock.toUTCDateTime(effectiveDate);
+    }
+
+    public String getStatus() {
+        return status;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJson.java
new file mode 100644
index 0000000..a08a305
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJson.java
@@ -0,0 +1,272 @@
+/*
+ * 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.jaxrs.json;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonView;
+import org.joda.time.DateTime;
+
+import com.ning.billing.util.clock.DefaultClock;
+
+public class SubscriptionJson {
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String subscriptionId;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String bundleId;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String productName;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String productCategory;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String billingPeriod;
+
+    @JsonView(BundleTimelineViews.Base.class)
+    private final String priceList;
+
+    @JsonView(BundleTimelineViews.ReadTimeline.class)
+    private final List<SubscriptionReadEventJson> events;
+
+    @JsonView(BundleTimelineViews.WriteTimeline.class)
+    private final List<SubscriptionDeletedEventJson> deletedEvents;
+
+    @JsonView(BundleTimelineViews.WriteTimeline.class)
+    private final List<SubscriptionNewEventJson> newEvents;
+
+
+    public static class SubscriptionReadEventJson extends SubscriptionBaseEventJson {
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String eventId;
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final DateTime effectiveDate;
+
+        @JsonCreator
+        public SubscriptionReadEventJson(@JsonProperty("event_id") String eventId,
+                @JsonProperty("billing_period") String billingPeriod,
+                @JsonProperty("requested_dt") DateTime requestedDate,
+                @JsonProperty("effective_dt") DateTime effectiveDate,
+                @JsonProperty("product") String product,
+                @JsonProperty("price_list") String priceList,
+                @JsonProperty("event_type") String eventType,
+                @JsonProperty("phase") String phase) {
+            super(billingPeriod, requestedDate, product, priceList, eventType, phase);
+            this.eventId = eventId;
+            this.effectiveDate = effectiveDate;
+        }
+
+        public String getEventId() {
+            return eventId;
+        }
+
+        public DateTime getEffectiveDate() {
+            return DefaultClock.toUTCDateTime(effectiveDate);
+        }
+
+        @Override
+        public String toString() {
+            return "SubscriptionReadEventJson [eventId=" + eventId
+                    + ", effectiveDate=" + effectiveDate
+                    + ", getBillingPeriod()=" + getBillingPeriod()
+                    + ", getRequestedDate()=" + getRequestedDate()
+                    + ", getProduct()=" + getProduct() + ", getPriceList()="
+                    + getPriceList() + ", getEventType()=" + getEventType()
+                    + ", getPhase()=" + getPhase() + ", getClass()="
+                    + getClass() + ", hashCode()=" + hashCode()
+                    + ", toString()=" + super.toString() + "]";
+        }
+    }
+
+    public static class SubscriptionDeletedEventJson extends SubscriptionReadEventJson {
+        @JsonCreator
+        public SubscriptionDeletedEventJson(@JsonProperty("event_id") String eventId,
+                @JsonProperty("billing_period") String billingPeriod,
+                @JsonProperty("requested_dt") DateTime requestedDate,
+                @JsonProperty("effective_dt") DateTime effectiveDate,
+                @JsonProperty("product") String product,
+                @JsonProperty("price_list") String priceList,
+                @JsonProperty("event_type") String eventType,
+                @JsonProperty("phase") String phase) {
+            super(eventId, billingPeriod, requestedDate, effectiveDate, product, priceList, eventType, phase);
+
+        }
+    }
+
+
+    public static class SubscriptionNewEventJson extends SubscriptionBaseEventJson {
+        @JsonCreator
+        public SubscriptionNewEventJson(@JsonProperty("billing_period") String billingPeriod,
+                @JsonProperty("requested_dt") DateTime requestedDate,
+                @JsonProperty("product") String product,
+                @JsonProperty("price_list") String priceList,
+                @JsonProperty("event_type") String eventType,
+                @JsonProperty("phase") String phase) {
+            super(billingPeriod, requestedDate, product, priceList, eventType, phase);
+        }
+
+        @Override
+        public String toString() {
+            return "SubscriptionNewEventJson [getBillingPeriod()="
+                    + getBillingPeriod() + ", getRequestedDate()="
+                    + getRequestedDate() + ", getProduct()=" + getProduct()
+                    + ", getPriceList()=" + getPriceList()
+                    + ", getEventType()=" + getEventType() + ", getPhase()="
+                    + getPhase() + ", getClass()=" + getClass()
+                    + ", hashCode()=" + hashCode() + ", toString()="
+                    + super.toString() + "]";
+        }
+    }
+
+    public static class SubscriptionBaseEventJson {
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String billingPeriod;
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final DateTime requestedDate;
+
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String product;
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String priceList;
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String eventType;
+
+        @JsonView(BundleTimelineViews.Timeline.class)
+        private final String phase;
+
+        @JsonCreator
+        public SubscriptionBaseEventJson(@JsonProperty("billing_period") String billingPeriod,
+                @JsonProperty("requested_dt") DateTime requestedDate,
+                @JsonProperty("product") String product,
+                @JsonProperty("price_list") String priceList,
+                @JsonProperty("event_type") String eventType,
+                @JsonProperty("phase") String phase) {
+            super();
+            this.billingPeriod = billingPeriod;
+            this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
+            this.product = product;
+            this.priceList = priceList;
+            this.eventType = eventType;
+            this.phase = phase;
+        }
+
+        public String getBillingPeriod() {
+            return billingPeriod;
+        }
+
+        public DateTime getRequestedDate() {
+            return DefaultClock.toUTCDateTime(requestedDate);
+        }
+
+        public String getProduct() {
+            return product;
+        }
+
+        public String getPriceList() {
+            return priceList;
+        }
+
+        public String getEventType() {
+            return eventType;
+        }
+
+        public String getPhase() {
+            return phase;
+        }
+    }
+
+
+    @JsonCreator
+    public SubscriptionJson(@JsonProperty("subscription_id") String subscriptionId,
+            @JsonProperty("bundle_id") String bundleId,
+            @JsonProperty("product_name") String productName,
+            @JsonProperty("product_category") String productCategory,
+            @JsonProperty("billing_period") String billingPeriod,
+            @JsonProperty("price_list") String priceList,
+            @JsonProperty("events") List<SubscriptionReadEventJson> events,
+            @JsonProperty("new_events") List<SubscriptionNewEventJson> newEvents,
+            @JsonProperty("deleted_events") List<SubscriptionDeletedEventJson> deletedEvents) {
+        super();
+        this.subscriptionId = subscriptionId;
+        this.bundleId = bundleId;
+        this.productName = productName;
+        this.productCategory = productCategory;
+        this.billingPeriod = billingPeriod;
+        this.priceList = priceList;
+        this.events = events;
+        this.deletedEvents = deletedEvents;
+        this.newEvents = newEvents;
+    }
+
+    public String getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    public String getBundleId() {
+        return bundleId;
+    }
+
+    public String getProductName() {
+        return productName;
+    }
+
+    public String getProductCategory() {
+        return productCategory;
+    }
+
+    public String getBillingPeriod() {
+        return billingPeriod;
+    }
+
+    public String getPriceList() {
+        return priceList;
+    }
+
+    public List<SubscriptionReadEventJson> getEvents() {
+        return events;
+    }
+
+    public List<SubscriptionNewEventJson> getNewEvents() {
+        return newEvents;
+    }
+
+    public List<SubscriptionDeletedEventJson> getDeletedEvents() {
+        return deletedEvents;
+    }
+
+    @Override
+    public String toString() {
+        return "SubscriptionJson [subscriptionId=" + subscriptionId
+                + ", bundleId=" + bundleId + ", productName=" + productName
+                + ", productCategory=" + productCategory + ", billingPeriod="
+                + billingPeriod + ", priceList=" + priceList + ", events="
+                + events + ", deletedEvents=" + deletedEvents + ", newEvents="
+                + newEvents + "]";
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
new file mode 100644
index 0000000..d34d0ac
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -0,0 +1,140 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.net.URI;
+import java.util.UUID;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.Response.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountData;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.jaxrs.json.AccountJson;
+
+
+@Singleton
+@Path("/1.0/account")
+public class AccountResource {
+
+    private static final Logger log = LoggerFactory.getLogger(AccountResource.class);
+
+    private final AccountUserApi accountApi;
+
+    @Inject
+    public AccountResource(AccountUserApi accountApi) {
+        this.accountApi = accountApi;
+    }
+
+    @GET
+    @Path("/{accountId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getAccount(@PathParam("accountId") String accountId) {
+        Account account = accountApi.getAccountById(UUID.fromString(accountId));
+        if (account == null) {
+            return Response.status(Status.NOT_FOUND).build();
+        }
+        AccountJson json = new AccountJson(account);
+        return Response.status(Status.OK).entity(json).build();
+    }
+
+    @GET
+    @Produces(APPLICATION_JSON)
+    public Response getAccountByKey(@QueryParam("externalKey") String externalKey) {
+        Account account = null;
+        if (externalKey != null) {
+            account = accountApi.getAccountByKey(externalKey);
+        }
+        if (account == null) {
+            return Response.status(Status.NOT_FOUND).build();
+        }
+        AccountJson json = new AccountJson(account);
+        return Response.status(Status.OK).entity(json).build();
+    }
+
+    @POST
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createAccount(AccountJson json) {
+
+        try {
+            AccountData data = json.toAccountData();
+            final Account account = accountApi.createAccount(data, null, null);
+            URI uri = UriBuilder.fromPath(account.getId().toString()).build();
+            Response.ResponseBuilder ri = Response.created(uri);
+            return ri.entity(new Object() {
+                public URI getUri() {
+                    return UriBuilder.fromResource(AccountResource.class).path(AccountResource.class, "getAccount").build(account.getId());
+                }
+            }).build();
+        } catch (AccountApiException e) {
+            log.info(String.format("Failed to create account %s", json), e);
+            return Response.status(Status.BAD_REQUEST).build();
+        }
+    }
+
+    @PUT
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    @Path("/{accountId:\\w+}")
+    public Response updateAccount(AccountJson json, @PathParam("accountId") String accountId) {
+        try {
+            AccountData data = json.toAccountData();
+            accountApi.updateAccount(accountId, data);
+            return Response.status(Status.NO_CONTENT).build();
+        } catch (AccountApiException e) {
+            log.info(String.format("Failed to update account %s with %s", accountId, json), e);
+            return Response.status(Status.BAD_REQUEST).build();
+        }
+    }
+
+    // Not supported
+    @DELETE
+    @Path("/{accountId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response cancelAccount(@PathParam("accountId") String accountId) {
+        /*
+        try {
+            accountApi.cancelAccount(accountId);
+            return Response.status(Status.NO_CONTENT).build();
+        } catch (AccountApiException e) {
+            log.info(String.format("Failed to cancel account %s", accountId), e);
+            return Response.status(Status.BAD_REQUEST).build();
+        }
+       */
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountTimeline.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountTimeline.java
new file mode 100644
index 0000000..e154f85
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountTimeline.java
@@ -0,0 +1,21 @@
+/*
+ * 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.jaxrs.resources;
+
+public class AccountTimeline {
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
new file mode 100644
index 0000000..07a7517
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -0,0 +1,56 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.ning.billing.jaxrs.json.BundleJson;
+
+@Path("/1.0/bundle")
+public class BundleResource {
+
+    @GET
+    @Path("/{bundleId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getBundle(@PathParam("bundleId") String bundleId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @GET
+    @Produces(APPLICATION_JSON)
+    public Response getBundleByKey(@QueryParam("externalKey") String externalKey) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @POST
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createBundle(BundleJson bundle) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleTimelineResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleTimelineResource.java
new file mode 100644
index 0000000..93a1f23
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleTimelineResource.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+
+@Path("/1.0/timeline/bundle")
+public class BundleTimelineResource {
+
+    @GET
+    @Path("/{bundleId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getBundleTimeline(@PathParam("bundleId") String bundleId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @POST
+    @Produces(APPLICATION_JSON)
+    @Consumes(APPLICATION_JSON)
+    @Path("/{bundleId:\\w+}/repair")
+     public Response repairBundleTineline(BundleTimelineResource bundle,
+             @PathParam("bundleId") String bundleId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargedbackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargedbackResource.java
new file mode 100644
index 0000000..5d3168b
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargedbackResource.java
@@ -0,0 +1,21 @@
+/*
+ * 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.jaxrs.resources;
+
+public class ChargedbackResource {
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
new file mode 100644
index 0000000..076dbff
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -0,0 +1,21 @@
+/*
+ * 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.jaxrs.resources;
+
+public class CreditResource {
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
new file mode 100644
index 0000000..1db336e
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.ning.billing.jaxrs.json.InvoiceJson;
+
+
+
+@Path("/1.0/invoice")
+public class InvoiceResource {
+
+
+    @GET
+    @Produces(APPLICATION_JSON)
+    public Response getInvoices(@QueryParam("accountId") String accountId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @GET
+    @Path("/{invoiceId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getInvoice(@PathParam("invoiceId") String accountId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @POST
+    @Path("/{accountId:\\w+}")
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createFutureInvoice(InvoiceJson invoice,
+            @PathParam("accountId") String accountId,
+            @QueryParam("targetDate") String targetDate) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
new file mode 100644
index 0000000..f68874d
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.ning.billing.jaxrs.json.PaymentJson;
+
+
+@Path("/1.0/payment")
+public class PaymentResource {
+
+
+    @GET
+    @Path("/{invoiceId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getPayments(@PathParam("invoiceId") String invoiceId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @GET
+    @Path("/account/{accountId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getAllPayments(@PathParam("accountId") String accountId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @POST
+    @Produces(APPLICATION_JSON)
+    @Consumes(APPLICATION_JSON)
+    @Path("/{invoiceId:\\w+}")
+    public Response createInstantPayment(PaymentJson payment,
+            @PathParam("invoiceId") String invoiceId,
+            @QueryParam("last4CC") String last4CC,
+            @QueryParam("nameOnCC") String nameOnCC) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
new file mode 100644
index 0000000..05acf58
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
@@ -0,0 +1,21 @@
+/*
+ * 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.jaxrs.resources;
+
+public class RefundResource {
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
new file mode 100644
index 0000000..ee3c200
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -0,0 +1,80 @@
+/*
+ * 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.jaxrs.resources;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
+import com.ning.billing.jaxrs.json.SubscriptionJson;
+
+@Path("/1.0/subscription")
+public class SubscriptionResource {
+
+    @GET
+    @Path("/{subscriptionId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response getSubscription(@PathParam("subscriptionId") String subscriptionId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @POST
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createSubscription(SubscriptionJson subscription,
+            @QueryParam("requestedDate") String requestedDate) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @PUT
+    @Produces(APPLICATION_JSON)
+    @Consumes(APPLICATION_JSON)
+    @Path("/{subscriptionId:\\w+}")
+    public Response changeSubscriptionPlan(SubscriptionJson subscription,
+            @PathParam("subscriptionId") String subscriptionId,
+            @QueryParam("requestedDate") String requestedDate) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @PUT
+    @Path("/{subscriptionId:\\w+}/uncancel")
+    @Produces(APPLICATION_JSON)
+    public Response uncancelSubscriptionPlan(@PathParam("subscriptionId") String subscriptionId) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+
+    @DELETE
+    @Path("/{subscriptionId:\\w+}")
+    @Produces(APPLICATION_JSON)
+    public Response cancelSubscriptionPlan(@PathParam("subscriptionId") String subscriptionId,
+            @QueryParam("requestedDate") String requestedDate) {
+        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
new file mode 100644
index 0000000..cc19095
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -0,0 +1,21 @@
+/*
+ * 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.jaxrs.resources;
+
+public class TagResource {
+
+}
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestJsonViews.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestJsonViews.java
new file mode 100644
index 0000000..7e28130
--- /dev/null
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestJsonViews.java
@@ -0,0 +1,340 @@
+/*
+ * 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.jaxrs.json;
+
+import java.io.StringWriter;
+import java.io.Writer;
+import java.math.BigDecimal;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.ObjectWriter;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.json.SubscriptionJson.SubscriptionDeletedEventJson;
+import com.ning.billing.jaxrs.json.SubscriptionJson.SubscriptionNewEventJson;
+import com.ning.billing.jaxrs.json.SubscriptionJson.SubscriptionReadEventJson;
+
+public class TestJsonViews {
+
+
+    public static final Logger log = LoggerFactory.getLogger(TestJsonViews.class);
+
+    private ObjectMapper objectMapper;
+
+    @BeforeClass(groups="fast")
+    public void setup() {
+        objectMapper = new ObjectMapper().configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
+        objectMapper.disable(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS);
+    }
+
+
+
+    @Test(groups="fast")
+    public void testSubscriptionBaseView() {
+        testSubscriptionView(BundleTimelineViews.Base.class);
+    }
+
+    @Test(groups="fast")
+    public void testSubscriptionTimelineView() {
+        testSubscriptionView(BundleTimelineViews.ReadTimeline.class);
+    }
+
+    private void testSubscriptionView(Class<? extends BundleTimelineViews.Base> viewClass) {
+        try {
+
+            SubscriptionJson obj = buildSubscriptionReadEventJson();
+
+            ObjectWriter objWriter = objectMapper.writerWithView(viewClass);
+
+            Writer writer = new StringWriter();
+            objWriter.writeValue(writer, obj);
+            String baseJson = writer.toString();
+
+            log.info(baseJson);
+
+            SubscriptionJson objFromJson = objectMapper.readValue(baseJson, SubscriptionJson.class);
+
+            log.info(objFromJson.toString());
+
+            if (viewClass.equals(BundleTimelineViews.Base.class)) {
+                Assert.assertNull(objFromJson.getEvents());
+            } else {
+                Assert.assertNotNull(objFromJson.getEvents());
+            }
+
+            writer = new StringWriter();
+            objWriter.writeValue(writer, objFromJson);
+            String newBaseJson = writer.toString();
+
+            Assert.assertEquals(newBaseJson, baseJson);
+
+        } catch (Exception e) {
+            Assert.fail(e.getMessage());
+        }
+    }
+
+    @Test(groups="fast")
+    public void testBundleReadTimelineJson() {
+        testBundleTimelineJson(BundleTimelineViews.ReadTimeline.class);
+    }
+
+    @Test(groups="fast")
+    public void testBundleWriteTimelineJson() {
+        testBundleTimelineJson(BundleTimelineViews.WriteTimeline.class);
+    }
+
+    private void testBundleTimelineJson(Class<? extends BundleTimelineViews.Base> viewClass) {
+
+        final boolean readTimeline = viewClass.equals(BundleTimelineViews.ReadTimeline.class);
+        try {
+
+            BundleTimelineJson obj = buildBundleTimelineJson(readTimeline);
+
+            ObjectWriter objWriter = objectMapper.writerWithView(viewClass);
+
+            Writer writer = new StringWriter();
+            objWriter.writeValue(writer, obj);
+            String baseJson = writer.toString();
+
+            log.info(baseJson);
+
+            BundleTimelineJson objFromJson = objectMapper.readValue(baseJson, BundleTimelineJson.class);
+
+            log.info(objFromJson.toString());
+
+            Assert.assertNotNull(objFromJson.getViewId());
+            Assert.assertNotNull(objFromJson.getBundle());
+
+            BundleJson bundle = objFromJson.getBundle();
+            Assert.assertNotNull(bundle.getBundleId());
+            Assert.assertNotNull(bundle.getAccountId());
+            Assert.assertNotNull(bundle.getExternalKey());
+            Assert.assertNotNull(bundle.getSubscriptions());
+
+            List<SubscriptionJson> subscriptions = bundle.getSubscriptions();
+            Assert.assertEquals(subscriptions.size(), 1);
+            SubscriptionJson sub = subscriptions.get(0);
+            Assert.assertNotNull(sub.getBundleId());
+            Assert.assertNotNull(sub.getBillingPeriod());
+            Assert.assertNotNull(sub.getPriceList());
+            Assert.assertNotNull(sub.getProductCategory());
+            Assert.assertNotNull(sub.getProductName());
+            Assert.assertNotNull(sub.getSubscriptionId());
+
+            List<SubscriptionReadEventJson> events = sub.getEvents();
+            List<SubscriptionDeletedEventJson> deletedEvents = sub.getDeletedEvents();
+            List<SubscriptionNewEventJson> newEvents = sub.getNewEvents();
+
+            if (viewClass.equals(BundleTimelineViews.WriteTimeline.class)) {
+                Assert.assertNull(objFromJson.getPayments());
+                Assert.assertNull(objFromJson.getInvoices());
+                Assert.assertNull(objFromJson.getInvoices());
+
+                Assert.assertNull(events);
+                Assert.assertEquals(newEvents.size(), 1);
+                for (SubscriptionNewEventJson cur : newEvents) {
+                    Assert.assertNotNull(cur.getRequestedDate());
+                    Assert.assertNotNull(cur.getEventType());
+                    Assert.assertNotNull(cur.getBillingPeriod());
+                    Assert.assertNotNull(cur.getPhase());
+                    Assert.assertNotNull(cur.getPriceList());
+                    Assert.assertNotNull(cur.getProduct());
+                }
+
+
+                Assert.assertEquals(deletedEvents.size(), 1);
+                for (SubscriptionDeletedEventJson cur : deletedEvents) {
+                    Assert.assertNotNull(cur.getEventId());
+                    Assert.assertNotNull(cur.getEffectiveDate());
+                    Assert.assertNotNull(cur.getRequestedDate());
+                    Assert.assertNotNull(cur.getEventType());
+                    Assert.assertNotNull(cur.getBillingPeriod());
+                    Assert.assertNotNull(cur.getPhase());
+                    Assert.assertNotNull(cur.getPriceList());
+                    Assert.assertNotNull(cur.getProduct());
+                }
+
+
+                Assert.assertNotNull(objFromJson.getResonForChange());
+
+            } else if (viewClass.equals(BundleTimelineViews.ReadTimeline.class)) {
+                Assert.assertNotNull(objFromJson.getPayments());
+                Assert.assertNotNull(objFromJson.getInvoices());
+                Assert.assertNotNull(objFromJson.getInvoices());
+
+                Assert.assertNull(newEvents);
+                Assert.assertNull(deletedEvents);
+                Assert.assertEquals(events.size(), 2);
+                for (SubscriptionReadEventJson cur : events) {
+                    Assert.assertNotNull(cur.getEventId());
+                    Assert.assertNotNull(cur.getEffectiveDate());
+                    Assert.assertNotNull(cur.getRequestedDate());
+                    Assert.assertNotNull(cur.getEventType());
+                    Assert.assertNotNull(cur.getBillingPeriod());
+                    Assert.assertNotNull(cur.getPhase());
+                    Assert.assertNotNull(cur.getPriceList());
+                    Assert.assertNotNull(cur.getProduct());
+                }
+
+                Assert.assertNull(objFromJson.getResonForChange());
+            } else {
+                Assert.fail("View of no interest");
+            }
+
+            writer = new StringWriter();
+            objWriter.writeValue(writer, objFromJson);
+            String newBaseJson = writer.toString();
+
+            Assert.assertEquals(newBaseJson, baseJson);
+
+        } catch (Exception e) {
+            Assert.fail(e.getMessage());
+        }
+
+    }
+
+    private BundleTimelineJson buildBundleTimelineJson(boolean readTimeline) {
+
+        final String reason = "whatever";
+        final String viewId = "view-123356";
+        final BundleJson bundle = buildBundle(readTimeline);
+        final List<PaymentJson> payments = new LinkedList<PaymentJson>();
+        payments.add(buildPaymentJson());
+
+        final List<InvoiceJson> invoices = new LinkedList<InvoiceJson>();
+        invoices.add(buildInvoiceJson());
+        return new BundleTimelineJson(viewId, bundle, payments, invoices, reason);
+    }
+
+
+    private BundleJson buildBundle(boolean readTimeline) {
+        final String bundleId = UUID.randomUUID().toString();
+        final String accountId = UUID.randomUUID().toString();
+        final String externalKey = "bozo-the-sioux";
+        final List<SubscriptionJson> subscriptions = new LinkedList<SubscriptionJson>();
+        subscriptions.add(readTimeline ? buildSubscriptionReadEventJson() : buildSubscriptionWriteEventJson());
+        return new BundleJson(bundleId, accountId, externalKey, subscriptions);
+    }
+    private PaymentJson buildPaymentJson() {
+
+        final BigDecimal paidAmount = new BigDecimal(128.56);
+        final String invoiceId = UUID.randomUUID().toString();
+        final String paymentId = UUID.randomUUID().toString();
+        final DateTime requestedDate =  new DateTime();
+        final DateTime effectiveDate = requestedDate;
+        final String status = "Success";
+        return new PaymentJson(paidAmount, invoiceId, paymentId, requestedDate, effectiveDate, status);
+    }
+
+    private InvoiceJson buildInvoiceJson() {
+        final BigDecimal amount = new BigDecimal(128.56);
+        final BigDecimal balance = new BigDecimal(0.0);
+        final String invoiceId = UUID.randomUUID().toString();
+        final String invoiceNumber =  "INV-00012";
+        final DateTime requestedDate =  new DateTime();
+        return new InvoiceJson(amount, invoiceId, requestedDate, invoiceNumber, balance);
+    }
+
+    private SubscriptionJson buildSubscriptionReadEventJson() {
+
+        final List<SubscriptionReadEventJson> events = new LinkedList<SubscriptionReadEventJson>();
+
+        final String eventId1 = UUID.randomUUID().toString();
+        final String productName1 = "gold";
+        final String billingPeriod1 = "monthly";
+        final DateTime requestedDate1 =  new DateTime();
+        final DateTime effectiveDate1 = requestedDate1;
+        final String priceList1 = "default";
+        final String eventType1 = "CREATE";
+        final String phase1 = "TRIAL";
+        SubscriptionReadEventJson ev1 = new SubscriptionReadEventJson(eventId1, billingPeriod1, requestedDate1, effectiveDate1, productName1, priceList1, eventType1, phase1);
+        events.add(ev1);
+
+        final String eventId2 = UUID.randomUUID().toString();
+        final String productName2 = "gold";
+        final String billingPeriod2 = "monthly";
+        final DateTime requestedDate2 =  new DateTime();
+        final DateTime effectiveDate2 = requestedDate2;
+        final String priceList2 = "default";
+        final String eventType2 = "PHASE";
+        final String phase2 = "EVERGREEN";
+        SubscriptionReadEventJson ev2 = new SubscriptionReadEventJson(eventId2, billingPeriod2, requestedDate2, effectiveDate2, productName2, priceList2, eventType2, phase2);
+        events.add(ev2);
+
+
+        final String subscriptionId = UUID.randomUUID().toString();
+        final String bundleId = UUID.randomUUID().toString();
+        final String productName = productName2;
+        final String productCategory = "classic";
+        final String billingPeriod = billingPeriod2;
+        final String priceList = priceList2;
+
+        SubscriptionJson obj = new SubscriptionJson(subscriptionId, bundleId, productName, productCategory, billingPeriod, priceList, events, null, null);
+        return obj;
+    }
+
+
+    private SubscriptionJson buildSubscriptionWriteEventJson() {
+
+        final List<SubscriptionNewEventJson> newEvents = new LinkedList<SubscriptionNewEventJson>();
+
+        final String eventId1 = UUID.randomUUID().toString();
+        final String productName1 = "gold";
+        final String billingPeriod1 = "monthly";
+        final DateTime requestedDate1 =  new DateTime();
+        final DateTime effectiveDate1 = requestedDate1;
+        final String priceList1 = "default";
+        final String eventType1 = "CREATE";
+        final String phase1 = "TRIAL";
+        SubscriptionNewEventJson ev1 = new SubscriptionNewEventJson(billingPeriod1, requestedDate1, productName1, priceList1, eventType1, phase1);
+        newEvents.add(ev1);
+
+        final List<SubscriptionDeletedEventJson> deletedEvents = new LinkedList<SubscriptionDeletedEventJson>();
+        final String eventId2 = UUID.randomUUID().toString();
+        final String productName2 = "gold";
+        final String billingPeriod2 = "monthly";
+        final DateTime requestedDate2 =  new DateTime();
+        final DateTime effectiveDate2 = requestedDate2;
+        final String priceList2 = "default";
+        final String eventType2 = "PHASE";
+        final String phase2 = "EVERGREEN";
+        SubscriptionDeletedEventJson ev2 = new SubscriptionDeletedEventJson(eventId2, billingPeriod2, requestedDate2, effectiveDate2, productName2, priceList2, eventType2, phase2);
+        deletedEvents.add(ev2);
+
+
+        final String subscriptionId = UUID.randomUUID().toString();
+        final String bundleId = UUID.randomUUID().toString();
+        final String productName = productName2;
+        final String productCategory = "classic";
+        final String billingPeriod = billingPeriod2;
+        final String priceList = priceList2;
+
+        SubscriptionJson obj = new SubscriptionJson(subscriptionId, bundleId, productName, productCategory, billingPeriod, priceList, null, newEvents, deletedEvents);
+        return obj;
+    }
+
+
+}
diff --git a/jaxrs/src/test/resources/log4j.xml b/jaxrs/src/test/resources/log4j.xml
new file mode 100644
index 0000000..512d2dc
--- /dev/null
+++ b/jaxrs/src/test/resources/log4j.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+
+    <logger name="com.ning.billing.jaxrs">
+        <level value="info"/>
+    </logger>
+
+    <root>
+        <priority value="info"/>
+        <appender-ref ref="stdout"/>
+    </root>
+</log4j:configuration>

pom.xml 35(+31 -4)

diff --git a/pom.xml b/pom.xml
index c0c46a2..65cc464 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,9 +47,31 @@
         <module>invoice</module>
         <module>payment</module>
         <module>util</module>
+        <module>jaxrs</module>
+        <module>server</module>
     </modules>
     <dependencyManagement>
         <dependencies>
+           <dependency>
+                <groupId>javax.ws.rs</groupId>
+                <artifactId>jsr311-api</artifactId>
+                <version>1.1.1</version>
+           </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-beatrix</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-analytics</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-jaxrs</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-api</artifactId>
@@ -64,6 +86,11 @@
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-server</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-account</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -137,17 +164,17 @@
             <dependency>
                 <groupId>org.codehaus.jackson</groupId>
                 <artifactId>jackson-core-asl</artifactId>
-                <version>1.9.2</version>
+                <version>1.9.4</version>
             </dependency>
             <dependency>
                 <groupId>org.codehaus.jackson</groupId>
                 <artifactId>jackson-jaxrs</artifactId>
-                <version>1.9.2</version>
+                <version>1.9.4</version>
             </dependency>
             <dependency>
                 <groupId>org.codehaus.jackson</groupId>
                 <artifactId>jackson-mapper-asl</artifactId>
-                <version>1.9.2</version>
+                <version>1.9.4</version>
             </dependency>
             <dependency>
                 <groupId>com.jolbox</groupId>
@@ -203,7 +230,7 @@
             <dependency>
                 <groupId>commons-lang</groupId>
                 <artifactId>commons-lang</artifactId>
-                <version>2.5</version>
+                <version>2.6</version>
             </dependency>
             <dependency>
                 <groupId>commons-collections</groupId>

server/pom.xml 470(+470 -0)

diff --git a/server/pom.xml b/server/pom.xml
new file mode 100644
index 0000000..7653948
--- /dev/null
+++ b/server/pom.xml
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ning.billing</groupId>
+        <artifactId>killbill</artifactId>
+        <version>0.1.8-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>killbill-server</artifactId>
+    <name>killbill-server</name>
+    <packaging>war</packaging>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <skeleton.version>0.0.20</skeleton.version>
+    </properties>
+
+    <dependencies>
+
+
+  
+
+
+        <!-- NOT in master POM; include version as well -->
+
+        <dependency>
+            <groupId>org.weakref</groupId>
+            <artifactId>jmxutils</artifactId>
+            <version>1.10</version>
+        </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.google.inject.extensions</groupId>
+            <artifactId>guice-servlet</artifactId>
+            <version>3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>1.10</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey.contribs</groupId>
+            <artifactId>jersey-guice</artifactId>
+            <version>1.10</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Do we want to depend on skeleton -->
+        <dependency>
+            <groupId>com.ning.jetty</groupId>
+            <artifactId>ning-service-skeleton-base</artifactId>
+            <version>${skeleton.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.jetty</groupId>
+            <artifactId>ning-service-skeleton-log4j</artifactId>
+            <version>${skeleton.version}</version>
+            <classifier>selfcontained</classifier>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- JETTY -->
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-http</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-io</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-deploy</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-xml</artifactId>
+            <version>7.5.1.v20110908</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.6.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.6.3</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.6.3</version>
+        </dependency>
+
+
+        <!-- FROM MASTER POM / LIBRARY -->
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-beatrix</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-entitlement</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-invoice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-payment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-catalog</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-analytics</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency><!-- Needed by jmxutils -->
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-multibindings</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <!--  SCOPE RUNTIME FROM MAIN POM; DO WE NEED IT ? -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+      <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>stringtemplate</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <!-- Ning specific -->
+            <id>pulse-build</id>
+            <properties>
+                <jettyWebroot>root</jettyWebroot>
+            </properties>
+            <activation>
+                <property>
+                    <name>env</name>
+                    <value>pulse-build</value>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency><!-- For LogLevelCounterAppender -->
+                    <groupId>com.ning.jetty</groupId>
+                    <artifactId>ning-service-skeleton-log4j</artifactId>
+                    <version>${skeleton.version}</version>
+                    <classifier>selfcontained</classifier>
+                    <scope>provided</scope>
+                </dependency>
+                <dependency>
+                    <groupId>ning.core</groupId>
+                    <artifactId>galaxy-deploy-scripts</artifactId>
+                    <version>13.0.4</version>
+                    <type>tar.gz</type>
+                    <scope>provided</scope>
+                </dependency>
+                <dependency>
+                    <groupId>ning.galaxy</groupId>
+                    <artifactId>galaxy-library</artifactId>
+                    <version>2.4.1</version>
+                    <type>tar.gz</type>
+                    <scope>provided</scope>
+                </dependency>
+                <dependency>
+                    <groupId>ning.jetty</groupId>
+                    <artifactId>ning-jetty-distribution</artifactId>
+                    <version>7.5.1-NING-1.0.1</version>
+                    <type>tar.gz</type>
+                    <scope>provided</scope>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <dependencies>
+                            <dependency>
+                                <groupId>ning.maven</groupId>
+                                <artifactId>default-assemblies</artifactId>
+                                <version>2.1.0</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <id>assemble-irs</id>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <phase>package</phase>
+                                <configuration>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                    <descriptorRefs>
+                                        <descriptorRef>default-jetty7-war-assembly</descriptorRef>
+                                    </descriptorRefs>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.ning.maven.plugins</groupId>
+                <artifactId>maven-dependency-versions-check-plugin</artifactId>
+                <version>2.0.2</version>
+                <configuration>
+                    <failBuildInCaseOfConflict>true</failBuildInCaseOfConflict>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <!-- To make eclipse happy -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.5</version>
+            </plugin>
+            <plugin>
+                <groupId>com.ning.maven.plugins</groupId>
+                <artifactId>maven-duplicate-finder-plugin</artifactId>
+                <version>1.0.2</version>
+                <configuration>
+                    <failBuildInCaseOfConflict>false</failBuildInCaseOfConflict>
+                    <!-- That's for Jetty -->
+                    <ignoredResources>
+                        <ignoredResource>about.html</ignoredResource>
+                    </ignoredResources>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <id>analyze</id>
+                        <goals>
+                            <goal>analyze-only</goal>
+                        </goals>
+                        <configuration>
+                            <ignoreNonCompile>true</ignoreNonCompile>
+                            <failOnWarning>false</failOnWarning>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <version>2.2.1</version>
+                <configuration>
+                    <mavenExecutorId>forked-path</mavenExecutorId>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.scm</groupId>
+                        <artifactId>maven-scm-provider-gitexe</artifactId>
+                        <version>1.4</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.codehaus.plexus</groupId>
+                        <artifactId>plexus-utils</artifactId>
+                        <version>1.5.9</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <!-- TODO: fix for http://jira.codehaus.org/browse/MSITE-286? -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>3.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <useManifestOnlyJar>false</useManifestOnlyJar>
+                    <systemPropertyVariables>
+                        <log4j.configuration>file:${project.basedir}/src/test/resources/log4j.xml</log4j.configuration>
+                        <xn.billing.zuora.useSluggedRatePlans>false</xn.billing.zuora.useSluggedRatePlans>
+                    </systemPropertyVariables>
+                    <groups>fast,slow</groups>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <attachClasses>true</attachClasses>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>7.5.1.v20110908</version>
+                <dependencies>
+                    <dependency><!-- For LogLevelCounterAppender -->
+                        <groupId>com.ning.jetty</groupId>
+                        <artifactId>ning-service-skeleton-log4j</artifactId>
+                        <version>${skeleton.version}</version>
+                        <classifier>selfcontained</classifier>
+                        <scope>runtime</scope>
+                    </dependency>
+                    <!-- Needed to redirect Jetty logs to slf4j -->
+                    <dependency>
+                        <groupId>org.slf4j</groupId>
+                        <artifactId>slf4j-api</artifactId>
+                        <version>1.6.3</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.slf4j</groupId>
+                        <artifactId>slf4j-log4j12</artifactId>
+                        <version>1.6.3</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <scanIntervalSeconds>60</scanIntervalSeconds>
+                    <systemProperties>
+                        <systemProperty>
+                            <name>log4j.configuration</name>
+                            <value>file:${basedir}/src/test/resources/log4j.xml</value>
+                        </systemProperty>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java b/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java
new file mode 100644
index 0000000..fc29d5f
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.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.server.config;
+
+import org.skife.config.Config;
+import org.skife.config.Default;
+
+public interface KillbillServerConfig {
+
+}
diff --git a/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java b/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java
new file mode 100644
index 0000000..2cad006
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.healthchecks;
+
+import org.weakref.jmx.Managed;
+
+import com.yammer.metrics.core.HealthCheck;
+
+public class KillbillHealthcheck extends HealthCheck {
+
+    @Override
+    public String name() {
+        return "KillbillHealthCheck";
+    }
+
+    @Override
+    public Result check() {
+        try {
+            // STEPH obviously needs more than that
+            return Result.healthy();
+        } catch (Exception e) {
+            return Result.unhealthy(e);
+        }
+    }
+
+
+    @Managed
+    public boolean isHealthy() {
+        return check().isHealthy();
+    }
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/GuiceModuleFactory.java b/server/src/main/java/com/ning/billing/server/listeners/GuiceModuleFactory.java
new file mode 100644
index 0000000..4ebd481
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/listeners/GuiceModuleFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.server.listeners;
+
+import com.google.inject.Module;
+
+public interface GuiceModuleFactory {
+    Module createModule();
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
new file mode 100644
index 0000000..880fc4f
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server.listeners;
+
+
+import javax.servlet.ServletContextEvent;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Injector;
+import com.ning.jetty.core.listeners.SetupServer;
+
+public class KillbillGuiceListener extends SetupServer {
+
+
+    private static Injector injectorInstance;
+
+    public static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
+
+
+    @Override
+    public void contextInitialized(final ServletContextEvent event) {
+
+        logger.info("GuiceListener : contextInitialized");
+
+        final String moduleFactoryClassName = event.getServletContext().getInitParameter("guiceModuleFactoryClass");
+
+        if (StringUtils.isEmpty(moduleFactoryClassName)) {
+            throw new IllegalStateException("Missing parameter 'guiceModuleFactoryClass' for IrsGuiceListener!");
+        }
+        try {
+            final Class<?> moduleFactoryClass = Class.forName(moduleFactoryClassName);
+            if (!GuiceModuleFactory.class.isAssignableFrom(moduleFactoryClass)) {
+                throw new IllegalStateException(String.format("%s exists but is not a guice module factory!", moduleFactoryClassName));
+            }
+
+            GuiceModuleFactory factory = GuiceModuleFactory.class.cast(moduleFactoryClass.newInstance());
+            logger.info("Instantiated " + moduleFactoryClassName + " as the factory for the main guice module.");
+
+            guiceModule = factory.createModule();
+        }
+        catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+
+        super.contextInitialized(event);
+
+        injectorInstance = this.injector(event);
+
+    }
+
+    public static Injector getInjectorInstance() {
+        return injectorInstance;
+    }
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceModuleFactory.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceModuleFactory.java
new file mode 100644
index 0000000..effa7bd
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceModuleFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.server.listeners;
+
+import static com.sun.jersey.api.core.PackagesResourceConfig.PROPERTY_PACKAGES;
+import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS;
+import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Module;
+
+import com.ning.billing.server.healthchecks.KillbillHealthcheck;
+import com.ning.billing.server.modules.KillbillServerModule;
+import com.ning.jetty.base.modules.ServerModuleBuilder;
+import com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;
+import com.sun.jersey.api.container.filter.LoggingFilter;
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+
+
+public class KillbillGuiceModuleFactory implements GuiceModuleFactory {
+
+
+    private static final List<String> FILTERS = ImmutableList.of(GZIPContentEncodingFilter.class.getName(),
+            LoggingFilter.class.getName());
+    private static final List<String> RESOURCES = ImmutableList.of("com.ning.billing.jaxrs.resources");
+
+    private static final Map<String, String> JERSEY_PARAMS = ImmutableMap.of(
+            PROPERTY_CONTAINER_REQUEST_FILTERS, StringUtils.join(FILTERS, ";"),
+            // Though it would seem to make sense that filters should be applied to responses in reverse order, in fact the
+            // response filters appear to wrap each other up before executing, with the result being that execution order
+            // is the reverse of the declared order.
+            PROPERTY_CONTAINER_RESPONSE_FILTERS, StringUtils.join(FILTERS, ";"),
+            PROPERTY_PACKAGES, StringUtils.join(RESOURCES, ";")
+    );
+
+    private KillbillServerModule instantiateServiceModule() {
+        try {
+            /*
+            ParameterizedType parameterizedType = (ParameterizedType)getClass().getGenericSuperclass();
+            @SuppressWarnings("unchecked")
+            Class<KillbillServerModule> clazz = (Class<KillbillServerModule>)parameterizedType.getActualTypeArguments()[0];
+            */
+            return KillbillServerModule.class.newInstance();
+        }
+        catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    @Override
+    public Module createModule() {
+        final ServerModuleBuilder builder = new ServerModuleBuilder();
+
+        builder.addHealthCheck(KillbillHealthcheck.class)
+        .addJMXExport(KillbillHealthcheck.class)
+        .addModule(instantiateServiceModule())
+        .enableLog4J()
+        .trackRequests()
+        .addFilter("/1.0/*", GuiceContainer.class, JERSEY_PARAMS);
+        return builder.build();
+    }
+
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillLifecycleListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillLifecycleListener.java
new file mode 100644
index 0000000..0aef190
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillLifecycleListener.java
@@ -0,0 +1,106 @@
+/*
+ * 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.server.listeners;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Injector;
+import com.ning.billing.beatrix.lifecycle.DefaultLifecycle;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.Bus.EventBusException;
+
+public class KillbillLifecycleListener implements ServletContextListener {
+
+
+    public static final Logger logger = LoggerFactory.getLogger(KillbillLifecycleListener.class);
+
+    private DefaultLifecycle killbillLifecycle;
+    private BusService killbillBusService;
+
+    private KillbillEventHandler killbilleventHandler;
+
+
+    @Override
+    public void contextInitialized(ServletContextEvent sce) {
+
+        logger.info("KillbillLifecycleListener : contextInitialized");
+        Injector injector = KillbillGuiceListener.getInjectorInstance();
+        killbillLifecycle = injector.getInstance(DefaultLifecycle.class);
+        killbillBusService = injector.getInstance(BusService.class);
+
+        killbilleventHandler = new KillbillEventHandler();
+
+        //
+        // Fire all Startup levels up to service start
+        //
+        killbillLifecycle.fireStartupSequencePriorEventRegistration();
+        //
+        // Perform Bus registration
+        //
+        try {
+            killbillBusService.getBus().register(killbilleventHandler);
+        } catch (EventBusException e) {
+           logger.error("Failed to register for event notifications, this is bad exiting!", e);
+           System.exit(1);
+        }
+        // Let's start!
+        killbillLifecycle.fireStartupSequencePostEventRegistration();
+    }
+
+    @Override
+    public void contextDestroyed(ServletContextEvent sce) {
+        logger.info("IrsKillbillListener : contextDestroyed");
+        // Stop services
+        // Guice error, no need to fill the screen with useless stack traces
+        if (killbillLifecycle == null) {
+            return;
+        }
+
+        killbillLifecycle.fireShutdownSequencePriorEventUnRegistration();
+
+        try {
+            killbillBusService.getBus().unregister(killbilleventHandler);
+        } catch (EventBusException e) {
+            logger.warn("Failed to unregister for event notifications", e);
+        }
+
+        // Complete shutdown sequence
+        killbillLifecycle.fireShutdownSequencePostEventUnRegistration();
+    }
+
+
+    //
+    // At this point we have one generic handler in IRS that could dispatch notifications to the various pieces
+    // interested but we could the various pieces register their own handler directly
+    //     //
+    public static class KillbillEventHandler {
+
+        /*
+         * IRS event handler for killbill entitlement events
+         */
+        @Subscribe
+        public void handleEntitlementevents(SubscriptionTransition event) {
+            logger.info("Killbill entitlement event {}", event.toString());
+        }
+    }
+}
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
new file mode 100644
index 0000000..edf8f10
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -0,0 +1,98 @@
+/*
+ * 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.server.modules;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.account.glue.AccountModule;
+import com.ning.billing.analytics.setup.AnalyticsModule;
+import com.ning.billing.beatrix.glue.BeatrixModule;
+import com.ning.billing.catalog.glue.CatalogModule;
+import com.ning.billing.entitlement.glue.EntitlementModule;
+import com.ning.billing.invoice.glue.InvoiceModule;
+import com.ning.billing.jaxrs.resources.AccountResource;
+import com.ning.billing.jaxrs.resources.BundleResource;
+import com.ning.billing.jaxrs.resources.BundleTimelineResource;
+import com.ning.billing.jaxrs.resources.InvoiceResource;
+import com.ning.billing.jaxrs.resources.PaymentResource;
+import com.ning.billing.jaxrs.resources.SubscriptionResource;
+import com.ning.billing.payment.setup.PaymentModule;
+import com.ning.billing.server.config.KillbillServerConfig;
+import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NotificationQueueModule;
+import com.ning.billing.util.glue.TagStoreModule;
+import com.ning.jetty.utils.providers.DBIProvider;
+
+public class KillbillServerModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        configureConfig();
+        configureDao();
+        configureResources();
+        installKillbillModules();
+        // STEPH Do we need that?
+        installMBeanExporter();
+    }
+
+    protected void configureDao() {
+        bind(IDBI.class).to(DBI.class).asEagerSingleton();
+        bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
+    }
+
+
+    protected void configureConfig() {
+        KillbillServerConfig config = new ConfigurationObjectFactory(System.getProperties()).build(KillbillServerConfig.class);
+        bind(KillbillServerConfig.class).toInstance(config);
+    }
+
+    protected void configureResources() {
+        bind(AccountResource.class).asEagerSingleton();
+        bind(BundleResource.class).asEagerSingleton();
+        bind(SubscriptionResource.class).asEagerSingleton();
+        bind(BundleTimelineResource.class).asEagerSingleton();
+        bind(InvoiceResource.class).asEagerSingleton();
+        bind(PaymentResource.class).asEagerSingleton();
+    }
+
+    protected void installKillbillModules() {
+        install(new BusModule());
+        install(new NotificationQueueModule());
+        install(new AccountModule());
+        install(new InvoiceModule());
+        install(new EntitlementModule());
+        install(new AnalyticsModule());
+        install(new PaymentModule());
+        install(new TagStoreModule());
+        install(new CatalogModule());
+        install(new BeatrixModule());
+        install(new ClockModule());
+    }
+
+    protected void installMBeanExporter() {
+        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+        bind(MBeanServer.class).toInstance(mbeanServer);
+    }
+}
diff --git a/server/src/main/jetty-config/contexts/root.xml b/server/src/main/jetty-config/contexts/root.xml
new file mode 100755
index 0000000..cdf71e1
--- /dev/null
+++ b/server/src/main/jetty-config/contexts/root.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"  encoding="UTF-8"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+    <Set name="contextPath">/</Set>
+    <Set name="war">
+        <SystemProperty name="xn.jetty.webapp.path" default="webapps/root"/>
+    </Set>
+    <Set name="defaultsDescriptor">
+        <SystemProperty name="xn.jetty.webapps.defaultsDescriptor" default="etc/webdefault.xml"/>
+    </Set>
+</Configure>
diff --git a/server/src/main/jetty-config/etc/webdefault.xml b/server/src/main/jetty-config/etc/webdefault.xml
new file mode 100755
index 0000000..19ae6ff
--- /dev/null
+++ b/server/src/main/jetty-config/etc/webdefault.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app
+        xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+        metadata-complete="true"
+        version="2.5">
+    <description>
+        Default web.xml file.
+        This file is applied to a Web application before it's own WEB_INF/web.xml file
+    </description>
+    <context-param>
+        <param-name>org.mortbay.jetty.webapp.NoTLDJarPattern</param-name>
+        <param-value>
+            start.jar|ant-.*\.jar|dojo-.*\.jar|jetty-.*\.jar|jsp-api-.*\.jar|junit-.*\.jar|servlet-api-.*\.jar|dnsns\.jar|rt\.jar|jsse\.jar|tools\.jar|sunpkcs11\.jar|sunjce_provider\.jar|xerces.*\.jar
+        </param-value>
+    </context-param>
+    <locale-encoding-mapping-list>
+        <locale-encoding-mapping>
+            <locale>ar</locale>
+            <encoding>ISO-8859-6</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>be</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>bg</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ca</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>cs</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>da</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>de</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>el</locale>
+            <encoding>ISO-8859-7</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>en</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>es</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>et</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fi</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fr</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hr</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hu</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>is</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>it</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>iw</locale>
+            <encoding>ISO-8859-8</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ja</locale>
+            <encoding>Shift_JIS</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ko</locale>
+            <encoding>EUC-KR</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lt</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lv</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>mk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>nl</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>no</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pt</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ro</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ru</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sh</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sk</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sq</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sr</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sv</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>tr</locale>
+            <encoding>ISO-8859-9</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>uk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh</locale>
+            <encoding>GB2312</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh_TW</locale>
+            <encoding>Big5</encoding>
+        </locale-encoding-mapping>
+    </locale-encoding-mapping-list>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Disable TRACE</web-resource-name>
+            <url-pattern>/</url-pattern>
+            <http-method>TRACE</http-method>
+        </web-resource-collection>
+        <auth-constraint/>
+    </security-constraint>
+</web-app>
+
diff --git a/server/src/main/jetty-config/ning-jetty-conf.xml b/server/src/main/jetty-config/ning-jetty-conf.xml
new file mode 100644
index 0000000..60764c5
--- /dev/null
+++ b/server/src/main/jetty-config/ning-jetty-conf.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+    <!-- =============================================================== -->
+    <!-- Setup MBean Server early                                        -->
+    <!-- =============================================================== -->
+    <Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/>
+
+    <New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
+        <Arg>
+            <Ref id="MBeanServer"/>
+        </Arg>
+    </New>
+
+    <Get id="Container" name="container">
+        <Call name="addEventListener">
+            <Arg>
+                <Ref id="MBeanContainer"/>
+            </Arg>
+        </Call>
+    </Get>
+
+    <!-- =========================================================== -->
+    <!-- Server Thread Pool                                          -->
+    <!-- =========================================================== -->
+    <Set name="ThreadPool">
+        <!-- Default queued blocking threadpool -->
+        <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+            <Set name="minThreads">
+                <SystemProperty name="xn.server.threads.min" default="10"/>
+            </Set>
+            <Set name="maxThreads">
+                <SystemProperty name="xn.server.threads.max" default="200"/>
+            </Set>
+        </New>
+    </Set>
+
+    <!-- =========================================================== -->
+    <!-- Set connectors                                              -->
+    <!-- =========================================================== -->
+
+    <!-- Use this connector if NIO is not available. -->
+    <Call name="addConnector">
+        <Arg>
+            <New class="org.eclipse.jetty.server.bio.SocketConnector">
+                <Set name="host">
+                    <SystemProperty name="xn.server.ip"/>
+                </Set>
+                <Set name="port">
+                    <SystemProperty name="xn.server.port" default="8080"/>
+                </Set>
+                <Set name="maxIdleTime">300000</Set>
+                <Set name="Acceptors">2</Set>
+                <Set name="statsOn">true</Set>
+                <Set name="confidentialPort">
+                    <SystemProperty name="xn.server.ssl.port" default="8443"/>
+                </Set>
+            </New>
+        </Arg>
+    </Call>
+
+    <Set name="handler">
+        <New class="org.eclipse.jetty.server.handler.StatisticsHandler">
+            <Set name="handler">
+                <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+                    <Set name="handlers">
+                        <Array type="org.eclipse.jetty.server.Handler">
+                            <Item>
+                                <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
+                            </Item>
+                            <Item>
+                                <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
+                            </Item>
+                            <Item>
+                                <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
+                            </Item>
+                        </Array>
+                    </Set>
+                </New>
+            </Set>
+        </New>
+    </Set>
+
+    <Ref id="RequestLog">
+        <Set name="requestLog">
+            <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
+                <Arg>
+                    <SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log
+                </Arg>
+                <Set name="retainDays">30</Set>
+                <Set name="append">true</Set>
+                <Set name="extended">false</Set>
+                <Set name="LogTimeZone">GMT</Set>
+            </New>
+        </Set>
+    </Ref>
+
+    <Call name="addLifeCycle">
+        <Arg>
+            <New class="org.eclipse.jetty.deploy.ContextDeployer">
+                <Set name="contexts">
+                    <Ref id="Contexts"/>
+                </Set>
+                <Set name="configurationDir">
+                    <SystemProperty name="xn.jetty.contextDir" default="contexts"/>
+                </Set>
+                <Set name="scanInterval">1</Set>
+            </New>
+        </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- extra options                                               -->
+    <!-- =========================================================== -->
+    <Set name="stopAtShutdown">true</Set>
+    <Set name="sendServerVersion">false</Set>
+    <Set name="sendDateHeader">true</Set>
+    <Set name="gracefulShutdown">
+        <SystemProperty name="xn.jetty.gracefulShutdownTimeoutInMs" default="1000"/>
+    </Set>
+</Configure>
diff --git a/server/src/main/resources/catalog-demo.xml b/server/src/main/resources/catalog-demo.xml
new file mode 100644
index 0000000..8a97d57
--- /dev/null
+++ b/server/src/main/resources/catalog-demo.xml
@@ -0,0 +1,641 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+  ~ 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.
+  -->
+
+<!-- 
+Use cases covered so far:
+	Tiered Product (Pistol/Shotgun/Assault-Rifle)
+	Multiple changeEvent plan policies
+	Multiple PlanAlignment (see below, trial add-on alignments and rescue discount package)
+	Product transition rules
+	Add on (Scopes, Hoster)
+	Multi-pack addon (Extra-Ammo)
+	Addon Trial aligned to base plan (holster-monthly-regular)
+	Addon Trial aligned to creation (holster-monthly-special)
+	Rescue discount package (assault-rifle-annual-rescue)
+	Plan phase with a reccurring and a one off (refurbish-maintenance)
+	Phan with more than 2 phase (gunclub discount plans)
+		
+Use Cases to do:
+	Tiered Add On
+	Riskfree period
+	
+
+
+ -->
+<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
+
+	<effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
+	<catalogName>Firearms</catalogName>
+
+	<currencies>
+		<currency>USD</currency>
+		<currency>EUR</currency>
+		<currency>GBP</currency>
+	</currencies>
+	
+	<products>
+		<product name="Pistol">
+			<category>BASE</category>
+		</product>
+		<product name="Shotgun">
+			<category>BASE</category>
+            <available>
+                <addonProduct>Telescopic-Scope</addonProduct>
+                <addonProduct>Laser-Scope</addonProduct>
+            </available>
+		</product>
+		<product name="Assault-Rifle">
+			<category>BASE</category>
+			<included> 
+				<addonProduct>Telescopic-Scope</addonProduct>
+			</included>
+			<available>
+				<addonProduct>Laser-Scope</addonProduct>
+			</available>
+		</product>
+		<product name="Telescopic-Scope">
+			<category>ADD_ON</category>
+		</product>
+		<product name="Laser-Scope">
+			<category>ADD_ON</category>
+		</product>
+		<product name="Holster">
+			<category>ADD_ON</category>
+		</product>
+		<product name="Extra-Ammo">
+			<category>ADD_ON</category>
+		</product>
+		<product name="Refurbish-Maintenance">
+			<category>ADD_ON</category>
+		</product>
+	</products>
+	 
+	<rules>
+		<changePolicy>
+			<changePolicyCase> 
+				<phaseType>TRIAL</phaseType>
+				<policy>IMMEDIATE</policy>
+			</changePolicyCase>
+            <changePolicyCase> 
+                <toProduct>Assault-Rifle</toProduct>
+                <policy>IMMEDIATE</policy>
+            </changePolicyCase>
+            <changePolicyCase> 
+                <fromProduct>Pistol</fromProduct>            
+                <toProduct>Shotgun</toProduct>
+                <policy>IMMEDIATE</policy>
+            </changePolicyCase>
+			<changePolicyCase> 
+				<toPriceList>rescue</toPriceList>
+				<policy>END_OF_TERM</policy>
+			</changePolicyCase>
+			<changePolicyCase> 
+				<fromBillingPeriod>MONTHLY</fromBillingPeriod>
+				<toBillingPeriod>ANNUAL</toBillingPeriod>
+				<policy>IMMEDIATE</policy>
+			</changePolicyCase>
+			<changePolicyCase> 
+				<fromBillingPeriod>ANNUAL</fromBillingPeriod>
+				<toBillingPeriod>MONTHLY</toBillingPeriod>
+				<policy>END_OF_TERM</policy>
+			</changePolicyCase>
+			<changePolicyCase> 
+				<policy>END_OF_TERM</policy>
+			</changePolicyCase>
+		</changePolicy>
+		<changeAlignment>
+			<changeAlignmentCase>
+				<toPriceList>rescue</toPriceList>
+				<alignment>CHANGE_OF_PLAN</alignment>
+			</changeAlignmentCase>
+			<changeAlignmentCase>
+				<fromPriceList>rescue</fromPriceList>
+				<toPriceList>rescue</toPriceList>
+				<alignment>CHANGE_OF_PRICELIST</alignment>
+			</changeAlignmentCase>
+            <changeAlignmentCase>
+                <alignment>START_OF_SUBSCRIPTION</alignment>
+            </changeAlignmentCase>
+		</changeAlignment>
+		<cancelPolicy>
+			<cancelPolicyCase>
+				<phaseType>TRIAL</phaseType>
+				<policy>IMMEDIATE</policy>
+			</cancelPolicyCase>
+            <cancelPolicyCase>
+                <policy>END_OF_TERM</policy>
+            </cancelPolicyCase>
+		</cancelPolicy>
+		<createAlignment>
+		    <createAlignmentCase>
+		        <product>Laser-Scope</product>
+                <alignment>START_OF_SUBSCRIPTION</alignment>
+            </createAlignmentCase>
+            <createAlignmentCase>
+                <alignment>START_OF_BUNDLE</alignment>
+            </createAlignmentCase>
+		</createAlignment>
+		<billingAlignment>
+			<billingAlignmentCase>
+				<productCategory>ADD_ON</productCategory>
+				<alignment>BUNDLE</alignment>
+			</billingAlignmentCase>
+			<billingAlignmentCase>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<alignment>SUBSCRIPTION</alignment>
+			</billingAlignmentCase>
+			<billingAlignmentCase>
+				<alignment>ACCOUNT</alignment>
+			</billingAlignmentCase>
+		</billingAlignment>
+		<priceList>
+			<priceListCase>
+				<fromPriceList>rescue</fromPriceList>
+				<toPriceList>DEFAULT</toPriceList>
+			</priceListCase>
+		</priceList>
+	</rules>
+
+	<plans>
+		<plan name="pistol-monthly">
+			<product>Pistol</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice> <!-- empty price implies $0 -->
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>GBP</currency><value>29.95</value></price>
+					<price><currency>EUR</currency><value>29.95</value></price> 
+					<price><currency>USD</currency><value>29.95</value></price>								
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="shotgun-monthly">
+			<product>Shotgun</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice></fixedPrice>
+				    <!-- no price implies $0 -->
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+					<number>-1</number>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>249.95</value></price>								
+					<price><currency>EUR</currency><value>149.95</value></price>
+					<price><currency>GBP</currency><value>169.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="assault-rifle-monthly">
+			<product>Assault-Rifle</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>599.95</value></price>								
+					<price><currency>EUR</currency><value>349.95</value></price>
+					<price><currency>GBP</currency><value>399.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="pistol-annual">
+			<product>Pistol</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>199.95</value></price>								
+					<price><currency>EUR</currency><value>199.95</value></price>
+					<price><currency>GBP</currency><value>199.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="shotgun-annual">
+			<product>Shotgun</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>2399.95</value></price>								
+					<price><currency>EUR</currency><value>1499.95</value></price>
+					<price><currency>GBP</currency><value>1699.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="assault-rifle-annual">
+			<product>Assault-Rifle</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>5999.95</value></price>								
+					<price><currency>EUR</currency><value>3499.95</value></price>
+					<price><currency>GBP</currency><value>3999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="pistol-annual-gunclub-discount">
+			<product>Pistol</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+				<phase type="DISCOUNT">
+					<duration>
+						<unit>MONTHS</unit>
+						<number>6</number>
+					</duration>
+					<billingPeriod>MONTHLY</billingPeriod>
+					<recurringPrice>
+						<price><currency>USD</currency><value>9.95</value></price>								
+						<price><currency>EUR</currency><value>9.95</value></price>
+						<price><currency>GBP</currency><value>9.95</value></price>
+					</recurringPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>199.95</value></price>								
+					<price><currency>EUR</currency><value>199.95</value></price>
+					<price><currency>GBP</currency><value>199.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="shotgun-annual-gunclub-discount">
+			<product>Shotgun</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+				<phase type="DISCOUNT">
+					<duration>
+						<unit>MONTHS</unit>
+						<number>6</number>
+					</duration>
+					<billingPeriod>MONTHLY</billingPeriod>
+					<recurringPrice>
+						<price><currency>USD</currency><value>19.95</value></price>								
+						<price><currency>EUR</currency><value>49.95</value></price>
+						<price><currency>GBP</currency><value>69.95</value></price>
+					</recurringPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>2399.95</value></price>								
+					<price><currency>EUR</currency><value>1499.95</value></price>
+					<price><currency>GBP</currency><value>1699.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="assault-rifle-annual-gunclub-discount">
+			<product>Assault-Rifle</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+				<phase type="DISCOUNT">
+					<duration>
+						<unit>MONTHS</unit>
+						<number>6</number>
+					</duration>
+					<billingPeriod>MONTHLY</billingPeriod>
+					<recurringPrice>
+						<price><currency>USD</currency><value>99.95</value></price>								
+						<price><currency>EUR</currency><value>99.95</value></price>
+						<price><currency>GBP</currency><value>99.95</value></price>
+						</recurringPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>5999.95</value></price>								
+					<price><currency>EUR</currency><value>3499.95</value></price>
+					<price><currency>GBP</currency><value>3999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="laser-scope-monthly">
+		<product>Laser-Scope</product>
+           <initialPhases>
+              <phase type="DISCOUNT">
+                 <duration>
+                    <unit>MONTHS</unit>
+                    <number>1</number>
+                  </duration>
+                 <billingPeriod>MONTHLY</billingPeriod>
+                    <recurringPrice>
+                      <price><currency>USD</currency><value>999.95</value></price>                             
+                      <price><currency>EUR</currency><value>499.95</value></price>
+                      <price><currency>GBP</currency><value>999.95</value></price>
+                      </recurringPrice>
+                </phase>
+            </initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>1999.95</value></price>								
+					<price><currency>EUR</currency><value>1499.95</value></price>
+					<price><currency>GBP</currency><value>1999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="telescopic-scope-monthly">
+			<product>Telescopic-Scope</product>
+			<initialPhases>
+              <phase type="DISCOUNT">
+                 <duration>
+                    <unit>MONTHS</unit>
+                    <number>1</number>
+                  </duration>
+                 <billingPeriod>MONTHLY</billingPeriod>
+                    <recurringPrice>
+                      <price><currency>USD</currency><value>399.95</value></price>                             
+                      <price><currency>EUR</currency><value>299.95</value></price>
+                      <price><currency>GBP</currency><value>399.95</value></price>
+                      </recurringPrice>
+                </phase>
+            </initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>999.95</value></price>								
+					<price><currency>EUR</currency><value>499.95</value></price>
+					<price><currency>GBP</currency><value>999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="extra-ammo-monthly">
+			<product>Extra-Ammo</product>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>999.95</value></price>								
+					<price><currency>EUR</currency><value>499.95</value></price>
+					<price><currency>GBP</currency><value>999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+			<plansAllowedInBundle>-1</plansAllowedInBundle> <!-- arbitrary number of these (multipack) -->
+		</plan>
+		<plan name="holster-monthly-regular">
+			<product>Holster</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>199.95</value></price>								
+					<price><currency>EUR</currency><value>199.95</value></price>
+					<price><currency>GBP</currency><value>199.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="holster-monthly-special">
+			<product>Holster</product>
+			<initialPhases>
+				<phase type="TRIAL">
+					<duration>
+						<unit>DAYS</unit>
+						<number>30</number>
+					</duration>
+					<billingPeriod>NO_BILLING_PERIOD</billingPeriod>
+					<fixedPrice>
+					</fixedPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>199.95</value></price>								
+					<price><currency>EUR</currency><value>199.95</value></price>
+					<price><currency>GBP</currency><value>199.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="assault-rifle-annual-rescue">
+			<product>Assault-Rifle</product>
+			<initialPhases>
+				<phase type="DISCOUNT">
+					<duration>
+						<unit>YEARS</unit>
+						<number>1</number>
+					</duration>
+					<billingPeriod>ANNUAL</billingPeriod>
+					<recurringPrice>
+						<price><currency>USD</currency><value>5999.95</value></price>								
+						<price><currency>EUR</currency><value>3499.95</value></price>
+						<price><currency>GBP</currency><value>3999.95</value></price>
+					</recurringPrice>
+				</phase>
+			</initialPhases>
+			<finalPhase type="EVERGREEN">
+				<duration>
+					<unit>UNLIMITED</unit>
+				</duration>
+				<billingPeriod>ANNUAL</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>5999.95</value></price>								
+					<price><currency>EUR</currency><value>3499.95</value></price>
+					<price><currency>GBP</currency><value>3999.95</value></price>
+				</recurringPrice>
+			</finalPhase>
+		</plan>
+		<plan name="refurbish-maintenance">
+			<product>Refurbish-Maintenance</product>
+			<finalPhase type="FIXEDTERM">
+				<duration>
+					<unit>MONTHS</unit>
+					<number>12</number>
+				</duration>
+				<billingPeriod>MONTHLY</billingPeriod>
+				<recurringPrice>
+					<price><currency>USD</currency><value>199.95</value></price>								
+					<price><currency>EUR</currency><value>199.95</value></price>
+					<price><currency>GBP</currency><value>199.95</value></price>
+				</recurringPrice>
+				<fixedPrice>
+					<price><currency>USD</currency><value>599.95</value></price>								
+					<price><currency>EUR</currency><value>599.95</value></price>
+					<price><currency>GBP</currency><value>599.95</value></price>
+				</fixedPrice>
+			</finalPhase>
+		</plan>
+	</plans>
+	<priceLists>
+		<defaultPriceList name="DEFAULT"> 
+			<plans>
+				<plan>pistol-monthly</plan>
+				<plan>shotgun-monthly</plan>
+				<plan>assault-rifle-monthly</plan>
+				<plan>pistol-annual</plan>
+				<plan>shotgun-annual</plan>
+				<plan>assault-rifle-annual</plan>
+				<plan>laser-scope-monthly</plan>
+				<plan>telescopic-scope-monthly</plan>
+				<plan>extra-ammo-monthly</plan>
+				<plan>holster-monthly-regular</plan>
+				<plan>refurbish-maintenance</plan>
+			</plans>
+		</defaultPriceList>
+		<childPriceList name="gunclubDiscount">
+			<plans>
+				<plan>pistol-monthly</plan>
+				<plan>shotgun-monthly</plan>
+				<plan>assault-rifle-monthly</plan>
+				<plan>pistol-annual-gunclub-discount</plan>
+				<plan>shotgun-annual-gunclub-discount</plan>
+				<plan>assault-rifle-annual-gunclub-discount</plan>
+				<plan>holster-monthly-special</plan>
+			</plans>
+		</childPriceList>
+		<childPriceList name="rescue">
+			<plans>
+				<plan>assault-rifle-annual-rescue</plan>
+			</plans>
+		</childPriceList>
+	</priceLists>
+
+</catalog>
diff --git a/server/src/main/resources/killbill-server.properties b/server/src/main/resources/killbill-server.properties
new file mode 100644
index 0000000..facf47d
--- /dev/null
+++ b/server/src/main/resources/killbill-server.properties
@@ -0,0 +1,11 @@
+com.ning.core.dao.url=jdbc:mysql://127.0.0.1:3306/killbill
+com.ning.core.dao.user=root
+com.ning.core.dao.password=root
+
+killbill.catalog.uri=file:src/main/resources/catalog-demo.xml
+
+killbill.entitlement.dao.claim.time=60000
+killbill.entitlement.dao.ready.max=1
+killbill.entitlement.engine.notifications.sleep=500
+user.timezone=UTC
+
diff --git a/server/src/main/resources/log4j.xml b/server/src/main/resources/log4j.xml
new file mode 100644
index 0000000..cd2f7c0
--- /dev/null
+++ b/server/src/main/resources/log4j.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+    <appender name="requests" class="org.apache.log4j.RollingFileAppender">
+        <param name="File" value="logs/http.log"/>
+        <param name="MaxFileSize" value="100MB"/>
+        <param name="MaxBackupIndex" value="1"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+    <!-- Bilr response logs -->
+    <appender name="bilr_responses" class="org.apache.log4j.RollingFileAppender">
+        <param name="File" value="logs/bilr.log"/>
+        <param name="MaxFileSize" value="100MB"/>
+        <param name="MaxBackupIndex" value="10"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+    <appender name="LOG_LEVEL_COUNTER" class="com.ning.jetty.log4j.LogLevelCounterAppender"/>
+
+    <logger name="com.sun.jersey.api.container.filter" additivity="false">
+        <level value="info"/>
+        <appender-ref ref="requests"/>
+    </logger>
+
+    <logger name="com.ning.metrics" additivity="false">
+        <level value="error"/>
+        <appender-ref ref="stdout"/>
+    </logger>
+
+    <!-- Silence com.ning.http.client.generators.InputStreamBodyGenerator inputStream.markSupported() not supported. Some features will not works
+         which doesn't seem to impact us -->
+    <logger name="com.ning.http.client.generators.InputStreamBodyGenerator">
+        <level value="error"/>
+    </logger>
+
+    <!-- Silence com.ning.http.client.providers.netty.NettyAsyncHttpProvider Number of application's worked threads is 8
+         which is not that useful -->
+    <logger name="com.ning.http.client.providers.netty.NettyAsyncHttpProvider">
+        <level value="warn"/>
+    </logger>
+
+    <logger name="com.ning">
+        <level value="info"/>
+    </logger>
+
+    <root>
+        <priority value="info"/>
+        <appender-ref ref="stdout"/>
+        <appender-ref ref="LOG_LEVEL_COUNTER"/>
+    </root>
+</log4j:configuration>
diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..e9c0ee0
--- /dev/null
+++ b/server/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+        version="2.5">
+    <display-name>irs</display-name>
+    <filter>
+        <!-- Guice emulates Servlet API with DI -->
+        <filter-name>guiceFilter</filter-name>
+        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>guiceFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <listener>
+        <!-- Jersey insists on using java.util.logging (JUL) -->
+        <listener-class>com.ning.jetty.core.listeners.SetupJULBridge</listener-class>
+    </listener>
+    <!-- This param tells the IrsGuiceListener listener which factory to use for the root guice module -->
+    <context-param>
+        <param-name>guiceModuleFactoryClass</param-name>
+        <param-value>com.ning.billing.server.listeners.KillbillGuiceModuleFactory</param-value>
+    </context-param>
+    <listener>
+        <!-- Context listener: called at startup time and creates the injector -->
+        <listener-class>com.ning.billing.server.listeners.KillbillGuiceListener</listener-class>
+    </listener>
+    <listener>
+        <listener-class>com.ning.billing.server.listeners.KillbillLifecycleListener</listener-class>
+    </listener>
+    <!-- ServletHandler#handle requires a backend servlet, it won't be used though (handled by Guice) -->
+    <servlet>
+        <servlet-name>log-invalid-resources</servlet-name>
+        <servlet-class>com.ning.jetty.core.servlets.LogInvalidResourcesServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>log-invalid-resources</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/server/src/test/resources/log4j.xml b/server/src/test/resources/log4j.xml
new file mode 100644
index 0000000..1a946d3
--- /dev/null
+++ b/server/src/test/resources/log4j.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+
+    <logger name="com.ning.billing.server">
+        <level value="info"/>
+    </logger>
+
+    <root>
+        <priority value="info"/>
+        <appender-ref ref="stdout"/>
+    </root>
+</log4j:configuration>
diff --git a/util/src/main/java/com/ning/billing/util/clock/Clock.java b/util/src/main/java/com/ning/billing/util/clock/Clock.java
index b41a36d..6b65aac 100644
--- a/util/src/main/java/com/ning/billing/util/clock/Clock.java
+++ b/util/src/main/java/com/ning/billing/util/clock/Clock.java
@@ -25,6 +25,5 @@ public interface Clock {
 
     public DateTime getUTCNow();
 
-
     //public DateTime addDuration(DateTime input, IDuration duration);
 }
diff --git a/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
index 8280a15..057a58c 100644
--- a/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
+++ b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
@@ -36,6 +36,13 @@ public class DefaultClock implements Clock {
         return getNow(DateTimeZone.UTC);
     }
 
+    public static DateTime toUTCDateTime(DateTime input) {
+        if (input == null) {
+            return null;
+        }
+        DateTime result = input.toDateTime(DateTimeZone.UTC);
+        return truncateMs(result);
+    }
 
     public static DateTime truncateMs(DateTime input) {
         return input.minus(input.getMillisOfSecond());