killbill-memoizeit

Changes

Details

diff --git a/api/src/main/java/com/ning/billing/BillingExceptionBase.java b/api/src/main/java/com/ning/billing/BillingExceptionBase.java
index 85761ab..251773a 100644
--- a/api/src/main/java/com/ning/billing/BillingExceptionBase.java
+++ b/api/src/main/java/com/ning/billing/BillingExceptionBase.java
@@ -76,7 +76,6 @@ public class BillingExceptionBase extends Exception {
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
-        sb.append("BillingExceptionBase");
         sb.append("{cause=").append(cause);
         sb.append(", code=").append(code);
         sb.append(", formattedMsg='").append(formattedMsg).append('\'');
diff --git a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
index b67e847..7fcf838 100644
--- a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
+++ b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
@@ -23,9 +23,11 @@ public enum ObjectType {
     INVOICE("invoice"),
     PAYMENT("payment"),
     INVOICE_ITEM("invoice item"),
+    INVOICE_PAYMENT("invoice payment"),
     SUBSCRIPTION("subscription"),
     PAYMENT_METHOD("payment method"),
-    REFUND("refund");
+    REFUND("refund"),
+    TAG_DEFINITION("tag definition");
 
     private final String objectName;
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
index 4ba56e6..86ce645 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
@@ -13,10 +13,13 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.json;
 
 import javax.annotation.Nullable;
 
+import com.ning.billing.util.tag.TagDefinition;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
@@ -26,20 +29,19 @@ public class TagDefinitionJson {
     private final String name;
     private final String description;
 
-    public TagDefinitionJson() {
-        this(null, null, null);
-    }
-
     @JsonCreator
     public TagDefinitionJson(@JsonProperty("id") final String id,
-            @JsonProperty("name") final String name,
-            @JsonProperty("description") @Nullable final String description) {
-        super();
+                             @JsonProperty("name") final String name,
+                             @JsonProperty("description") @Nullable final String description) {
         this.id = id;
         this.name = name;
         this.description = description;
     }
 
+    public TagDefinitionJson(final TagDefinition tagDefinition) {
+        this(tagDefinition.getId().toString(), tagDefinition.getName(), tagDefinition.getDescription());
+    }
+
     public String getId() {
         return id;
     }
@@ -57,10 +59,10 @@ public class TagDefinitionJson {
         final int prime = 31;
         int result = 1;
         result = prime * result
-                + ((description == null) ? 0 : description.hashCode());
+                 + ((description == null) ? 0 : description.hashCode());
         result = prime * result + ((name == null) ? 0 : name.hashCode());
         result = prime * result
-                + ((id == null) ? 0 : id.hashCode());
+                 + ((id == null) ? 0 : id.hashCode());
         return result;
     }
 
@@ -85,7 +87,6 @@ public class TagDefinitionJson {
         return true;
     }
 
-
     @Override
     public boolean equals(Object obj) {
         if (!equalsNoId(obj)) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/AccountApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/AccountApiExceptionMapper.java
new file mode 100644
index 0000000..7daeea2
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/AccountApiExceptionMapper.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.account.api.AccountApiException;
+
+@Singleton
+@Provider
+public class AccountApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<AccountApiException> {
+
+    private final UriInfo uriInfo;
+
+    public AccountApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final AccountApiException exception) {
+        if (exception.getCode() == ErrorCode.ACCOUNT_ALREADY_EXISTS.getCode()) {
+            return buildConflictingRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_CANNOT_CHANGE_EXTERNAL_KEY.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_CANNOT_MAP_NULL_KEY.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_CREATION_FAILED.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_INVALID_NAME.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ACCOUNT_UPDATE_FAILED.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BillingExceptionBaseMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BillingExceptionBaseMapper.java
new file mode 100644
index 0000000..fc19514
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BillingExceptionBaseMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.BillingExceptionBase;
+
+@Singleton
+@Provider
+public class BillingExceptionBaseMapper extends ExceptionMapperBase implements ExceptionMapper<BillingExceptionBase> {
+
+    private final UriInfo uriInfo;
+
+    public BillingExceptionBaseMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final BillingExceptionBase exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BlockingApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BlockingApiExceptionMapper.java
new file mode 100644
index 0000000..cf38364
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/BlockingApiExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.junction.api.BlockingApiException;
+
+@Singleton
+@Provider
+public class BlockingApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<BlockingApiException> {
+
+    private final UriInfo uriInfo;
+
+    public BlockingApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final BlockingApiException exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CatalogApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CatalogApiExceptionMapper.java
new file mode 100644
index 0000000..7a4cf86
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CatalogApiExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.catalog.api.CatalogApiException;
+
+@Singleton
+@Provider
+public class CatalogApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<CatalogApiException> {
+
+    private final UriInfo uriInfo;
+
+    public CatalogApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final CatalogApiException exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CurrencyValueNullMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CurrencyValueNullMapper.java
new file mode 100644
index 0000000..6ec1e78
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/CurrencyValueNullMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.catalog.api.CurrencyValueNull;
+
+@Singleton
+@Provider
+public class CurrencyValueNullMapper extends ExceptionMapperBase implements ExceptionMapper<CurrencyValueNull> {
+
+    private final UriInfo uriInfo;
+
+    public CurrencyValueNullMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final CurrencyValueNull exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EmailApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EmailApiExceptionMapper.java
new file mode 100644
index 0000000..2b47f7a
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EmailApiExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.util.email.EmailApiException;
+
+@Singleton
+@Provider
+public class EmailApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<EmailApiException> {
+
+    private final UriInfo uriInfo;
+
+    public EmailApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final EmailApiException exception) {
+        return buildInternalErrorResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementBillingApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementBillingApiExceptionMapper.java
new file mode 100644
index 0000000..9ca7de6
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementBillingApiExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+
+@Singleton
+@Provider
+public class EntitlementBillingApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<EntitlementBillingApiException> {
+
+    private final UriInfo uriInfo;
+
+    public EntitlementBillingApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final EntitlementBillingApiException exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementRepairExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementRepairExceptionMapper.java
new file mode 100644
index 0000000..dd9bd89
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementRepairExceptionMapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
+
+@Singleton
+@Provider
+public class EntitlementRepairExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<EntitlementRepairException> {
+
+    private final UriInfo uriInfo;
+
+    public EntitlementRepairExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final EntitlementRepairException exception) {
+        if (exception.getCode() == ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_INVALID_DELETE_SET.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_NON_EXISTENT_DELETE_EVENT.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_SUB_EMPTY.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_SUB_RECREATE_NOT_EMPTY.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_UNKNOWN_SUBSCRIPTION.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_UNKNOWN_TYPE.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_REPAIR_VIEW_CHANGED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementUserApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementUserApiExceptionMapper.java
new file mode 100644
index 0000000..2efbfd1
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntitlementUserApiExceptionMapper.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+
+@Singleton
+@Provider
+public class EntitlementUserApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<EntitlementUserApiException> {
+
+    private final UriInfo uriInfo;
+
+    public EntitlementUserApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final EntitlementUserApiException exception) {
+        if (exception.getCode() == ErrorCode.ENT_ACCOUNT_IS_OVERDUE_BLOCKED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_BUNDLE_IS_OVERDUE_BLOCKED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CANCEL_BAD_STATE.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CHANGE_DRY_RUN_NOT_BP.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CHANGE_FUTURE_CANCELLED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CHANGE_NON_ACTIVE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_AO_ALREADY_INCLUDED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_AO_BP_NON_ACTIVE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_AO_NOT_AVAILABLE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_BAD_PHASE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_BP_EXISTS.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_NO_BP.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_CREATE_NO_BUNDLE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_KEY.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_GET_NO_BUNDLE_FOR_SUBSCRIPTION.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_INVALID_REQUESTED_DATE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_INVALID_REQUESTED_FUTURE_DATE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.ENT_RECREATE_BAD_STATE.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        }  else if (exception.getCode() == ErrorCode.ENT_UNCANCEL_BAD_STATE.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntityPersistenceExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntityPersistenceExceptionMapper.java
new file mode 100644
index 0000000..b68f6ad
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/EntityPersistenceExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+@Singleton
+@Provider
+public class EntityPersistenceExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<EntityPersistenceException> {
+
+    private final UriInfo uriInfo;
+
+    public EntityPersistenceExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final EntityPersistenceException exception) {
+        return buildInternalErrorResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java
new file mode 100644
index 0000000..d803d10
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class ExceptionMapperBase {
+
+    private static final Logger log = LoggerFactory.getLogger(ExceptionMapperBase.class);
+
+    protected Response buildConflictingRequestResponse(final Exception e, final UriInfo uriInfo) {
+        return buildConflictingRequestResponse(e.toString(), uriInfo);
+    }
+
+    protected Response buildConflictingRequestResponse(final String error, final UriInfo uriInfo) {
+        log.warn("Conflicting request for {}: {}", uriInfo.getRequestUri(), error);
+        return Response.status(Status.CONFLICT)
+                       .entity(error)
+                       .type(MediaType.TEXT_PLAIN_TYPE)
+                       .build();
+    }
+
+    protected Response buildNotFoundResponse(final Exception e, final UriInfo uriInfo) {
+        return buildNotFoundResponse(e.toString(), uriInfo);
+    }
+
+    protected Response buildNotFoundResponse(final String error, final UriInfo uriInfo) {
+        log.warn("Not found for {}: {}", uriInfo.getRequestUri(), error);
+        return Response.status(Status.NOT_FOUND)
+                       .entity(error)
+                       .type(MediaType.TEXT_PLAIN_TYPE)
+                       .build();
+    }
+
+    protected Response buildBadRequestResponse(final Exception e, final UriInfo uriInfo) {
+        return buildBadRequestResponse(e.toString(), uriInfo);
+    }
+
+    protected Response buildBadRequestResponse(final String error, final UriInfo uriInfo) {
+        log.warn("Bad request for {}: {}", uriInfo.getRequestUri(), error);
+        return Response.status(Status.BAD_REQUEST)
+                       .entity(error)
+                       .type(MediaType.TEXT_PLAIN_TYPE)
+                       .build();
+    }
+
+    protected Response buildInternalErrorResponse(final Exception e, final UriInfo uriInfo) {
+        return buildInternalErrorResponse(e.toString(), uriInfo);
+    }
+
+    protected Response buildInternalErrorResponse(final String error, final UriInfo uriInfo) {
+        log.warn("Internal error for {}: {}", uriInfo.getRequestUri(), error);
+        return Response.status(Status.INTERNAL_SERVER_ERROR)
+                       .entity(error)
+                       .type(MediaType.TEXT_PLAIN_TYPE)
+                       .build();
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalArgumentExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalArgumentExceptionMapper.java
new file mode 100644
index 0000000..b859b31
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalArgumentExceptionMapper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+@Singleton
+@Provider
+public class IllegalArgumentExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<IllegalArgumentException> {
+
+    private final UriInfo uriInfo;
+
+    public IllegalArgumentExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final IllegalArgumentException exception) {
+        // Likely bad UUID String
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalPlanChangeMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalPlanChangeMapper.java
new file mode 100644
index 0000000..cab1d81
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/IllegalPlanChangeMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.catalog.api.IllegalPlanChange;
+
+@Singleton
+@Provider
+public class IllegalPlanChangeMapper extends ExceptionMapperBase implements ExceptionMapper<IllegalPlanChange> {
+
+    private final UriInfo uriInfo;
+
+    public IllegalPlanChangeMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final IllegalPlanChange exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/InvoiceApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/InvoiceApiExceptionMapper.java
new file mode 100644
index 0000000..85c3bb2
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/InvoiceApiExceptionMapper.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.invoice.api.InvoiceApiException;
+
+@Singleton
+@Provider
+public class InvoiceApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<InvoiceApiException> {
+
+    private final UriInfo uriInfo;
+
+    public InvoiceApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final InvoiceApiException exception) {
+        if (exception.getCode() == ErrorCode.INVOICE_ACCOUNT_ID_INVALID.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_INVALID_DATE_SEQUENCE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_INVALID_TRANSITION.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_NO_SUCH_CREDIT.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_NOT_FOUND.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_PAYMENT_BY_ATTEMPT_NOT_FOUND.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_PAYMENT_NOT_FOUND.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_TARGET_DATE_TOO_FAR_IN_THE_FUTURE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueApiExceptionMapper.java
new file mode 100644
index 0000000..bbfac5f
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueApiExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.overdue.OverdueApiException;
+
+@Singleton
+@Provider
+public class OverdueApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<OverdueApiException> {
+
+    private final UriInfo uriInfo;
+
+    public OverdueApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final OverdueApiException exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueErrorMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueErrorMapper.java
new file mode 100644
index 0000000..98ac732
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/OverdueErrorMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.overdue.config.api.OverdueError;
+
+@Singleton
+@Provider
+public class OverdueErrorMapper extends ExceptionMapperBase implements ExceptionMapper<OverdueError> {
+
+    private final UriInfo uriInfo;
+
+    public OverdueErrorMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final OverdueError exception) {
+        return buildBadRequestResponse(exception, uriInfo);
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/PaymentApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/PaymentApiExceptionMapper.java
new file mode 100644
index 0000000..551f0d2
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/PaymentApiExceptionMapper.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.payment.api.PaymentApiException;
+
+@Singleton
+@Provider
+public class PaymentApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<PaymentApiException> {
+
+    private final UriInfo uriInfo;
+
+    public PaymentApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final PaymentApiException exception) {
+        if (exception.getCode() == ErrorCode.PAYMENT_ADD_PAYMENT_METHOD.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_AMOUNT_DENIED.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_BAD_ACCOUNT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_PAYMENT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_BAD.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_WITH_NON_POSITIVE_INV.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_PAYMENT_PROVIDER_ACCOUNT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_CREATE_REFUND.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_DEL_DEFAULT_PAYMENT_METHOD.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_DEL_PAYMENT_METHOD.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_GET_PAYMENT_METHODS.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_GET_PAYMENT_PROVIDER.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_GET_PAYMENT_PROVIDER_ACCOUNT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_INTERNAL_ERROR.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_PAYMENT_METHODS.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_SUCH_PAYMENT.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_SUCH_REFUND.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NO_SUCH_SUCCESS_PAYMENT.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_NULL_INVOICE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_PLUGIN_ACCOUNT_INIT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_PLUGIN_TIMEOUT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_REFRESH_PAYMENT_METHOD.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_REFUND_AMOUNT_TOO_LARGE.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_UPD_GATEWAY_FAILED.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_UPD_PAYMENT_METHOD.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.PAYMENT_UPD_PAYMENT_PROVIDER_ACCOUNT.getCode()) {
+            return buildInternalErrorResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/RuntimeExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/RuntimeExceptionMapper.java
new file mode 100644
index 0000000..e8e3c61
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/RuntimeExceptionMapper.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+@Singleton
+@Provider
+public class RuntimeExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<RuntimeException> {
+
+    private final UriInfo uriInfo;
+
+    public RuntimeExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final RuntimeException exception) {
+        if (exception instanceof NullPointerException) {
+            // Assume bad payload
+            return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception instanceof WebApplicationException) {
+            // e.g. com.sun.jersey.api.NotFoundException
+            return ((WebApplicationException) exception).getResponse();
+        } else {
+            return buildInternalErrorResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagApiExceptionMapper.java
new file mode 100644
index 0000000..bcd1220
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagApiExceptionMapper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.util.api.TagApiException;
+
+@Singleton
+@Provider
+public class TagApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<TagApiException> {
+
+    private final UriInfo uriInfo;
+
+    public TagApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final TagApiException exception) {
+        if (exception.getCode() == ErrorCode.TAG_DOES_NOT_EXIST.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagDefinitionApiExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagDefinitionApiExceptionMapper.java
new file mode 100644
index 0000000..741a263
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/TagDefinitionApiExceptionMapper.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.util.api.TagDefinitionApiException;
+
+@Singleton
+@Provider
+public class TagDefinitionApiExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<TagDefinitionApiException> {
+
+    private final UriInfo uriInfo;
+
+    public TagDefinitionApiExceptionMapper(@Context final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response toResponse(final TagDefinitionApiException exception) {
+        if (exception.getCode() == ErrorCode.TAG_DEFINITION_ALREADY_EXISTS.getCode()) {
+            return buildConflictingRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.TAG_DEFINITION_CONFLICTS_WITH_CONTROL_TAG.getCode()) {
+            return buildConflictingRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.TAG_DEFINITION_IN_USE.getCode()) {
+            return buildBadRequestResponse(exception, uriInfo);
+        } else {
+            return buildBadRequestResponse(exception, uriInfo);
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index d251e80..25eaf57 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -38,10 +37,6 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
@@ -74,13 +69,14 @@ import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.Refund;
 import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Collections2;
-import com.google.common.collect.LinkedListMultimap;
 import com.google.common.collect.Multimap;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -91,7 +87,6 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 @Path(JaxrsResource.ACCOUNTS_PATH)
 public class AccountResource extends JaxRsResourceBase {
 
-    private static final Logger log = LoggerFactory.getLogger(AccountResource.class);
     private static final String ID_PARAM_NAME = "accountId";
 
     private final AccountUserApi accountApi;
@@ -101,7 +96,6 @@ public class AccountResource extends JaxRsResourceBase {
     private final InvoicePaymentApi invoicePaymentApi;
     private final PaymentApi paymentApi;
     private final Context context;
-    private final JaxrsUriBuilder uriBuilder;
 
     @Inject
     public AccountResource(final JaxrsUriBuilder uriBuilder,
@@ -111,11 +105,10 @@ public class AccountResource extends JaxRsResourceBase {
                            final InvoicePaymentApi invoicePaymentApi,
                            final PaymentApi paymentApi,
                            final EntitlementTimelineApi timelineApi,
-                           final CustomFieldUserApi customFieldUserApi,
                            final TagUserApi tagUserApi,
+                           final CustomFieldUserApi customFieldUserApi,
                            final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi);
-        this.uriBuilder = uriBuilder;
         this.accountApi = accountApi;
         this.entitlementApi = entitlementApi;
         this.invoiceApi = invoiceApi;
@@ -128,67 +121,37 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getAccount(@PathParam("accountId") final String accountId) {
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-
-            final AccountJson json = new AccountJson(account);
-            return Response.status(Status.OK).entity(json).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+    public Response getAccount(@PathParam("accountId") final String accountId) throws AccountApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
 
+        final AccountJson json = new AccountJson(account);
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + BUNDLES)
     @Produces(APPLICATION_JSON)
-    public Response getAccountBundles(@PathParam("accountId") final String accountId) {
-        try {
-            final UUID uuid = UUID.fromString(accountId);
-            accountApi.getAccountById(uuid);
-
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid);
-            final Collection<BundleJsonNoSubscriptions> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJsonNoSubscriptions>() {
-                @Override
-                public BundleJsonNoSubscriptions apply(final SubscriptionBundle input) {
-                    return new BundleJsonNoSubscriptions(input);
-                }
-            });
-            return Response.status(Status.OK).entity(result).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
+    public Response getAccountBundles(@PathParam("accountId") final String accountId) throws AccountApiException {
+        final UUID uuid = UUID.fromString(accountId);
+        accountApi.getAccountById(uuid);
+
+        final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid);
+        final Collection<BundleJsonNoSubscriptions> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJsonNoSubscriptions>() {
+            @Override
+            public BundleJsonNoSubscriptions apply(final SubscriptionBundle input) {
+                return new BundleJsonNoSubscriptions(input);
             }
-        }
+        });
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @GET
     @Produces(APPLICATION_JSON)
-    public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey) {
-        try {
-            Account account = null;
-            if (externalKey != null) {
-                account = accountApi.getAccountByKey(externalKey);
-            }
-            if (account == null) {
-                return Response.status(Status.NO_CONTENT).build();
-            }
-            final AccountJson json = new AccountJson(account);
-            return Response.status(Status.OK).entity(json).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+    public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey) throws AccountApiException {
+        final Account account = accountApi.getAccountByKey(externalKey);
+        final AccountJson json = new AccountJson(account);
+
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @POST
@@ -197,19 +160,10 @@ public class AccountResource extends JaxRsResourceBase {
     public Response createAccount(final AccountJson json,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
-                                  @HeaderParam(HDR_COMMENT) final String comment) {
-
-        try {
-            final AccountData data = json.toAccountData();
-            final Account account = accountApi.createAccount(data, context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
-        } catch (AccountApiException e) {
-            final String error = String.format("Failed to create account %s", json);
-            log.info(error, e);
-            return Response.status(Status.BAD_REQUEST).entity(error).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                  @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+        final AccountData data = json.toAccountData();
+        final Account account = accountApi.createAccount(data, context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
     }
 
     @PUT
@@ -220,22 +174,11 @@ public class AccountResource extends JaxRsResourceBase {
                                   @PathParam("accountId") final String accountId,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
-                                  @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final AccountData data = json.toAccountData();
-            final UUID uuid = UUID.fromString(accountId);
-            accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment));
-            return getAccount(accountId);
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                log.info(String.format("Failed to update account %s with %s", accountId, json), e);
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                  @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+        final AccountData data = json.toAccountData();
+        final UUID uuid = UUID.fromString(accountId);
+        accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment));
+        return getAccount(accountId);
     }
 
     // Not supported
@@ -258,55 +201,41 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TIMELINE)
     @Produces(APPLICATION_JSON)
-    public Response getAccountTimeline(@PathParam("accountId") final String accountIdString) {
-        try {
-            final UUID accountId = UUID.fromString(accountIdString);
-            final Account account = accountApi.getAccountById(accountId);
+    public Response getAccountTimeline(@PathParam("accountId") final String accountIdString) throws AccountApiException, PaymentApiException, EntitlementRepairException {
+        final UUID accountId = UUID.fromString(accountIdString);
+        final Account account = accountApi.getAccountById(accountId);
 
-            // Get the invoices
-            final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        // Get the invoices
+        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
 
-            // Get the payments
-            final List<Payment> payments = paymentApi.getAccountPayments(accountId);
+        // Get the payments
+        final List<Payment> payments = paymentApi.getAccountPayments(accountId);
 
-            // Get the refunds
-            final List<Refund> refunds = paymentApi.getAccountRefunds(account);
-            final Multimap<UUID, Refund> refundsByPayment = ArrayListMultimap.<UUID, Refund>create();
-            for (final Refund refund : refunds) {
-                refundsByPayment.put(refund.getPaymentId(), refund);
-            }
+        // Get the refunds
+        final List<Refund> refunds = paymentApi.getAccountRefunds(account);
+        final Multimap<UUID, Refund> refundsByPayment = ArrayListMultimap.<UUID, Refund>create();
+        for (final Refund refund : refunds) {
+            refundsByPayment.put(refund.getPaymentId(), refund);
+        }
 
-            // Get the chargebacks
-            final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(accountId);
-            final Multimap<UUID, InvoicePayment> chargebacksByPayment = ArrayListMultimap.<UUID, InvoicePayment>create();
-            for (final InvoicePayment chargeback : chargebacks) {
-                chargebacksByPayment.put(chargeback.getPaymentId(), chargeback);
-            }
+        // Get the chargebacks
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(accountId);
+        final Multimap<UUID, InvoicePayment> chargebacksByPayment = ArrayListMultimap.<UUID, InvoicePayment>create();
+        for (final InvoicePayment chargeback : chargebacks) {
+            chargebacksByPayment.put(chargeback.getPaymentId(), chargeback);
+        }
 
-            // Get the bundles
-            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
-            final List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
-            for (final SubscriptionBundle cur : bundles) {
-                bundlesTimeline.add(timelineApi.getBundleRepair(cur.getId()));
-            }
+        // Get the bundles
+        final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
+        final List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
+        for (final SubscriptionBundle cur : bundles) {
+            bundlesTimeline.add(timelineApi.getBundleRepair(cur.getId()));
+        }
 
-            final AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline,
-                                                                     refundsByPayment, chargebacksByPayment);
+        final AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline,
+                                                                 refundsByPayment, chargebacksByPayment);
 
-            return Response.status(Status.OK).entity(json).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        } catch (PaymentApiException e) {
-            log.error(e.getMessage());
-            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
-        } catch (EntitlementRepairException e) {
-            log.error(e.getMessage());
-            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
-        }
+        return Response.status(Status.OK).entity(json).build();
     }
 
     /*
@@ -316,19 +245,11 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
     @Produces(APPLICATION_JSON)
-    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountId) {
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, account.isNotifiedForInvoices());
+    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountId) throws AccountApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+        final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, account.isNotifiedForInvoices());
 
-            return Response.status(Status.OK).entity(invoiceEmailJson).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+        return Response.status(Status.OK).entity(invoiceEmailJson).build();
     }
 
     @PUT
@@ -339,23 +260,15 @@ public class AccountResource extends JaxRsResourceBase {
                                                     @PathParam("accountId") final String accountIdString,
                                                     @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                     @HeaderParam(HDR_REASON) final String reason,
-                                                    @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final UUID accountId = UUID.fromString(accountIdString);
-            final Account account = accountApi.getAccountById(accountId);
+                                                    @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+        final UUID accountId = UUID.fromString(accountIdString);
+        final Account account = accountApi.getAccountById(accountId);
 
-            final MutableAccountData mutableAccountData = account.toMutableAccountData();
-            mutableAccountData.setIsNotifiedForInvoices(json.isNotifiedForInvoices());
-            accountApi.updateAccount(accountId, mutableAccountData, context.createContext(createdBy, reason, comment));
+        final MutableAccountData mutableAccountData = account.toMutableAccountData();
+        mutableAccountData.setIsNotifiedForInvoices(json.isNotifiedForInvoices());
+        accountApi.updateAccount(accountId, mutableAccountData, context.createContext(createdBy, reason, comment));
 
-            return Response.status(Status.OK).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+        return Response.status(Status.OK).build();
     }
 
     /*
@@ -367,17 +280,13 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getPayments(@PathParam("accountId") final String accountId,
                                 @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-                                @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
-        try {
-            final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
-            final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
-            for (final Payment cur : payments) {
-                result.add(new PaymentJsonSimple(cur));
-            }
-            return Response.status(Status.OK).entity(result).build();
-        } catch (PaymentApiException e) {
-            return Response.status(Status.BAD_REQUEST).build();
+                                @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) throws PaymentApiException {
+        final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
+        final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
+        for (final Payment cur : payments) {
+            result.add(new PaymentJsonSimple(cur));
         }
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @POST
@@ -389,26 +298,12 @@ public class AccountResource extends JaxRsResourceBase {
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
-                                        @javax.ws.rs.core.Context final UriInfo uriInfo) {
-        try {
-            final PaymentMethod data = json.toPaymentMethod();
-            final Account account = accountApi.getAccountById(data.getAccountId());
+                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, PaymentApiException {
+        final PaymentMethod data = json.toPaymentMethod();
+        final Account account = accountApi.getAccountById(data.getAccountId());
 
-            final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(PaymentMethodResource.class, "getPaymentMethod", paymentMethodId, uriInfo.getBaseUri().toString());
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        } catch (PaymentApiException e) {
-            final String error = String.format("Failed to create payment Method  %s", json);
-            log.info(error, e);
-            return Response.status(Status.BAD_REQUEST).entity(error).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+        final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(PaymentMethodResource.class, "getPaymentMethod", paymentMethodId, uriInfo.getBaseUri().toString());
     }
 
     @GET
@@ -417,28 +312,17 @@ public class AccountResource extends JaxRsResourceBase {
     public Response getPaymentMethods(@PathParam("accountId") final String accountId,
                                       @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                       @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-                                      @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
-
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
-            final List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
-                @Override
-                public PaymentMethodJson apply(final PaymentMethod input) {
-                    return PaymentMethodJson.toPaymentMethodJson(account, input);
-                }
-            }));
-            return Response.status(Status.OK).entity(json).build();
-
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NOT_FOUND).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
+                                      @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) throws AccountApiException, PaymentApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+        final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
+        final List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
+            @Override
+            public PaymentMethodJson apply(final PaymentMethod input) {
+                return PaymentMethodJson.toPaymentMethodJson(account, input);
             }
-        }
+        }));
+
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @PUT
@@ -449,22 +333,10 @@ public class AccountResource extends JaxRsResourceBase {
                                             @PathParam("paymentMethodId") final String paymentMethodId,
                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                             @HeaderParam(HDR_REASON) final String reason,
-                                            @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
-            return Response.status(Status.OK).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NOT_FOUND).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                            @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, PaymentApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+        paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
+        return Response.status(Status.OK).build();
     }
 
     /*
@@ -473,27 +345,17 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + REFUNDS)
     @Produces(APPLICATION_JSON)
-    public Response getRefunds(@PathParam("accountId") final String accountId) {
-
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            List<Refund> refunds = paymentApi.getAccountRefunds(account);
-            List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
-                @Override
-                public RefundJson apply(Refund input) {
-                    return new RefundJson(input);
-                }
-            }));
-            return Response.status(Status.OK).entity(result).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
+    public Response getRefunds(@PathParam("accountId") final String accountId) throws AccountApiException, PaymentApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+        final List<Refund> refunds = paymentApi.getAccountRefunds(account);
+        final List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
+            @Override
+            public RefundJson apply(Refund input) {
+                return new RefundJson(input);
             }
-        } catch (PaymentApiException e) {
-            return Response.status(Status.BAD_REQUEST).build();
-        }
+        }));
+
+        return Response.status(Status.OK).entity(result).build();
     }
 
     /*
@@ -540,7 +402,7 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TAGS)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) throws TagDefinitionApiException {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -552,7 +414,7 @@ public class AccountResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -565,8 +427,7 @@ public class AccountResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) {
-
+                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -586,7 +447,7 @@ public class AccountResource extends JaxRsResourceBase {
         for (final AccountEmail email : emails) {
             emailsJson.add(new AccountEmailJson(email.getAccountId().toString(), email.getEmail()));
         }
-        return Response.status(Response.Status.OK).entity(emailsJson).build();
+        return Response.status(Status.OK).entity(emailsJson).build();
     }
 
     @POST
@@ -597,27 +458,15 @@ public class AccountResource extends JaxRsResourceBase {
                              @PathParam(ID_PARAM_NAME) final String id,
                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                              @HeaderParam(HDR_REASON) final String reason,
-                             @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final UUID accountId = UUID.fromString(id);
+                             @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException {
+        final UUID accountId = UUID.fromString(id);
 
-            // Make sure the account exist or we will confuse the history and auditing code
-            if (accountApi.getAccountById(accountId) == null) {
-                return Response.status(Response.Status.BAD_REQUEST).entity("Account id " + accountId + " does not exist").build();
-            }
+        // Make sure the account exist or we will confuse the history and auditing code
+        accountApi.getAccountById(accountId);
 
-            accountApi.addEmail(accountId, json.toAccountEmail(), context.createContext(createdBy, reason, comment));
+        accountApi.addEmail(accountId, json.toAccountEmail(), context.createContext(createdBy, reason, comment));
 
-            return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
-        } catch (RuntimeException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-            }
-        }
+        return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
     }
 
     @DELETE
@@ -628,16 +477,12 @@ public class AccountResource extends JaxRsResourceBase {
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                 @HeaderParam(HDR_REASON) final String reason,
                                 @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final UUID accountId = UUID.fromString(id);
-            final AccountEmailJson accountEmailJson = new AccountEmailJson(id, email);
-            final AccountEmail accountEmail = accountEmailJson.toAccountEmail();
-            accountApi.removeEmail(accountId, accountEmail, context.createContext(createdBy, reason, comment));
-
-            return Response.status(Response.Status.OK).build();
-        } catch (RuntimeException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+        final UUID accountId = UUID.fromString(id);
+        final AccountEmailJson accountEmailJson = new AccountEmailJson(id, email);
+        final AccountEmail accountEmail = accountEmailJson.toAccountEmail();
+        accountApi.removeEmail(accountId, accountEmail, context.createContext(createdBy, reason, comment));
+
+        return Response.status(Status.OK).build();
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
index 3538696..44e5e77 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -26,19 +30,9 @@ 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.UriInfo;
 import javax.ws.rs.core.Response.Status;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.ws.rs.core.UriInfo;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -49,15 +43,20 @@ import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.BUNDLES_PATH)
 public class BundleResource extends JaxRsResourceBase {
 
-    private static final Logger log = LoggerFactory.getLogger(BundleResource.class);
     private static final String ID_PARAM_NAME = "bundleId";
     private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS;
     private static final String TAG_URI = JaxrsResource.TAGS;
@@ -67,8 +66,10 @@ public class BundleResource extends JaxRsResourceBase {
     private final JaxrsUriBuilder uriBuilder;
 
     @Inject
-    public BundleResource(final JaxrsUriBuilder uriBuilder, final EntitlementUserApi entitlementApi,
-                          final TagUserApi tagUserApi, final CustomFieldUserApi customFieldUserApi,
+    public BundleResource(final JaxrsUriBuilder uriBuilder,
+                          final EntitlementUserApi entitlementApi,
+                          final TagUserApi tagUserApi,
+                          final CustomFieldUserApi customFieldUserApi,
                           final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi);
         this.uriBuilder = uriBuilder;
@@ -80,35 +81,17 @@ public class BundleResource extends JaxRsResourceBase {
     @Path("/{bundleId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getBundle(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
-        try {
-            final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
-            final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
-            return Response.status(Status.OK).entity(json).build();
-        } catch (EntitlementUserApiException e) {
-            if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                throw e;
-            }
-
-        }
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
+        final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @GET
     @Produces(APPLICATION_JSON)
     public Response getBundleByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey) throws EntitlementUserApiException {
-        try {
-            final SubscriptionBundle bundle = entitlementApi.getBundleForKey(externalKey);
-            final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
-            return Response.status(Status.OK).entity(json).build();
-        } catch (EntitlementUserApiException e) {
-            if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_KEY.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                throw e;
-            }
-
-        }
+        final SubscriptionBundle bundle = entitlementApi.getBundleForKey(externalKey);
+        final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @POST
@@ -117,46 +100,30 @@ public class BundleResource extends JaxRsResourceBase {
     public Response createBundle(final BundleJsonNoSubscriptions json,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
-                                 @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final UUID accountId = UUID.fromString(json.getAccountId());
-            final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(),
-                                                                                    context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(BundleResource.class, "getBundle", bundle.getId());
-        } catch (EntitlementUserApiException e) {
-            log.info(String.format("Failed to create bundle %s", json), e);
-            return Response.status(Status.BAD_REQUEST).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                 @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+        final UUID accountId = UUID.fromString(json.getAccountId());
+        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(),
+                                                                                context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(BundleResource.class, "getBundle", bundle.getId());
     }
 
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + SUBSCRIPTIONS)
     @Produces(APPLICATION_JSON)
     public Response getBundleSubscriptions(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
-        try {
-            final UUID uuid = UUID.fromString(bundleId);
-            final SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid);
-            if (bundle == null) {
-                return Response.status(Status.NO_CONTENT).build();
-            }
-            final List<Subscription> bundles = entitlementApi.getSubscriptionsForBundle(uuid);
-            final Collection<SubscriptionJsonNoEvents> result = Collections2.transform(bundles, new Function<Subscription, SubscriptionJsonNoEvents>() {
-                @Override
-                public SubscriptionJsonNoEvents apply(final Subscription input) {
-                    return new SubscriptionJsonNoEvents(input);
-                }
-            });
-            return Response.status(Status.OK).entity(result).build();
-        } catch (EntitlementUserApiException e) {
-            if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                throw e;
-            }
-
+        final UUID uuid = UUID.fromString(bundleId);
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid);
+        if (bundle == null) {
+            return Response.status(Status.NO_CONTENT).build();
         }
+        final List<Subscription> bundles = entitlementApi.getSubscriptionsForBundle(uuid);
+        final Collection<SubscriptionJsonNoEvents> result = Collections2.transform(bundles, new Function<Subscription, SubscriptionJsonNoEvents>() {
+            @Override
+            public SubscriptionJsonNoEvents apply(final Subscription input) {
+                return new SubscriptionJsonNoEvents(input);
+            }
+        });
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @GET
@@ -195,7 +162,7 @@ public class BundleResource extends JaxRsResourceBase {
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) throws TagDefinitionApiException {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -208,7 +175,7 @@ public class BundleResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -221,8 +188,7 @@ public class BundleResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) {
-
+                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
index 62d03e4..4fac93c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
@@ -16,6 +16,9 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -25,18 +28,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import com.ning.billing.ErrorCode;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
@@ -44,29 +37,29 @@ import com.ning.billing.jaxrs.json.ChargebackCollectionJson;
 import com.ning.billing.jaxrs.json.ChargebackJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
-import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.Payment.PaymentAttempt;
-import com.ning.billing.payment.api.PaymentApi;
-import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentStatus;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.dao.ObjectType;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.CHARGEBACKS_PATH)
-public class ChargebackResource implements JaxrsResource {
-    private static final Logger log = LoggerFactory.getLogger(ChargebackResource.class);
+public class ChargebackResource extends JaxRsResourceBase {
 
-    private final JaxrsUriBuilder uriBuilder;
     private final InvoicePaymentApi invoicePaymentApi;
     private final Context context;
 
     @Inject
     public ChargebackResource(final JaxrsUriBuilder uriBuilder,
                               final InvoicePaymentApi invoicePaymentApi,
-                              final PaymentApi paymentApi,
+                              final TagUserApi tagUserApi,
+                              final CustomFieldUserApi customFieldUserApi,
                               final Context context) {
-        this.uriBuilder = uriBuilder;
+        super(uriBuilder, tagUserApi, customFieldUserApi);
         this.invoicePaymentApi = invoicePaymentApi;
         this.context = context;
     }
@@ -74,17 +67,11 @@ public class ChargebackResource implements JaxrsResource {
     @GET
     @Path("/{chargebackId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getChargeback(@PathParam("chargebackId") final String chargebackId) {
-        try {
-            final InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId));
-            final ChargebackJson chargebackJson = new ChargebackJson(chargeback);
-
-            return Response.status(Response.Status.OK).entity(chargebackJson).build();
-        } catch (InvoiceApiException e) {
-            final String error = String.format("Failed to locate chargeback for id %s", chargebackId);
-            log.info(error, e);
-            return Response.status(Response.Status.NO_CONTENT).build();
-        }
+    public Response getChargeback(@PathParam("chargebackId") final String chargebackId) throws InvoiceApiException {
+        final InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId));
+        final ChargebackJson chargebackJson = new ChargebackJson(chargeback);
+
+        return Response.status(Response.Status.OK).entity(chargebackJson).build();
     }
 
     @GET
@@ -101,24 +88,18 @@ public class ChargebackResource implements JaxrsResource {
     @GET
     @Path("/payments/{paymentId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForPayment(@PathParam("paymentId") final String paymentId) {
-
-        try {
-            final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.fromString(paymentId));
-            if (chargebacks.size() == 0) {
-                return Response.status(Response.Status.NO_CONTENT).build();
-            }
-
-            final UUID invoicePaymentId = chargebacks.get(0).getId();
-            final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(invoicePaymentId).toString();
-            final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
-            final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
-
-            return Response.status(Response.Status.OK).entity(json).build();
-        } catch (InvoiceApiException e) {
-            final String error = String.format("Failed to locate account for payment id %s", paymentId);
-            return Response.status(Response.Status.NO_CONTENT).entity(error).build();
+    public Response getForPayment(@PathParam("paymentId") final String paymentId) throws InvoiceApiException {
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentId(UUID.fromString(paymentId));
+        if (chargebacks.size() == 0) {
+            return Response.status(Response.Status.NO_CONTENT).build();
         }
+
+        final UUID invoicePaymentId = chargebacks.get(0).getId();
+        final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(invoicePaymentId).toString();
+        final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
+        final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
+
+        return Response.status(Response.Status.OK).entity(json).build();
     }
 
     @POST
@@ -127,22 +108,15 @@ public class ChargebackResource implements JaxrsResource {
     public Response createChargeback(final ChargebackJson json,
                                      @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                      @HeaderParam(HDR_REASON) final String reason,
-                                     @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(UUID.fromString(json.getPaymentId()));
-            if (invoicePayment == null) {
-                final String error = String.format("Failed to locate invoice payment for paymentAttemptId %s", json.getPaymentId());
-                return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
-            }
-
-            final InvoicePayment chargeBack = invoicePaymentApi.createChargeback(invoicePayment.getId(), json.getChargebackAmount(),
-                                                                                  context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", chargeBack.getId());
-        } catch (InvoiceApiException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+                                     @HeaderParam(HDR_COMMENT) final String comment) throws InvoiceApiException {
+        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(UUID.fromString(json.getPaymentId()));
+        if (invoicePayment == null) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, json.getPaymentId());
         }
+
+        final InvoicePayment chargeBack = invoicePaymentApi.createChargeback(invoicePayment.getId(), json.getChargebackAmount(),
+                                                                             context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", chargeBack.getId());
     }
 
     private List<ChargebackJson> convertToJson(final List<InvoicePayment> chargebacks) {
@@ -153,4 +127,9 @@ public class ChargebackResource implements JaxrsResource {
 
         return result;
     }
+
+    @Override
+    protected ObjectType getObjectType() {
+        return ObjectType.INVOICE_PAYMENT;
+    }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
index a53a287..25a1775 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -25,14 +25,10 @@ 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.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.joda.time.LocalDate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
@@ -42,6 +38,9 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.jaxrs.json.CreditJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.dao.ObjectType;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -50,18 +49,20 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.CREDITS_PATH)
-public class CreditResource implements JaxrsResource {
+public class CreditResource extends JaxRsResourceBase {
 
-    private static final Logger log = LoggerFactory.getLogger(CreditResource.class);
-
-    private final JaxrsUriBuilder uriBuilder;
     private final InvoiceUserApi invoiceUserApi;
     private final AccountUserApi accountUserApi;
     private final Context context;
 
     @Inject
-    public CreditResource(final JaxrsUriBuilder uriBuilder, final InvoiceUserApi invoiceUserApi, final AccountUserApi accountUserApi, final Context context) {
-        this.uriBuilder = uriBuilder;
+    public CreditResource(final JaxrsUriBuilder uriBuilder,
+                          final InvoiceUserApi invoiceUserApi,
+                          final AccountUserApi accountUserApi,
+                          final TagUserApi tagUserApi,
+                          final CustomFieldUserApi customFieldUserApi,
+                          final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi);
         this.invoiceUserApi = invoiceUserApi;
         this.accountUserApi = accountUserApi;
         this.context = context;
@@ -70,22 +71,11 @@ public class CreditResource implements JaxrsResource {
     @GET
     @Path("/{creditId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getCredit(@PathParam("creditId") final String creditId) {
-        try {
-            final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
-            final Account account = accountUserApi.getAccountById(credit.getAccountId());
-            final CreditJson creditJson = new CreditJson(credit, account.getTimeZone());
-            return Response.status(Response.Status.OK).entity(creditJson).build();
-        } catch (InvoiceApiException e) {
-            if (e.getCode() == ErrorCode.INVOICE_NO_SUCH_CREDIT.getCode()) {
-                return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).type(MediaType.TEXT_PLAIN_TYPE).build();
-            } else {
-                return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN_TYPE).build();
-            }
-        } catch (AccountApiException e) {
-            log.warn(String.format("Failed to locate account for credit id %s", creditId), e);
-            return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).type(MediaType.TEXT_PLAIN_TYPE).build();
-        }
+    public Response getCredit(@PathParam("creditId") final String creditId) throws InvoiceApiException, AccountApiException {
+        final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
+        final Account account = accountUserApi.getAccountById(credit.getAccountId());
+        final CreditJson creditJson = new CreditJson(credit, account.getTimeZone());
+        return Response.status(Response.Status.OK).entity(creditJson).build();
     }
 
     @POST
@@ -94,38 +84,26 @@ public class CreditResource implements JaxrsResource {
     public Response createCredit(final CreditJson json,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
-                                 @HeaderParam(HDR_COMMENT) final String comment) {
-        final UUID accountId = json.getAccountId();
-        if (accountId == null) {
-            return Response.status(Response.Status.BAD_REQUEST).entity("AccountId cannot be null").build();
+                                 @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
+        final Account account = accountUserApi.getAccountById(json.getAccountId());
+        final LocalDate effectiveDate = json.getEffectiveDate().toDateTime(account.getTimeZone()).toLocalDate();
+
+        final InvoiceItem credit;
+        if (json.getInvoiceId() != null) {
+            // Apply an invoice level credit
+            credit = invoiceUserApi.insertCreditForInvoice(account.getId(), json.getInvoiceId(), json.getCreditAmount(),
+                                                           effectiveDate, account.getCurrency(), context.createContext(createdBy, reason, comment));
+        } else {
+            // Apply a account level credit
+            credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), effectiveDate,
+                                                 account.getCurrency(), context.createContext(createdBy, reason, comment));
         }
 
-        try {
-            final Account account = accountUserApi.getAccountById(accountId);
-            final LocalDate effectiveDate = json.getEffectiveDate().toDateTime(account.getTimeZone()).toLocalDate();
-
-            final InvoiceItem credit;
-            if (json.getInvoiceId() != null) {
-                // Apply an invoice level credit
-                credit = invoiceUserApi.insertCreditForInvoice(account.getId(), json.getInvoiceId(), json.getCreditAmount(),
-                                                               effectiveDate, account.getCurrency(), context.createContext(createdBy, reason, comment));
-            } else {
-                // Apply a account level credit
-                credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), effectiveDate,
-                                                     account.getCurrency(), context.createContext(createdBy, reason, comment));
-            }
+        return uriBuilder.buildResponse(CreditResource.class, "getCredit", credit.getId());
+    }
 
-            return uriBuilder.buildResponse(CreditResource.class, "getCredit", credit.getId());
-        } catch (InvoiceApiException e) {
-            final String error = String.format("Failed to create credit %s", json);
-            log.info(error, e);
-            return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (AccountApiException e) {
-            final String error = String.format("Failed to create credit %s", json);
-            log.info(error, e);
-            return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
-        }
+    @Override
+    protected ObjectType getObjectType() {
+        return ObjectType.INVOICE_ITEM;
     }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 22e0e04..7a9c201 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -16,6 +16,12 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -27,13 +33,8 @@ 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.UriInfo;
 import javax.ws.rs.core.Response.Status;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
+import javax.ws.rs.core.UriInfo;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
@@ -42,8 +43,6 @@ import org.joda.time.format.ISODateTimeFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -62,13 +61,16 @@ import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.inject.Inject;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static javax.ws.rs.core.MediaType.TEXT_HTML;
 
-
 @Path(JaxrsResource.INVOICES_PATH)
 public class InvoiceResource extends JaxRsResourceBase {
 
@@ -106,30 +108,27 @@ public class InvoiceResource extends JaxRsResourceBase {
 
     @GET
     @Produces(APPLICATION_JSON)
-    public Response getInvoices(@QueryParam(QUERY_ACCOUNT_ID) final String accountId) {
-        try {
-            Preconditions.checkNotNull(accountId, "% query parameter must be specified", QUERY_ACCOUNT_ID);
-            accountApi.getAccountById(UUID.fromString(accountId));
-            final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
-            final List<InvoiceJsonSimple> result = new LinkedList<InvoiceJsonSimple>();
-            for (final Invoice cur : invoices) {
-                result.add(new InvoiceJsonSimple(cur));
-            }
-            return Response.status(Status.OK).entity(result).build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (NullPointerException e) {
-            return Response.status(Status.BAD_REQUEST).build();
+    public Response getInvoices(@QueryParam(QUERY_ACCOUNT_ID) final String accountId) throws AccountApiException {
+        // Verify the account exists
+        accountApi.getAccountById(UUID.fromString(accountId));
+
+        final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
+        final List<InvoiceJsonSimple> result = new LinkedList<InvoiceJsonSimple>();
+        for (final Invoice cur : invoices) {
+            result.add(new InvoiceJsonSimple(cur));
         }
+
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @GET
     @Path("/{invoiceId:" + UUID_PATTERN + "}/")
     @Produces(APPLICATION_JSON)
-    public Response getInvoice(@PathParam("invoiceId") final String invoiceId, @QueryParam("withItems") @DefaultValue("false") final boolean withItems) {
+    public Response getInvoice(@PathParam("invoiceId") final String invoiceId,
+                               @QueryParam("withItems") @DefaultValue("false") final boolean withItems) throws InvoiceApiException {
         final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
         if (invoice == null) {
-            return Response.status(Status.NO_CONTENT).build();
+            throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND);
         } else {
             final InvoiceJsonSimple json = withItems ? new InvoiceJsonWithItems(invoice) : new InvoiceJsonSimple(invoice);
             return Response.status(Status.OK).entity(json).build();
@@ -139,16 +138,8 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Path("/{invoiceId:" + UUID_PATTERN + "}/html")
     @Produces(TEXT_HTML)
-    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId) {
-        try {
-            return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId))).build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (IOException e) {
-            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
-        } catch (InvoiceApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        }
+    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId) throws InvoiceApiException, IOException, AccountApiException {
+        return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId))).build();
     }
 
     @POST
@@ -159,51 +150,33 @@ public class InvoiceResource extends JaxRsResourceBase {
                                         @QueryParam(QUERY_DRY_RUN) @DefaultValue("false") final Boolean dryRun,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            Preconditions.checkNotNull(accountId, "% needs to be specified", QUERY_ACCOUNT_ID);
-            Preconditions.checkNotNull(targetDateTime, "% needs to be specified", QUERY_TARGET_DATE);
-
-            final DateTime inputDateTime = (targetDateTime != null) ? DATE_TIME_FORMATTER.parseDateTime(targetDateTime) : null;
-
-            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            final LocalDate inputDate = inputDateTime.toDateTime(account.getTimeZone()).toLocalDate();
-
-            final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun,
-                                                                                 context.createContext(createdBy, reason, comment));
-            if (dryRun) {
-                return Response.status(Status.OK).entity(new InvoiceJsonSimple(generatedInvoice)).build();
-            } else {
-                return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
-            }
-        } catch (InvoiceApiException e) {
-            if (e.getCode() == ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-            }
-        } catch (NullPointerException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (AccountApiException e) {
-            log.warn(String.format("Failed to locate account for id %s", accountId), e);
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+                                        @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, InvoiceApiException {
+        final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+
+        final DateTime inputDateTime = DATE_TIME_FORMATTER.parseDateTime(targetDateTime);
+        final LocalDate inputDate = inputDateTime.toDateTime(account.getTimeZone()).toLocalDate();
+
+        final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun,
+                                                                             context.createContext(createdBy, reason, comment));
+        if (dryRun) {
+            return Response.status(Status.OK).entity(new InvoiceJsonSimple(generatedInvoice)).build();
+        } else {
+            return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
         }
     }
 
     @GET
     @Path("/{invoiceId:" + UUID_PATTERN + "}/" + PAYMENTS)
     @Produces(APPLICATION_JSON)
-    public Response getPayments(@PathParam("invoiceId") final String invoiceId) {
-        try {
-            final List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId));
-            final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
-            for (final Payment cur : payments) {
-                result.add(new PaymentJsonSimple(cur));
-            }
-            return Response.status(Status.OK).entity(result).build();
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NOT_FOUND).build();
+    public Response getPayments(@PathParam("invoiceId") final String invoiceId) throws PaymentApiException {
+        final List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId));
+
+        final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
+        for (final Payment cur : payments) {
+            result.add(new PaymentJsonSimple(cur));
         }
+
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @POST
@@ -214,23 +187,14 @@ public class InvoiceResource extends JaxRsResourceBase {
                                          @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                          @HeaderParam(HDR_REASON) final String reason,
-                                         @HeaderParam(HDR_COMMENT) final String comment) {
+                                         @HeaderParam(HDR_COMMENT) final String comment) throws AccountApiException, PaymentApiException {
         if (externalPayment) {
             return Response.status(Status.BAD_REQUEST).entity("External payments have not been implemented yet").build();
         }
-        try {
-            final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
-            paymentApi.createPayment(account, UUID.fromString(payment.getInvoiceId()), null, context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
-        } catch (PaymentApiException e) {
-            final String error = String.format("Failed to create payment %s", e.getMessage());
-            return Response.status(Status.BAD_REQUEST).entity(error).build();
-        } catch (AccountApiException e) {
-            final String error = String.format("Failed to create payment, can't find account %s", payment.getAccountId());
-            return Response.status(Status.BAD_REQUEST).entity(error).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+
+        final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
+        paymentApi.createPayment(account, UUID.fromString(payment.getInvoiceId()), null, context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
     }
 
     @POST
@@ -240,25 +204,18 @@ public class InvoiceResource extends JaxRsResourceBase {
     public Response triggerEmailNotificationForInvoice(@PathParam("invoiceId") final String invoiceId,
                                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                        @HeaderParam(HDR_REASON) final String reason,
-                                                       @HeaderParam(HDR_COMMENT) final String comment) {
+                                                       @HeaderParam(HDR_COMMENT) final String comment) throws InvoiceApiException, AccountApiException {
         final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
         if (invoice == null) {
-            return Response.status(Status.NOT_FOUND).build();
+            throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND);
         }
 
-        try {
-            final Account account = accountApi.getAccountById(invoice.getAccountId());
+        final Account account = accountApi.getAccountById(invoice.getAccountId());
 
-            // Send the email (synchronous send)
-            invoiceNotifier.notify(account, invoice);
+        // Send the email (synchronous send)
+        invoiceNotifier.notify(account, invoice);
 
-            return Response.status(Status.OK).build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NOT_FOUND).build();
-        } catch (InvoiceApiException e) {
-            // Sending failed
-            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
-        }
+        return Response.status(Status.OK).build();
     }
 
     @GET
@@ -297,7 +254,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) throws TagDefinitionApiException {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -310,7 +267,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -323,8 +280,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) {
-
+                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
index 01463ea..e092c39 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -27,10 +23,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.util.api.CustomFieldUserApi;
@@ -44,8 +42,14 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
 public abstract class JaxRsResourceBase implements JaxrsResource {
 
+    private static final Logger log = LoggerFactory.getLogger(JaxRsResourceBase.class);
+
     protected final JaxrsUriBuilder uriBuilder;
     protected final TagUserApi tagUserApi;
     protected final CustomFieldUserApi customFieldUserApi;
@@ -60,73 +64,47 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         this.customFieldUserApi = customFieldUserApi;
     }
 
-    protected Response getTags(final UUID id) {
-
-        try {
-            final Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType());
-            final Collection<UUID> tagIdList = (tags.size() == 0) ?
-                    Collections.<UUID>emptyList() :
-                        Collections2.transform(tags.values(), new Function<Tag, UUID>() {
-                            @Override
-                            public UUID apply(final Tag input) {
-                                return input.getTagDefinitionId();
-                            }
-                        });
-
-                    final List<TagDefinition> tagDefinitionList = tagUserApi.getTagDefinitions(tagIdList);
-                    return Response.status(Response.Status.OK).entity(tagDefinitionList).build();
-        } catch (TagDefinitionApiException e) {
-            return Response.status(Response.Status.NO_CONTENT).entity(e.getMessage()).build();
-        }
+    protected Response getTags(final UUID id) throws TagDefinitionApiException {
+        final Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType());
+        final Collection<UUID> tagIdList = (tags.size() == 0) ?
+                                           Collections.<UUID>emptyList() :
+                                           Collections2.transform(tags.values(), new Function<Tag, UUID>() {
+                                               @Override
+                                               public UUID apply(final Tag input) {
+                                                   return input.getTagDefinitionId();
+                                               }
+                                           });
+
+        final List<TagDefinition> tagDefinitionList = tagUserApi.getTagDefinitions(tagIdList);
+        return Response.status(Response.Status.OK).entity(tagDefinitionList).build();
     }
 
     protected Response createTags(final UUID id,
                                   final String tagList,
                                   final UriInfo uriInfo,
-                                  final CallContext context) {
-        try {
-            Preconditions.checkNotNull(tagList, "Query % list cannot be null", JaxrsResource.QUERY_TAGS);
-
-            final Collection<UUID> input = getTagDefinitionUUIDs(tagList);
-            tagUserApi.addTags(id, getObjectType(), input, context);
-            return uriBuilder.buildResponse(this.getClass(), "getTags", id, uriInfo.getBaseUri().toString());
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NullPointerException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (TagApiException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                  final CallContext context) throws TagApiException {
+        final Collection<UUID> input = getTagDefinitionUUIDs(tagList);
+        tagUserApi.addTags(id, getObjectType(), input, context);
+        return uriBuilder.buildResponse(this.getClass(), "getTags", id, uriInfo.getBaseUri().toString());
     }
 
-
     private Collection<UUID> getTagDefinitionUUIDs(final String tagList) {
         final String[] tagParts = tagList.split(",\\s*");
-        final Collection<UUID> result = Collections2.transform(ImmutableList.copyOf(tagParts), new Function<String, UUID>() {
+        return Collections2.transform(ImmutableList.copyOf(tagParts), new Function<String, UUID>() {
             @Override
-            public UUID apply(String input) {
+            public UUID apply(final String input) {
                 return UUID.fromString(input);
             }
         });
-        return result;
     }
 
     protected Response deleteTags(final UUID id,
                                   final String tagList,
-                                  final CallContext context) {
-
-        try {
-            final Collection<UUID> input = getTagDefinitionUUIDs(tagList);
-            tagUserApi.removeTags(id, getObjectType(), input, context);
-
-            return Response.status(Response.Status.OK).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NullPointerException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (TagApiException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                  final CallContext context) throws TagApiException {
+        final Collection<UUID> input = getTagDefinitionUUIDs(tagList);
+        tagUserApi.removeTags(id, getObjectType(), input, context);
+
+        return Response.status(Response.Status.OK).build();
     }
 
     protected Response getCustomFields(final UUID id) {
@@ -136,37 +114,26 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         for (final CustomField cur : fields.values()) {
             result.add(new CustomFieldJson(cur));
         }
+
         return Response.status(Response.Status.OK).entity(result).build();
     }
 
     protected Response createCustomFields(final UUID id,
                                           final List<CustomFieldJson> customFields,
                                           final CallContext context) {
-        try {
-            final LinkedList<CustomField> input = new LinkedList<CustomField>();
-            for (final CustomFieldJson cur : customFields) {
-                input.add(new StringCustomField(cur.getName(), cur.getValue()));
-            }
-
-            customFieldUserApi.saveCustomFields(id, getObjectType(), input, context);
-            return uriBuilder.buildResponse(this.getClass(), "createCustomFields", id);
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NullPointerException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        final LinkedList<CustomField> input = new LinkedList<CustomField>();
+        for (final CustomFieldJson cur : customFields) {
+            input.add(new StringCustomField(cur.getName(), cur.getValue()));
         }
+
+        customFieldUserApi.saveCustomFields(id, getObjectType(), input, context);
+        return uriBuilder.buildResponse(this.getClass(), "createCustomFields", id);
     }
 
     protected Response deleteCustomFields(final UUID id,
                                           final String customFieldList,
                                           final CallContext context) {
-        try {
-            // STEPH missing API to delete custom fields
-            return Response.status(Response.Status.OK).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NullPointerException e) {
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+        // STEPH missing API to delete custom fields
+        return Response.status(Response.Status.OK).build();
     }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
index 45961b3..91012ee 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
@@ -13,8 +13,11 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.resources;
 
+import java.util.UUID;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -27,13 +30,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
-import java.util.UUID;
-
-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.AccountUserApi;
@@ -47,76 +44,60 @@ import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.PAYMENT_METHODS_PATH)
 public class PaymentMethodResource extends JaxRsResourceBase {
 
-    private static final Logger log = LoggerFactory.getLogger(PaymentMethodResource.class);
-
     private final PaymentApi paymentApi;
     private final AccountUserApi accountApi;
     private final Context context;
 
     @Inject
-    public PaymentMethodResource(final JaxrsUriBuilder uriBuilder, final AccountUserApi accountApi,
-                                 final PaymentApi paymentApi, final TagUserApi tagUserApi,
-                                 final CustomFieldUserApi customFieldUserApi, final Context context) {
-        super(uriBuilder, tagUserApi,customFieldUserApi);
+    public PaymentMethodResource(final JaxrsUriBuilder uriBuilder,
+                                 final AccountUserApi accountApi,
+                                 final PaymentApi paymentApi,
+                                 final TagUserApi tagUserApi,
+                                 final CustomFieldUserApi customFieldUserApi,
+                                 final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi);
         this.paymentApi = paymentApi;
         this.accountApi = accountApi;
         this.context = context;
     }
 
-
     @GET
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getPaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
-                                     @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo) {
-        try {
-            PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
-            if (withPluginInfo) {
-                paymentMethod = paymentApi.getPaymentMethod(account, paymentMethod.getId(), true);
-            }
-            final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod);
-
-            return Response.status(Status.OK).entity(json).build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
+                                     @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo) throws AccountApiException, PaymentApiException {
+        PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+        if (withPluginInfo) {
+            paymentMethod = paymentApi.getPaymentMethod(account, paymentMethod.getId(), true);
         }
-    }
+        final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod);
 
+        return Response.status(Status.OK).entity(json).build();
+    }
 
     @PUT
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     public Response updatePaymentMethod(final PaymentMethodJson json,
-                                        @PathParam("paymentMethodId") final String paymentMethodId,
-                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
-                                        @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-
-            final PaymentMethod input = json.toPaymentMethod();
-            final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-
-            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
-
-            paymentApi.updatePaymentMethod(account, paymentMethod.getId(), input.getPluginDetail());
-            return getPaymentMethod(paymentMethod.getId().toString(), false);
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                        @PathParam("paymentMethodId") final String paymentMethodId) throws PaymentApiException, AccountApiException {
+        final PaymentMethod input = json.toPaymentMethod();
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+
+        paymentApi.updatePaymentMethod(account, paymentMethod.getId(), input.getPluginDetail());
+
+        return getPaymentMethod(paymentMethod.getId().toString(), false);
     }
 
     @DELETE
@@ -125,20 +106,13 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     public Response deletePaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
-                                        @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-
-            final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
-            paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
-            return Response.status(Status.OK).build();
-        } catch (PaymentApiException e) {
-            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
-        } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                        @HeaderParam(HDR_COMMENT) final String comment) throws PaymentApiException, AccountApiException {
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
+        final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
+
+        paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
+
+        return Response.status(Status.OK).build();
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
index 7b965b0..8ee10fa 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -25,24 +29,13 @@ 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.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.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;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.RefundJson;
 import com.ning.billing.jaxrs.util.Context;
@@ -52,9 +45,15 @@ import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.Refund;
 import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.PAYMENTS_PATH)
@@ -70,35 +69,30 @@ public class PaymentResource extends JaxRsResourceBase {
 
     @Inject
     public PaymentResource(final JaxrsUriBuilder uriBuilder,
-            final AccountUserApi accountApi,
-            final PaymentApi paymentApi,
-            final TagUserApi tagUserApi,
-            final CustomFieldUserApi customFieldUserApi,
-            final Context context) {
+                           final AccountUserApi accountApi,
+                           final PaymentApi paymentApi,
+                           final TagUserApi tagUserApi,
+                           final CustomFieldUserApi customFieldUserApi,
+                           final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi);
         this.context = context;
         this.paymentApi = paymentApi;
         this.accountApi = accountApi;
     }
 
-
     @GET
     @Path("/{paymentId:" + UUID_PATTERN + "}/" + REFUNDS)
     @Produces(APPLICATION_JSON)
-    public Response getRefunds(@PathParam("paymentId") final String paymentId) {
-
-        try {
-            List<Refund> refunds =  paymentApi.getPaymentRefunds(UUID.fromString(paymentId));
-            List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
-                @Override
-                public RefundJson apply(Refund input) {
-                    return new RefundJson(input);
-                }
-            }));
-            return Response.status(Status.OK).entity(result).build();
-        } catch (PaymentApiException e) {
-            return Response.status(Status.BAD_REQUEST).build();
-        }
+    public Response getRefunds(@PathParam("paymentId") final String paymentId) throws PaymentApiException {
+        final List<Refund> refunds = paymentApi.getPaymentRefunds(UUID.fromString(paymentId));
+        final List<RefundJson> result = new ArrayList<RefundJson>(Collections2.transform(refunds, new Function<Refund, RefundJson>() {
+            @Override
+            public RefundJson apply(final Refund input) {
+                return new RefundJson(input);
+            }
+        }));
+
+        return Response.status(Status.OK).entity(result).build();
     }
 
     @POST
@@ -106,30 +100,18 @@ public class PaymentResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createRefund(final RefundJson json,
-            @PathParam("paymentId") final String paymentId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context final UriInfo uriInfo) {
-
-        try {
-
-            final UUID paymentUuid = UUID.fromString(paymentId);
-            final Payment payment = paymentApi.getPayment(paymentUuid);
-            final Account account = accountApi.getAccountById(payment.getAccountId());
-
-
-            Refund result = paymentApi.createRefund(account, paymentUuid, json.getRefundAmount(), json.isAdjusted(), context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(RefundResource.class, "getRefund", result.getId(), uriInfo.getBaseUri().toString());
-        } catch (AccountApiException e) {
-            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        } catch (PaymentApiException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
-        }
+                                 @PathParam("paymentId") final String paymentId,
+                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                 @HeaderParam(HDR_REASON) final String reason,
+                                 @HeaderParam(HDR_COMMENT) final String comment,
+                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws PaymentApiException, AccountApiException {
+        final UUID paymentUuid = UUID.fromString(paymentId);
+        final Payment payment = paymentApi.getPayment(paymentUuid);
+        final Account account = accountApi.getAccountById(payment.getAccountId());
+
+        final Refund result = paymentApi.createRefund(account, paymentUuid, json.getRefundAmount(), json.isAdjusted(), context.createContext(createdBy, reason, comment));
+
+        return uriBuilder.buildResponse(RefundResource.class, "getRefund", result.getId(), uriInfo.getBaseUri().toString());
     }
 
     @GET
@@ -168,7 +150,7 @@ public class PaymentResource extends JaxRsResourceBase {
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) throws TagDefinitionApiException {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -181,7 +163,7 @@ public class PaymentResource extends JaxRsResourceBase {
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
-                               @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -194,8 +176,7 @@ public class PaymentResource extends JaxRsResourceBase {
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
-                               @HeaderParam(HDR_COMMENT) final String comment) {
-
+                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
index b67fb68..fe1e3c7 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.ArrayList;
-import java.util.List;
 import java.util.UUID;
 
 import javax.ws.rs.GET;
@@ -29,13 +25,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
@@ -44,20 +34,20 @@ import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import com.google.inject.Inject;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.REFUNDS_PATH)
 public class RefundResource extends JaxRsResourceBase {
 
-    private static final Logger log = LoggerFactory.getLogger(RefundResource.class);
-
     private final PaymentApi paymentApi;
 
     @Inject
     public RefundResource(final JaxrsUriBuilder uriBuilder,
-            final PaymentApi paymentApi,
-            final TagUserApi tagUserApi,
-            final CustomFieldUserApi customFieldUserApi,
-            final Context context) {
+                          final PaymentApi paymentApi,
+                          final TagUserApi tagUserApi,
+                          final CustomFieldUserApi customFieldUserApi) {
         super(uriBuilder, tagUserApi, customFieldUserApi);
         this.paymentApi = paymentApi;
     }
@@ -65,17 +55,9 @@ public class RefundResource extends JaxRsResourceBase {
     @GET
     @Path("/{refundId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getRefund(@PathParam("refundId") final String refundId) {
-        try {
-            Refund refund = paymentApi.getRefund(UUID.fromString(refundId));
-            return Response.status(Status.OK).entity(new RefundJson(refund)).build();
-        } catch (PaymentApiException e) {
-            if (e.getCode() == ErrorCode.PAYMENT_NO_SUCH_REFUND.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+    public Response getRefund(@PathParam("refundId") final String refundId) throws PaymentApiException {
+        final Refund refund = paymentApi.getRefund(UUID.fromString(refundId));
+        return Response.status(Status.OK).entity(new RefundJson(refund)).build();
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
index d870189..6851692 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -16,6 +16,11 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -28,12 +33,8 @@ 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.UriInfo;
 import javax.ws.rs.core.Response.Status;
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.TimeoutException;
+import javax.ws.rs.core.UriInfo;
 
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormatter;
@@ -41,8 +42,6 @@ import org.joda.time.format.ISODateTimeFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -50,8 +49,8 @@ import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.invoice.api.NullInvoiceEvent;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.util.Context;
@@ -60,15 +59,20 @@ import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.userrequest.CompletionUserRequestBase;
 
+import com.google.inject.Inject;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.SUBSCRIPTIONS_PATH)
 public class SubscriptionResource extends JaxRsResourceBase {
+
     private static final Logger log = LoggerFactory.getLogger(SubscriptionResource.class);
     private static final String ID_PARAM_NAME = "subscriptionId";
     private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
@@ -82,9 +86,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
     private final KillbillEventHandler killbillHandler;
 
     @Inject
-    public SubscriptionResource(final JaxrsUriBuilder uriBuilder, final EntitlementUserApi entitlementApi,
-            final Context context, final KillbillEventHandler killbillHandler,
-            final TagUserApi tagUserApi, final CustomFieldUserApi customFieldUserApi) {
+    public SubscriptionResource(final JaxrsUriBuilder uriBuilder,
+                                final EntitlementUserApi entitlementApi,
+                                final Context context,
+                                final KillbillEventHandler killbillHandler,
+                                final TagUserApi tagUserApi,
+                                final CustomFieldUserApi customFieldUserApi) {
         super(uriBuilder, tagUserApi, customFieldUserApi);
         this.uriBuilder = uriBuilder;
         this.entitlementApi = entitlementApi;
@@ -96,34 +103,22 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Path("/{subscriptionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getSubscription(@PathParam("subscriptionId") final String subscriptionId) throws EntitlementUserApiException {
-
-        try {
-            final UUID uuid = UUID.fromString(subscriptionId);
-            final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
-            final SubscriptionJsonNoEvents json = new SubscriptionJsonNoEvents(subscription);
-            return Response.status(Status.OK).entity(json).build();
-        } catch (EntitlementUserApiException e) {
-            if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                throw e;
-            }
-        }
+        final UUID uuid = UUID.fromString(subscriptionId);
+        final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
+        final SubscriptionJsonNoEvents json = new SubscriptionJsonNoEvents(subscription);
+        return Response.status(Status.OK).entity(json).build();
     }
 
-
     @POST
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createSubscription(final SubscriptionJsonNoEvents subscription,
-            @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
-            @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
-            @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-
-
+                                       @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+                                       @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+                                       @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
         final SubscriptionCallCompletionCallback<Subscription> callback = new SubscriptionCallCompletionCallback<Subscription>() {
             @Override
             public Subscription doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException, TimeoutException {
@@ -132,8 +127,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 final UUID uuid = UUID.fromString(subscription.getBundleId());
 
                 final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(subscription.getProductName(),
-                        ProductCategory.valueOf(subscription.getProductCategory()),
-                        BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), null);
+                                                                       ProductCategory.valueOf(subscription.getProductCategory()),
+                                                                       BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), null);
                 return entitlementApi.createSubscription(uuid, spec, inputDate, ctx);
             }
 
@@ -147,6 +142,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 return uriBuilder.buildResponse(SubscriptionResource.class, "getSubscription", createdSubscription.getId());
             }
         };
+
         final SubscriptionCallCompletion<Subscription> callCompletionCreation = new SubscriptionCallCompletion<Subscription>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
@@ -156,32 +152,25 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Path("/{subscriptionId:" + UUID_PATTERN + "}")
     public Response changeSubscriptionPlan(final SubscriptionJsonNoEvents subscription,
-            @PathParam("subscriptionId") final String subscriptionId,
-            @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
-            @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
-            @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-
+                                           @PathParam("subscriptionId") final String subscriptionId,
+                                           @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+                                           @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+                                           @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                           @HeaderParam(HDR_REASON) final String reason,
+                                           @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
         final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
 
             @Override
-            public Response doOperation(final CallContext ctx)
-            throws EntitlementUserApiException, InterruptedException,
-            TimeoutException {
-                try {
-                    final UUID uuid = UUID.fromString(subscriptionId);
-                    final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
-                    final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
-                    isImmediateOp = current.changePlan(subscription.getProductName(), BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), inputDate, ctx);
-                    return Response.status(Status.OK).build();
-                } catch (EntitlementUserApiException e) {
-                    log.warn("Subscription not found: " + subscriptionId, e);
-                    return Response.status(Status.NO_CONTENT).build();
-                }
+            public Response doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException,
+                                                                      TimeoutException {
+                final UUID uuid = UUID.fromString(subscriptionId);
+                final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+                final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
+                isImmediateOp = current.changePlan(subscription.getProductName(), BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), inputDate, ctx);
+                return Response.status(Status.OK).build();
             }
 
             @Override
@@ -190,21 +179,15 @@ public class SubscriptionResource extends JaxRsResourceBase {
             }
 
             @Override
-            public Response doResponseOk(final Response operationResponse) {
+            public Response doResponseOk(final Response operationResponse) throws EntitlementUserApiException {
                 if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
                     return operationResponse;
                 }
-                try {
-                    return getSubscription(subscriptionId);
-                } catch (EntitlementUserApiException e) {
-                    if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
-                        return Response.status(Status.NO_CONTENT).build();
-                    } else {
-                        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
-                    }
-                }
+
+                return getSubscription(subscriptionId);
             }
         };
+
         final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
@@ -213,59 +196,42 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Path("/{subscriptionId:" + UUID_PATTERN + "}/uncancel")
     @Produces(APPLICATION_JSON)
     public Response uncancelSubscriptionPlan(@PathParam("subscriptionId") final String subscriptionId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final UUID uuid = UUID.fromString(subscriptionId);
-            final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
-
-            current.uncancel(context.createContext(createdBy, reason, comment));
-            return Response.status(Status.OK).build();
-        } catch (EntitlementUserApiException e) {
-            if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
-                return Response.status(Status.NO_CONTENT).build();
-            } else {
-                log.info(String.format("Failed to uncancel plan for subscription %s", subscriptionId), e);
-                return Response.status(Status.BAD_REQUEST).build();
-            }
-        }
+                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                             @HeaderParam(HDR_REASON) final String reason,
+                                             @HeaderParam(HDR_COMMENT) final String comment) throws EntitlementUserApiException {
+        final UUID uuid = UUID.fromString(subscriptionId);
+        final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+
+        current.uncancel(context.createContext(createdBy, reason, comment));
+        return Response.status(Status.OK).build();
     }
 
     @DELETE
     @Path("/{subscriptionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response cancelSubscriptionPlan(@PathParam("subscriptionId") final String subscriptionId,
-            @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
-            @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
-            @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("5") final long timeoutSec,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-
+                                           @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+                                           @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+                                           @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("5") final long timeoutSec,
+                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                           @HeaderParam(HDR_REASON) final String reason,
+                                           @HeaderParam(HDR_COMMENT) final String comment,
+                                           @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementUserApiException {
         final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
 
             @Override
             public Response doOperation(final CallContext ctx)
-            throws EntitlementUserApiException, InterruptedException,
-            TimeoutException {
-                try {
-                    final UUID uuid = UUID.fromString(subscriptionId);
-
-                    final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
-
-                    final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
-                    isImmediateOp = current.cancel(inputDate, false, ctx);
-                    return Response.status(Status.OK).build();
-                } catch (EntitlementUserApiException e) {
-                    if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
-                        return Response.status(Status.NO_CONTENT).build();
-                    } else {
-                        throw e;
-                    }
-                }
+                    throws EntitlementUserApiException, InterruptedException,
+                           TimeoutException {
+                final UUID uuid = UUID.fromString(subscriptionId);
+
+                final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+
+                final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
+                isImmediateOp = current.cancel(inputDate, false, ctx);
+                return Response.status(Status.OK).build();
             }
 
             @Override
@@ -278,6 +244,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 return operationResponse;
             }
         };
+
         final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
@@ -289,9 +256,9 @@ public class SubscriptionResource extends JaxRsResourceBase {
         }
 
         @Override
-        public void onSubscriptionTransition(EffectiveSubscriptionEvent curEventEffective) {
+        public void onSubscriptionTransition(final EffectiveSubscriptionEvent curEventEffective) {
             log.info(String.format("Got event SubscriptionTransition token = %s, type = %s, remaining = %d ",
-                    curEventEffective.getUserToken(), curEventEffective.getTransitionType(),  curEventEffective.getRemainingEventsForUserOperation()));
+                                   curEventEffective.getUserToken(), curEventEffective.getTransitionType(), curEventEffective.getRemainingEventsForUserOperation()));
         }
 
         @Override
@@ -301,7 +268,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
         }
 
         @Override
-        public void onInvoiceCreation(InvoiceCreationEvent curEvent) {
+        public void onInvoiceCreation(final InvoiceCreationEvent curEvent) {
             log.info(String.format("Got event InvoiceCreationNotification token = %s ", curEvent.getUserToken()));
             if (curEvent.getAmountOwed().compareTo(BigDecimal.ZERO) <= 0) {
                 notifyForCompletion();
@@ -309,34 +276,35 @@ public class SubscriptionResource extends JaxRsResourceBase {
         }
 
         @Override
-        public void onPaymentInfo(PaymentInfoEvent curEvent) {
+        public void onPaymentInfo(final PaymentInfoEvent curEvent) {
             log.info(String.format("Got event PaymentInfo token = %s ", curEvent.getUserToken()));
             notifyForCompletion();
         }
 
         @Override
-        public void onPaymentError(PaymentErrorEvent curEvent) {
+        public void onPaymentError(final PaymentErrorEvent curEvent) {
             log.info(String.format("Got event PaymentError token = %s ", curEvent.getUserToken()));
             notifyForCompletion();
         }
     }
 
     private interface SubscriptionCallCompletionCallback<T> {
+
         public T doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException, TimeoutException;
 
         public boolean isImmOperation();
 
-        public Response doResponseOk(final T operationResponse);
+        public Response doResponseOk(final T operationResponse) throws EntitlementUserApiException;
     }
 
     private class SubscriptionCallCompletion<T> {
 
         public Response withSynchronization(final SubscriptionCallCompletionCallback<T> callback,
-                final long timeoutSec,
-                final boolean callCompletion,
-                final String createdBy,
-                final String reason,
-                final String comment) {
+                                            final long timeoutSec,
+                                            final boolean callCompletion,
+                                            final String createdBy,
+                                            final String reason,
+                                            final String comment) throws EntitlementUserApiException {
 
             final CallContext ctx = context.createContext(createdBy, reason, comment);
             final CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(ctx.getUserToken()) : null;
@@ -349,9 +317,6 @@ public class SubscriptionResource extends JaxRsResourceBase {
                     waiter.waitForCompletion(timeoutSec * 1000);
                 }
                 return callback.doResponseOk(operationValue);
-            } catch (EntitlementUserApiException e) {
-                log.info(String.format("Failed to complete operation"), e);
-                return Response.status(Status.BAD_REQUEST).build();
             } catch (InterruptedException e) {
                 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
             } catch (TimeoutException e) {
@@ -376,12 +341,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            final List<CustomFieldJson> customFields,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       final List<CustomFieldJson> customFields,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -389,18 +355,19 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) throws TagDefinitionApiException {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -409,13 +376,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context final UriInfo uriInfo) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment,
+                               @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagApiException {
         return super.createTags(UUID.fromString(id), tagList, uriInfo,
-                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -423,13 +390,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) throws TagApiException {
         return super.deleteTags(UUID.fromString(id), tagList,
-                context.createContext(createdBy, reason, comment));
+                                context.createContext(createdBy, reason, comment));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
index 89408ea..642c881 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -26,93 +30,82 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
 
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.TagDefinition;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.TAG_DEFINITIONS_PATH)
-public class TagResource implements JaxrsResource {
+public class TagResource extends JaxRsResourceBase {
 
-    private final TagUserApi tagUserApi;
     private final Context context;
-    private final JaxrsUriBuilder uriBuilder;
 
     @Inject
-    public TagResource(final TagUserApi tagUserApi, final JaxrsUriBuilder uriBuilder, final Context context) {
-        this.tagUserApi = tagUserApi;
+    public TagResource(final JaxrsUriBuilder uriBuilder,
+                       final TagUserApi tagUserApi,
+                       final CustomFieldUserApi customFieldUserApi,
+                       final Context context) {
+        super(uriBuilder, tagUserApi, customFieldUserApi);
         this.context = context;
-        this.uriBuilder = uriBuilder;
     }
 
     @GET
     @Produces(APPLICATION_JSON)
     public Response getTagDefinitions() {
+        final List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
 
         final List<TagDefinitionJson> result = new LinkedList<TagDefinitionJson>();
-        final List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
         for (final TagDefinition cur : tagDefinitions) {
-            result.add(new TagDefinitionJson(cur.getId().toString(), cur.getName(), cur.getDescription()));
+            result.add(new TagDefinitionJson(cur));
         }
+
         return Response.status(Status.OK).entity(result).build();
     }
 
     @GET
     @Path("/{tagDefinitionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId) {
-        try {
-            final TagDefinition tagDef = tagUserApi.getTagDefinition(UUID.fromString(tagDefId));
-            final TagDefinitionJson json = new TagDefinitionJson(tagDef.getId().toString(), tagDef.getName(), tagDef.getDescription());
-            return Response.status(Status.OK).entity(json).build();
-        } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        }
+    public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId) throws TagDefinitionApiException {
+        final TagDefinition tagDef = tagUserApi.getTagDefinition(UUID.fromString(tagDefId));
+        final TagDefinitionJson json = new TagDefinitionJson(tagDef);
+        return Response.status(Status.OK).entity(json).build();
     }
 
-
     @POST
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTagDefinition(final TagDefinitionJson json,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            final TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getId());
-        } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) throws TagDefinitionApiException {
+        final TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
+        return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getId());
     }
 
     @DELETE
     @Path("/{tagDefinitionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response deleteTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-        try {
-            tagUserApi.deleteTagDefinition(UUID.fromString(tagDefId), context.createContext(createdBy, reason, comment));
-            return Response.status(Status.OK).build();
-        } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build();
-        } catch (IllegalArgumentException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        }
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) throws TagDefinitionApiException {
+        tagUserApi.deleteTagDefinition(UUID.fromString(tagDefId), context.createContext(createdBy, reason, comment));
+        return Response.status(Status.NO_CONTENT).build();
+    }
+
+    @Override
+    protected ObjectType getObjectType() {
+        return ObjectType.TAG_DEFINITION;
     }
 }
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index 808ff0d..e20dc8e 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -56,6 +56,7 @@ public class KillbillGuiceListener extends SetupServer {
                 .addHealthCheck(KillbillHealthcheck.class)
                 .addJMXExport(KillbillHealthcheck.class)
                 .addModule(getModule())
+                .addJerseyResource("com.ning.billing.jaxrs.mappers")
                 .addJerseyResource("com.ning.billing.jaxrs.resources");
 
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index ae1f20e..9adeb8b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2012 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -13,13 +13,8 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.jaxrs;
-
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
+package com.ning.billing.jaxrs;
 
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -35,7 +30,6 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
@@ -49,15 +43,20 @@ import com.ning.billing.jaxrs.json.RefundJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.billing.mock.api.MockBillCycleDay;
 import com.ning.http.client.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 public class TestAccount extends TestJaxrsBase {
 
     private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountOk() throws Exception {
 
         final AccountJson input = createAccount("xoxo", "shdgfhwe", "xoxo@yahoo.com");
@@ -73,8 +72,8 @@ public class TestAccount extends TestJaxrsBase {
 
         // Update Account
         final AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
-                                               "zozo", 4, objFromJson.getExternalKey(), "rr@google.com", new BillCycleDayJson(18, 18),
-                                               "EUR", null, "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
+                                                     "zozo", 4, objFromJson.getExternalKey(), "rr@google.com", new BillCycleDayJson(18, 18),
+                                                     "EUR", null, "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
         baseJson = mapper.writeValueAsString(newInput);
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
         response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -84,46 +83,40 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertTrue(objFromJson.equals(newInput));
     }
 
-
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testUpdateNonExistentAccount() throws Exception {
         final AccountJson input = getAccountJson("xoxo", "shghaahwe", "xoxo@yahoo.com");
         final String baseJson = mapper.writeValueAsString(input);
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
         final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-        final String body = response.getResponseBody();
-        Assert.assertEquals(body, "");
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
     }
 
-
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountNonExistent() throws Exception {
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
         final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountBadAccountId() throws Exception {
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/yo";
         final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountTimeline() throws Exception {
 
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-
         final AccountJson accountJson = createAccountWithDefaultPaymentMethod("poney", "shdddqgfhwe", "poney@yahoo.com");
         assertNotNull(accountJson);
 
         final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
         assertNotNull(bundleJson);
 
-
         final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
@@ -148,8 +141,7 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 2);
     }
 
-
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountPaymentMethods() throws Exception {
 
         final AccountJson accountJson = createAccount("qwerty", "ytrewq", "qwerty@yahoo.com");
@@ -202,7 +194,6 @@ public class TestAccount extends TestJaxrsBase {
         List<PaymentMethodJson> paymentMethods = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
         assertEquals(paymentMethods.size(), 2);
 
-
         //
         // CHANGE DEFAULT
         //
@@ -236,7 +227,7 @@ public class TestAccount extends TestJaxrsBase {
         assertEquals(paymentMethods.size(), 1);
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testAccountPaymentsWithRefund() throws Exception {
 
         //clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
@@ -253,7 +244,6 @@ public class TestAccount extends TestJaxrsBase {
         clock.addMonths(1);
         crappyWaitForLackOfProperSynchonization();
 
-
         String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENTS;
 
         Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -271,7 +261,7 @@ public class TestAccount extends TestJaxrsBase {
 
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testTags() throws Exception {
 
         // Use tag definition for AUTO_PAY_OFF
@@ -289,11 +279,9 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
     }
 
-
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testCustomFields() throws Exception {
 
-
         final AccountJson accountJson = createAccount("yoyoq", "gfgrqe", "yoyoq@yahoo.com");
         assertNotNull(accountJson);
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
index 2f169f9..962c581 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
@@ -13,30 +13,28 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs;
 
-import javax.ws.rs.core.Response.Status;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.ws.rs.core.Response.Status;
+
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
-public class TestBundle extends TestJaxrsBase {
-
-    private static final Logger log = LoggerFactory.getLogger(TestBundle.class);
+import com.fasterxml.jackson.core.type.TypeReference;
 
+public class TestBundle extends TestJaxrsBase {
 
     @Test(groups = "slow", enabled = true)
     public void testBundleOk() throws Exception {
@@ -54,7 +52,6 @@ public class TestBundle extends TestJaxrsBase {
         Assert.assertTrue(objFromJson.equals(bundleJson));
     }
 
-
     @Test(groups = "slow", enabled = true)
     public void testBundleFromAccount() throws Exception {
 
@@ -84,17 +81,15 @@ public class TestBundle extends TestJaxrsBase {
 
         String uri = JaxrsResource.BUNDLES_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
         Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
 
         // Retrieves by external key
         final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "56566");
         response = doGet(JaxrsResource.BUNDLES_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
 
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
+        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.BUNDLES;
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         final String baseJson = response.getResponseBody();
@@ -107,7 +102,7 @@ public class TestBundle extends TestJaxrsBase {
     public void testAppNonExistent() throws Exception {
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747/" + JaxrsResource.BUNDLES;
         final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
     }
 
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
index 386c3b2..c20e0fe 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
@@ -21,13 +21,13 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
@@ -40,6 +40,9 @@ import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.ImmutableMap;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
@@ -54,7 +57,7 @@ public class TestChargeback extends TestJaxrsBase {
 
         // Create the chargeback
         Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
 
         // Find the chargeback by location
         final String location = response.getHeader("Location");
@@ -115,7 +118,7 @@ public class TestChargeback extends TestJaxrsBase {
 
 
     private void verifyCollectionChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         final ChargebackCollectionJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackCollectionJson.class);
         assertEquals(objFromJson.getChargebacks().size(), 1);
         ChargebackJson chargeBack = objFromJson.getChargebacks().get(0);
@@ -124,7 +127,7 @@ public class TestChargeback extends TestJaxrsBase {
     }
 
     private void verifySingleChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         final ChargebackJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackJson.class);
         assertTrue(objFromJson.getChargebackAmount().compareTo(input.getChargebackAmount()) == 0);
     }
@@ -137,7 +140,7 @@ public class TestChargeback extends TestJaxrsBase {
 
         // Try to create the chargeback
         final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
     }
 
     @Test(groups = "slow")
@@ -147,27 +150,26 @@ public class TestChargeback extends TestJaxrsBase {
 
         // Try to create the chargeback
         final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
     }
 
     @Test(groups = "slow")
     public void testNoChargebackForAccount() throws Exception {
         final String accountId = UUID.randomUUID().toString();
         final Response response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/accounts/" + accountId, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode(), response.getResponseBody());
 
         final ChargebackCollectionJson chargebackCollectionJson = mapper.readValue(response.getResponseBody(), ChargebackCollectionJson.class);
         Assert.assertEquals(chargebackCollectionJson.getAccountId(), accountId);
         Assert.assertEquals(chargebackCollectionJson.getChargebacks().size(), 0);
     }
 
-
     @Test(groups = "slow")
     public void testNoChargebackForPayment() throws Exception {
         final String payment = UUID.randomUUID().toString();
         final Response response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/payments/" + payment, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         // STEPH needs to fix that we get 200 instaed of 204 although stepping through code, i see we do return NO_CONTENT. mistery that needs to be solved!!!!
-        //assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.getResponseBody());
+        //assertEquals(response.getStatusCode(),Status.NO_CONTENT.getStatusCode(), response.getResponseBody());
     }
 
     private PaymentJsonSimple createAccountWithInvoiceAndPayment() throws Exception {
@@ -193,7 +195,7 @@ public class TestChargeback extends TestJaxrsBase {
 
         // Retrieve the invoice
         final Response response = doGet(JaxrsResource.INVOICES_PATH, ImmutableMap.<String, String>of(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId()), DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         final String baseJson = response.getResponseBody();
         final List<InvoiceJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
         assertNotNull(objFromJson);
@@ -208,7 +210,7 @@ public class TestChargeback extends TestJaxrsBase {
         final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
         final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
 
-        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         final String baseJson = response.getResponseBody();
         final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
         assertNotNull(objFromJson);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
index 8d0b3c8..50a58a7 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
@@ -19,22 +19,22 @@ package com.ning.billing.jaxrs;
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.joda.time.LocalDate;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.CreditJson;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.billing.util.clock.DefaultClock;
 import com.ning.http.client.Response;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
 public class TestCredit extends TestJaxrsBase {
+
     AccountJson accountJson;
 
     @BeforeMethod(groups = "slow")
@@ -54,14 +54,14 @@ public class TestCredit extends TestJaxrsBase {
 
         // Create the credit
         Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
 
         final String location = response.getHeader("Location");
         assertNotNull(location);
 
         // Retrieves by Id based on Location returned
         response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         // We can't just compare the object via .equals() due e.g. to the invoice id
         final CreditJson objFromJson = mapper.readValue(response.getResponseBody(), CreditJson.class);
@@ -81,7 +81,7 @@ public class TestCredit extends TestJaxrsBase {
 
         // Try to create the credit
         final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
     }
 
     @Test(groups = "slow")
@@ -91,12 +91,12 @@ public class TestCredit extends TestJaxrsBase {
 
         // Try to create the credit
         final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
     }
 
     @Test(groups = "slow")
     public void testCreditDoesNotExist() throws Exception {
         final Response response = doGet(JaxrsResource.CREDITS_PATH + "/" + UUID.randomUUID().toString(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index adb005b..a4c59bc 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -13,14 +13,16 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs;
 
-import javax.ws.rs.core.Response.Status;
 import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.slf4j.Logger;
@@ -28,7 +30,6 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
@@ -39,11 +40,14 @@ import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public class TestInvoice extends TestJaxrsBase {
+
     private static final Logger log = LoggerFactory.getLogger(TestInvoice.class);
 
     @Test(groups = "slow")
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
index d1aa37f..3f68c8c 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
@@ -23,8 +23,6 @@ import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
@@ -34,7 +32,11 @@ import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.ImmutableMap;
+
 public class TestInvoiceNotification extends TestJaxrsBase {
+
     @Test(groups = "slow")
     public void testTriggerNotification() throws Exception {
         final AccountJson accountJson = createScenarioWithOneInvoice();
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
index 090b700..3ca0383 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2012 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -13,38 +13,35 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package com.ning.billing.jaxrs;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
+package com.ning.billing.jaxrs;
 
 import java.math.BigDecimal;
 import java.util.List;
 
 import javax.ws.rs.core.Response.Status;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
-
 import com.ning.billing.jaxrs.json.RefundJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
-public class TestPayment extends TestJaxrsBase {
+import com.fasterxml.jackson.core.type.TypeReference;
 
-    private static final Logger log = LoggerFactory.getLogger(TestPayment.class);
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 
-    @Test(groups = "slow", enabled = true)
+public class TestPayment extends TestJaxrsBase {
+
+    @Test(groups = "slow")
     public void testPaymentWithRefund() throws Exception {
         final AccountJson accountJson = createAccountWithDefaultPaymentMethod("eraahahildo", "sheqrgfhwe", "eraahahildo@yahoo.com");
         assertNotNull(accountJson);
@@ -58,13 +55,12 @@ public class TestPayment extends TestJaxrsBase {
         clock.addMonths(1);
         crappyWaitForLackOfProperSynchonization();
 
-
         String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENTS;
 
         Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
-        List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
         Assert.assertEquals(objFromJson.size(), 1);
 
         final String paymentId = objFromJson.get(0).getPaymentId();
@@ -79,7 +75,7 @@ public class TestPayment extends TestJaxrsBase {
 
         // Issue the refund
 
-        RefundJson refundJson = new RefundJson(null, paymentId, paymentAmount, false);
+        final RefundJson refundJson = new RefundJson(null, paymentId, paymentAmount, false);
         baseJson = mapper.writeValueAsString(refundJson);
         response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
@@ -100,6 +96,5 @@ public class TestPayment extends TestJaxrsBase {
         baseJson = response.getResponseBody();
         objRefundFromJson = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
         Assert.assertEquals(objRefundFromJson.size(), 1);
-
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
index 28c6563..ce1e9f4 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2012 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -13,16 +13,16 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs;
 
-import javax.ws.rs.core.Response.Status;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -41,12 +41,9 @@ import static org.testng.Assert.assertTrue;
 
 public class TestSubscription extends TestJaxrsBase {
 
-    private static final Logger log = LoggerFactory.getLogger(TestSubscription.class);
-
     private static final String CALL_COMPLETION_TIMEOUT_SEC = "5";
 
-
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testSubscriptionInTrialOk() throws Exception {
 
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
@@ -64,7 +61,6 @@ public class TestSubscription extends TestJaxrsBase {
 
         String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
 
-
         // Retrieves with GET
         Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
@@ -76,12 +72,12 @@ public class TestSubscription extends TestJaxrsBase {
         final String newProductName = "Assault-Rifle";
 
         final SubscriptionJsonNoEvents newInput = new SubscriptionJsonNoEvents(subscriptionJson.getSubscriptionId(),
-                                                                         subscriptionJson.getBundleId(),
-                                                                         null,
-                                                                         newProductName,
-                                                                         subscriptionJson.getProductCategory(),
-                                                                         subscriptionJson.getBillingPeriod(),
-                                                                         subscriptionJson.getPriceList(), null, null);
+                                                                               subscriptionJson.getBundleId(),
+                                                                               null,
+                                                                               newProductName,
+                                                                               subscriptionJson.getProductCategory(),
+                                                                               subscriptionJson.getBillingPeriod(),
+                                                                               subscriptionJson.getPriceList(), null, null);
         baseJson = mapper.writeValueAsString(newInput);
 
         final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
@@ -103,7 +99,6 @@ public class TestSubscription extends TestJaxrsBase {
         response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
-
         // Retrieves to check EndDate
         uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -115,30 +110,26 @@ public class TestSubscription extends TestJaxrsBase {
         assertTrue(objFromJson.getCancelledDate().compareTo(clock.getUTCNow()) > 0);
 
         // Uncancel
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString() + "/uncancel";
+        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId() + "/uncancel";
         response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testWithNonExistentSubscription() throws Exception {
         final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
         final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(),
-                PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
+                                                                                       PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
         final String baseJson = mapper.writeValueAsString(subscriptionJson);
 
         Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-        String body = response.getResponseBody();
-        Assert.assertEquals(body, "");
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
 
         response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-        body = response.getResponseBody();
-        Assert.assertEquals(body, "");
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
 
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
     }
 
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
index 174fab1..2fbf239 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2012 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -13,27 +13,29 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs;
 
-import javax.ws.rs.core.Response.Status;
 import java.util.List;
 
-import org.testng.Assert;
+import javax.ws.rs.core.Response.Status;
+
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public class TestTag extends TestJaxrsBase {
-    @Test(groups = "slow", enabled = true)
-    public void testTagDefinitionOk() throws Exception {
 
+    @Test(groups = "slow")
+    public void testTagDefinitionOk() throws Exception {
         final TagDefinitionJson input = new TagDefinitionJson(null, "blue", "relaxing color");
         String baseJson = mapper.writeValueAsString(input);
         Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -52,9 +54,8 @@ public class TestTag extends TestJaxrsBase {
         assertTrue(objFromJson.equalsNoId(input));
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow")
     public void testMultipleTagDefinitionOk() throws Exception {
-
         Response response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
@@ -62,22 +63,22 @@ public class TestTag extends TestJaxrsBase {
         List<TagDefinitionJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
         final int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
 
-        TagDefinitionJson inputBlue = new TagDefinitionJson(null, "blue", "relaxing color");
+        final TagDefinitionJson inputBlue = new TagDefinitionJson(null, "blue", "relaxing color");
         baseJson = mapper.writeValueAsString(inputBlue);
         response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        TagDefinitionJson inputRed = new TagDefinitionJson(null, "red", "hot color");
+        final TagDefinitionJson inputRed = new TagDefinitionJson(null, "red", "hot color");
         baseJson = mapper.writeValueAsString(inputRed);
         response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        TagDefinitionJson inputYellow = new TagDefinitionJson(null, "yellow", "vibrant color");
+        final TagDefinitionJson inputYellow = new TagDefinitionJson(null, "yellow", "vibrant color");
         baseJson = mapper.writeValueAsString(inputYellow);
         response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        TagDefinitionJson inputGreen = new TagDefinitionJson(null, "green", "super relaxing color");
+        final TagDefinitionJson inputGreen = new TagDefinitionJson(null, "green", "super relaxing color");
         baseJson = mapper.writeValueAsString(inputGreen);
         response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
@@ -90,11 +91,9 @@ public class TestTag extends TestJaxrsBase {
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 4 + sizeSystemTag);
 
-
-
-        String uri = JaxrsResource.TAG_DEFINITIONS_PATH + "/" + objFromJson.get(0).getId();
+        final String uri = JaxrsResource.TAG_DEFINITIONS_PATH + "/" + objFromJson.get(0).getId();
         response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
 
         response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
@@ -103,7 +102,5 @@ public class TestTag extends TestJaxrsBase {
         objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 3 + sizeSystemTag);
-
     }
-
 }