killbill-memoizeit

Merge remote-tracking branch 'origin/master' into queue Conflicts: invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java osgi-bundles/bundles/meter/pom.xml osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/jaxrs/resources/MeterResource.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/MeterTestSuite.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/TestDateTimeUtils.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/TestInMemoryEventHandler.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineEventHandler.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/TimelineLoadGenerator.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/aggregator/TestTimelineAggregator.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/chunks/TestTimelineChunk.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/consumer/TestAccumulatorSampleConsumer.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestFileBackedBuffer.java osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestSamplesReplayer.java payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java pom.xml

7/11/2013 6:52:46 PM

Changes

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

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

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

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

doc/api.html 91(+0 -91)

doc/css/bootstrap.min.css 356(+0 -356)

doc/css/killbill.css 3(+0 -3)

doc/css/prettify.css 118(+0 -118)

doc/design.html 100(+0 -100)

doc/js/bootstrap-dropdown.js 55(+0 -55)

doc/js/prettify.js 28(+0 -28)

doc/setup.html 97(+0 -97)

doc/user.html 102(+0 -102)

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

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

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

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

osgi-bundles/bundles/analytics/pom.xml 211(+0 -211)

osgi-bundles/bundles/analytics/README.md 51(+0 -51)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsActivator.java 84(+0 -84)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java 312(+0 -312)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsRefreshException.java 31(+0 -31)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessAccount.java 325(+0 -325)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessEntityBase.java 151(+0 -151)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessField.java 111(+0 -111)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoice.java 199(+0 -199)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoiceItem.java 358(+0 -358)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoicePayment.java 522(+0 -522)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessOverdueStatus.java 109(+0 -109)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSnapshot.java 134(+0 -134)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSubscriptionTransition.java 429(+0 -429)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessTag.java 103(+0 -103)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java 86(+0 -86)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessExecutor.java 52(+0 -52)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AllBusinessObjectsDao.java 75(+0 -75)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AnalyticsDao.java 197(+0 -197)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java 34(+0 -34)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.java 166(+0 -166)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java 49(+0 -49)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessDBIProvider.java 108(+0 -108)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java 80(+0 -80)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java 147(+0 -147)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java 89(+0 -89)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java 53(+0 -53)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java 91(+0 -91)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java 114(+0 -114)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java 80(+0 -80)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessAccountFactory.java 130(+0 -130)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessBundleSummaryFactory.java 148(+0 -148)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFactoryBase.java 603(+0 -603)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFieldFactory.java 67(+0 -67)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceFactory.java 327(+0 -327)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoicePaymentFactory.java 103(+0 -103)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessOverdueStatusFactory.java 122(+0 -122)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessSubscriptionTransitionFactory.java 183(+0 -183)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessTagFactory.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessAccountFieldModelDao.java 49(+0 -49)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessAccountModelDao.java 417(+0 -417)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessAccountTagModelDao.java 52(+0 -52)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessBundleFieldModelDao.java 95(+0 -95)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessBundleSummaryModelDao.java 339(+0 -339)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessBundleTagModelDao.java 98(+0 -98)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessFieldModelDao.java 198(+0 -198)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceAdjustmentModelDao.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceFieldModelDao.java 98(+0 -98)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceItemAdjustmentModelDao.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceItemBaseModelDao.java 599(+0 -599)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceItemCreditModelDao.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceItemModelDao.java 70(+0 -70)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceModelDao.java 271(+0 -271)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentBaseModelDao.java 736(+0 -736)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentChargebackModelDao.java 61(+0 -61)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentFieldModelDao.java 95(+0 -95)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentModelDao.java 61(+0 -61)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentRefundModelDao.java 61(+0 -61)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoicePaymentTagModelDao.java 98(+0 -98)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessInvoiceTagModelDao.java 98(+0 -98)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessModelDaoBase.java 200(+0 -200)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessOverdueStatusModelDao.java 193(+0 -193)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessSubscription.java 310(+0 -310)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessSubscriptionEvent.java 186(+0 -186)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessSubscriptionTransitionModelDao.java 527(+0 -527)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/model/BusinessTagModelDao.java 192(+0 -192)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/TimeSeriesTuple.java 76(+0 -76)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/http/AnalyticsServlet.java 376(+0 -376)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/http/ObjectMapperProvider.java 37(+0 -37)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/json/NamedXYTimeSeries.java 42(+0 -42)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/json/XY.java 67(+0 -67)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/analysis/AverageSmoother.java 34(+0 -34)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/analysis/DateGranularity.java 22(+0 -22)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/analysis/Smoother.java 134(+0 -134)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/analysis/SummingSmoother.java 34(+0 -34)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/ReportConfigurationSection.java 36(+0 -36)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/ReportsConfiguration.java 94(+0 -94)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/ReportSpecification.java 84(+0 -84)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/ReportsUserApi.java 300(+0 -300)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/reports/scheduler/JobsScheduler.java 129(+0 -129)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/utils/BusinessInvoiceUtils.java 84(+0 -84)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/utils/Rounder.java 36(+0 -36)

osgi-bundles/bundles/analytics/src/main/resources/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.sql.stg 1362(+0 -1362)

osgi-bundles/bundles/analytics/src/main/resources/com/ning/billing/osgi/bundles/analytics/ddl.sql 774(+0 -774)

osgi-bundles/bundles/analytics/src/main/resources/reports/analytics.ini 93(+0 -93)

osgi-bundles/bundles/analytics/src/main/resources/reports/cancellations_per_day.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/chargebacks_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/conversions_per_day.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/invoice_adjustments_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/invoice_item_adjustments_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/invoice_item_credits_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/invoices_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/new_accounts_per_day.sql 9(+0 -9)

osgi-bundles/bundles/analytics/src/main/resources/reports/new_trials_last_24_hours.sql 14(+0 -14)

osgi-bundles/bundles/analytics/src/main/resources/reports/new_trials_per_day.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/payments_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/refunds_per_day.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_notifications_per_queue_name.sql 10(+0 -10)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_payment_payment_failure.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_payment_payment_failure_aborted.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_payment_plugin_failure.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_payment_plugin_failure_aborted.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/system_report_payment_success.sql 11(+0 -11)

osgi-bundles/bundles/analytics/src/main/resources/reports/v_revenue_recognition.sql 25(+0 -25)

osgi-bundles/bundles/analytics/src/main/resources/sanity/sanity.sql 996(+0 -996)

osgi-bundles/bundles/analytics/src/main/resources/static/analytics.html 150(+0 -150)

osgi-bundles/bundles/analytics/src/main/resources/static/dashboard.html 124(+0 -124)

osgi-bundles/bundles/analytics/src/main/resources/static/javascript/d3.js 5(+0 -5)

osgi-bundles/bundles/analytics/src/main/resources/static/javascript/jquery-1.9.0.min.js 4(+0 -4)

osgi-bundles/bundles/analytics/src/main/resources/static/javascript/killbill.js 509(+0 -509)

osgi-bundles/bundles/analytics/src/main/resources/static/javascript/purl.js 271(+0 -271)

osgi-bundles/bundles/analytics/src/main/resources/static/styles/dashboard.css 66(+0 -66)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java 428(+0 -428)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteWithEmbeddedDB.java 103(+0 -103)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessAccount.java 68(+0 -68)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessField.java 93(+0 -93)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessInvoice.java 99(+0 -99)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessInvoiceItem.java 73(+0 -73)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessInvoicePayment.java 62(+0 -62)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessOverdueStatus.java 50(+0 -50)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessSnapshot.java 180(+0 -180)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessSubscriptionTransition.java 92(+0 -92)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/TestBusinessTag.java 96(+0 -96)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/user/TestDefaultAnalyticsUserApi.java 49(+0 -49)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/factory/TestBusinessBundleSummaryFactory.java 146(+0 -146)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/factory/TestBusinessInvoiceFactory.java 200(+0 -200)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessAccountFieldModelDao.java 41(+0 -41)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessAccountModelDao.java 87(+0 -87)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessAccountTagModelDao.java 41(+0 -41)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessBundleSummaryModelDao.java 81(+0 -81)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoiceFieldModelDao.java 42(+0 -42)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoiceItemModelDao.java 101(+0 -101)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoiceModelDao.java 51(+0 -51)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoicePaymentFieldModelDao.java 42(+0 -42)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoicePaymentModelDao.java 119(+0 -119)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoicePaymentTagModelDao.java 42(+0 -42)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessInvoiceTagModelDao.java 42(+0 -42)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessOverdueStatusModelDao.java 49(+0 -49)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessSubscription.java 160(+0 -160)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessSubscriptionEvent.java 47(+0 -47)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/model/TestBusinessSubscriptionTransitionModelDao.java 88(+0 -88)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestAnalyticsDao.java 54(+0 -54)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAnalyticsSqlDao.java 471(+0 -471)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestCallContext.java 82(+0 -82)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/http/TestAnalyticsServlet.java 110(+0 -110)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestAnalyticsListener.java 48(+0 -48)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessExecutor.java 85(+0 -85)

osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/utils/TestRounder.java 40(+0 -40)

osgi-bundles/bundles/meter/README.md 5(+0 -5)

osgi-bundles/bundles/meter/scripts/load.rb 510(+0 -510)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/DecimationMode.java 22(+0 -22)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/TimeAggregationMode.java 26(+0 -26)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/AccumulatingJsonSamplesOutputer.java 79(+0 -79)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/DebugJsonSamplesOutputer.java 71(+0 -71)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/DecimatingJsonSamplesOutputer.java 109(+0 -109)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/DefaultJsonSamplesOutputer.java 55(+0 -55)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/DefaultMeterUserApi.java 136(+0 -136)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/JsonSamplesOutputer.java 181(+0 -181)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/api/user/MeterUserApi.java 149(+0 -149)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/DefaultMeterService.java 81(+0 -81)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/glue/CachingDefaultTimelineDaoProvider.java 47(+0 -47)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/glue/MeterModule.java 104(+0 -104)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/MeterService.java 22(+0 -22)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/osgi/MeterActivator.java 47(+0 -47)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/aggregator/TimelineAggregator.java 438(+0 -438)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/aggregator/TimelineAggregatorSqlDao.java 44(+0 -44)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/BackgroundDBChunkWriter.java 229(+0 -229)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/categories/CategoryAndMetrics.java 108(+0 -108)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/categories/CategoryAndMetricsForSources.java 97(+0 -97)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/categories/CategoryIdAndMetricBinder.java 48(+0 -48)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/categories/CategoryIdAndMetricMapper.java 33(+0 -33)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/categories/CategoryRecordIdAndMetric.java 68(+0 -68)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/chunks/TimeBytesAndSampleBytes.java 92(+0 -92)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/chunks/TimelineChunk.java 209(+0 -209)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/chunks/TimelineChunkBinder.java 81(+0 -81)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/chunks/TimelineChunkMapper.java 61(+0 -61)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/chunks/TimelineChunksViews.java 32(+0 -32)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/DefaultSampleCoder.java 527(+0 -527)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/EncodedBytesAndSampleCount.java 79(+0 -79)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/SampleAccumulator.java 155(+0 -155)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/SampleCoder.java 76(+0 -76)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/TimelineChunkAccumulator.java 81(+0 -81)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/codec/TimesAndSamplesCoder.java 79(+0 -79)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/AccumulatorSampleConsumer.java 123(+0 -123)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVConsumer.java 45(+0 -45)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVSampleProcessor.java 57(+0 -57)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/filter/DecimatingSampleFilter.java 248(+0 -248)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/SampleProcessor.java 38(+0 -38)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/TimelineChunkConsumer.java 24(+0 -24)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/TimelineChunkDecoded.java 109(+0 -109)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/consumer/TimeRangeSampleProcessor.java 68(+0 -68)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/metrics/MetricAndId.java 74(+0 -74)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/metrics/MetricAndIdMapper.java 31(+0 -31)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/metrics/SamplesForMetricAndSource.java 108(+0 -108)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/PendingChunkMap.java 50(+0 -50)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/CachingTimelineDao.java 243(+0 -243)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/DefaultTimelineDao.java 305(+0 -305)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/FileBackedBuffer.java 142(+0 -142)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/Replayer.java 166(+0 -166)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/StreamyBytesPersistentOutputStream.java 178(+0 -178)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/TimelineDao.java 88(+0 -88)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/persistent/TimelineSqlDao.java 128(+0 -128)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/HalfFloat.java 105(+0 -105)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/NullSample.java 24(+0 -24)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/RepeatSample.java 97(+0 -97)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/SampleBase.java 30(+0 -30)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/SampleOpcode.java 124(+0 -124)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/samples/ScalarSample.java 180(+0 -180)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/shutdown/ShutdownSaveMode.java 31(+0 -31)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/shutdown/StartTimes.java 88(+0 -88)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/shutdown/StartTimesBinder.java 62(+0 -62)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/shutdown/StartTimesMapper.java 47(+0 -47)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/sources/SourceAndId.java 77(+0 -77)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/sources/SourceIdAndMetricIdMapper.java 31(+0 -31)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/sources/SourceMapper.java 31(+0 -31)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/sources/SourceRecordIdAndMetricRecordId.java 74(+0 -74)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/sources/SourceSamplesForTimestamp.java 131(+0 -131)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/TimelineEventHandler.java 564(+0 -564)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/TimelineSourceEventAccumulator.java 340(+0 -340)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/times/DefaultTimelineCoder.java 350(+0 -350)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/times/DefaultTimelineCursor.java 148(+0 -148)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/times/TimelineCoder.java 60(+0 -60)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/times/TimelineCursor.java 36(+0 -36)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/times/TimelineOpcode.java 48(+0 -48)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/util/DateTimeUtils.java 32(+0 -32)

osgi-bundles/bundles/meter/src/main/java/com/ning/billing/meter/timeline/util/Hex.java 129(+0 -129)

osgi-bundles/bundles/meter/src/main/resources/com/ning/billing/meter/ddl.sql 75(+0 -75)

osgi-bundles/bundles/meter/src/main/resources/com/ning/billing/meter/timeline/aggregator/TimelineAggregatorSqlDao.sql.stg 63(+0 -63)

osgi-bundles/bundles/meter/src/main/resources/com/ning/billing/meter/timeline/persistent/TimelineSqlDao.sql.stg 253(+0 -253)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/MeterTestSuiteNoDB.java 20(+0 -20)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/MeterTestSuiteWithEmbeddedDB.java 85(+0 -85)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/categories/TestCategoryAndMetrics.java 67(+0 -67)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/chunks/TestTimeBytesAndSampleBytes.java 50(+0 -50)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/codec/TestEncodedBytesAndSampleCount.java 50(+0 -50)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/codec/TestSampleCoder.java 212(+0 -212)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/codec/TestSampleCompression.java 77(+0 -77)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/codec/TestTimelineChunkAccumulator.java 163(+0 -163)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/codec/TestTimelineChunkToJson.java 105(+0 -105)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/consumer/filter/TestDecimatingFilter.java 110(+0 -110)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/consumer/TestCSVConsumer.java 78(+0 -78)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/metrics/TestSamplesForMetricAndSource.java 39(+0 -39)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/MockFileBackedBuffer.java 72(+0 -72)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/MockTimelineDao.java 232(+0 -232)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestDefaultTimelineDao.java 101(+0 -101)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestReplayer.java 98(+0 -98)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/samples/TestNullSample.java 33(+0 -33)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/samples/TestRepeatSample.java 51(+0 -51)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/samples/TestSampleOpcode.java 44(+0 -44)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/samples/TestScalarSample.java 77(+0 -77)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/times/TestDefaultTimelineCoder.java 393(+0 -393)

osgi-bundles/bundles/meter/src/test/java/com/ning/billing/meter/timeline/times/TestTimelineOpcode.java 32(+0 -32)

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

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

pom.xml 4(+2 -2)

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

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

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

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

Details

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

diff --git a/account/pom.xml b/account/pom.xml
index 09a26e5..ccb16b4 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index 9af09fb..76aa8cc 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -119,7 +119,7 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
 
     @Override
     public void update(final AccountModelDao specifiedAccount, final InternalCallContext context) throws AccountApiException {
-        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+        transactionalSqlDao.execute(AccountApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
             public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws EventBusException, AccountApiException {
                 final AccountSqlDao transactional = entitySqlDaoWrapperFactory.become(AccountSqlDao.class);
@@ -152,7 +152,7 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
 
     @Override
     public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId, final InternalCallContext context) throws AccountApiException {
-        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+        transactionalSqlDao.execute(AccountApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
             public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws EntityPersistenceException, EventBusException {
                 final AccountSqlDao transactional = entitySqlDaoWrapperFactory.become(AccountSqlDao.class);
@@ -190,7 +190,7 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
 
     @Override
     public void addEmail(final AccountEmailModelDao email, final InternalCallContext context) throws AccountApiException {
-        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+        transactionalSqlDao.execute(AccountApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
             public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final AccountEmailSqlDao transactional = entitySqlDaoWrapperFactory.become(AccountEmailSqlDao.class);
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index e92996d..17df3eb 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -21,7 +21,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTimeZone;
-import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -220,9 +219,8 @@ public class TestAccountDao extends AccountTestSuiteWithEmbeddedDB {
         try {
             accountDao.addEmail(accountEmailModelDao, internalCallContext);
             Assert.fail();
-        } catch (TransactionFailedException e) {
-            Assert.assertTrue(e.getCause() instanceof AccountApiException);
-            Assert.assertEquals(((AccountApiException) e.getCause()).getCode(), ErrorCode.ACCOUNT_EMAIL_ALREADY_EXISTS.getCode());
+        } catch (AccountApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.ACCOUNT_EMAIL_ALREADY_EXISTS.getCode());
         }
     }
 

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

diff --git a/api/pom.xml b/api/pom.xml
index f602882..5fcd22d 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-internal-api</artifactId>

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

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 9fcf36e..1c92018 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-beatrix</artifactId>

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

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 86db146..0afb70c 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index fe6b2c7..f159b8d 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>

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

diff --git a/invoice/pom.xml b/invoice/pom.xml
index 2e1066a..1f5a4cb 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index a2c230f..38cd7a7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -20,13 +20,11 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import org.skife.jdbi.v2.exceptions.TransactionFailedException;
-
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
-import com.ning.billing.invoice.api.InvoicePaymentType;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
+import com.ning.billing.invoice.api.InvoicePaymentType;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceModelDao;
 import com.ning.billing.invoice.dao.InvoicePaymentModelDao;
@@ -44,8 +42,6 @@ import com.google.inject.Inject;
 
 public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
 
-    private static final WithInvoiceApiException<InvoicePayment> invoicePaymentWithException = new WithInvoiceApiException<InvoicePayment>();
-
     private final InvoiceDao dao;
     private final InternalCallContextFactory internalCallContextFactory;
 
@@ -140,38 +136,8 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
 
     @Override
     public InvoicePayment createChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
-        return invoicePaymentWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<InvoicePayment>() {
-
-            @Override
-            public InvoicePayment doHandle() throws InvoiceApiException {
-                // Retrieve the account id for the internal call context
-                final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(context));
-                return new DefaultInvoicePayment(dao.postChargeback(invoicePaymentId, amount, internalCallContextFactory.createInternalCallContext(accountId, context)));
-            }
-        });
-    }
-
-    //
-    // Allow to safely catch TransactionFailedException exceptions and rethrow the correct InvoiceApiException exception
-    //
-    private interface WithInvoiceApiExceptionCallback<T> {
-
-        public T doHandle() throws InvoiceApiException;
-    }
-
-    private static final class WithInvoiceApiException<T> {
-
-        public T executeAndThrow(final WithInvoiceApiExceptionCallback<T> callback) throws InvoiceApiException {
-
-            try {
-                return callback.doHandle();
-            } catch (TransactionFailedException e) {
-                if (e.getCause() instanceof InvoiceApiException) {
-                    throw (InvoiceApiException) e.getCause();
-                } else {
-                    throw e;
-                }
-            }
-        }
+        // Retrieve the account id for the internal call context
+        final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(context));
+        return new DefaultInvoicePayment(dao.postChargeback(invoicePaymentId, amount, internalCallContextFactory.createInternalCallContext(accountId, context)));
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index 7294f86..100e57d 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -25,7 +25,6 @@ import javax.inject.Inject;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
-import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.Currency;
@@ -48,9 +47,6 @@ import com.google.common.collect.Collections2;
 
 public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
 
-    private static final WithInvoiceApiException<InvoicePayment> invoicePaymentWithException = new WithInvoiceApiException<InvoicePayment>();
-    private static final WithInvoiceApiException<Void> voidWithException = new WithInvoiceApiException<Void>();
-
     private final InvoiceDao dao;
 
     @Inject
@@ -126,50 +122,14 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
 
     @Override
     public InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final UUID paymentCookieId, final InternalCallContext context) throws InvoiceApiException {
-        return invoicePaymentWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<InvoicePayment>() {
-
-            @Override
-            public InvoicePayment doHandle() throws InvoiceApiException {
-                if (amount.compareTo(BigDecimal.ZERO) <= 0) {
-                    throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
-                }
-                return new DefaultInvoicePayment(dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, context));
-            }
-        });
+        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
+            throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
+        }
+        return new DefaultInvoicePayment(dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, context));
     }
 
     @Override
     public void consumeExistingCBAOnAccountWithUnpaidInvoices(final UUID accountId, final InternalCallContext context) throws InvoiceApiException {
-        voidWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<Void>()  {
-            @Override
-            public Void doHandle() throws InvoiceApiException {
-                dao.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, context);
-                return null;
-            }
-        });
-    }
-
-    //
-    // Allow to safely catch TransactionFailedException exceptions and rethrow the correct InvoiceApiException exception
-    //
-    private interface WithInvoiceApiExceptionCallback<T> {
-
-        public T doHandle() throws InvoiceApiException;
-    }
-
-    private static final class WithInvoiceApiException<T> {
-
-        public T executeAndThrow(final WithInvoiceApiExceptionCallback<T> callback) throws InvoiceApiException {
-
-            try {
-                return callback.doHandle();
-            } catch (TransactionFailedException e) {
-                if (e.getCause() instanceof InvoiceApiException) {
-                    throw (InvoiceApiException) e.getCause();
-                } else {
-                    throw e;
-                }
-            }
-        }
+        dao.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, context);
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index f4e3fb3..41d5ff1 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -156,12 +156,11 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public InvoiceModelDao getByNumber(final Integer number, final InternalTenantContext context) throws InvoiceApiException {
-
         if (number == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_NUMBER, "(null)");
         }
 
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoiceModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoiceModelDao>() {
             @Override
             public InvoiceModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final InvoiceSqlDao invoiceDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
@@ -290,11 +289,10 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
     @Override
     public InvoicePaymentModelDao createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
                                                final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final UUID paymentCookieId,
-                                               final InternalCallContext context)
-            throws InvoiceApiException {
+                                               final InternalCallContext context) throws InvoiceApiException {
         final boolean isInvoiceItemAdjusted = isInvoiceAdjusted && invoiceItemIdsWithNullAmounts.size() > 0;
 
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
             @Override
             public InvoicePaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final InvoicePaymentSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class);
@@ -372,23 +370,20 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
             }
         });
     }
-
-
     @Override
     public InvoicePaymentModelDao postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final InternalCallContext context) throws InvoiceApiException {
-
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
             @Override
             public InvoicePaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final InvoicePaymentSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class);
 
                 final BigDecimal maxChargedBackAmount = invoiceDaoHelper.getRemainingAmountPaidFromTransaction(invoicePaymentId, entitySqlDaoWrapperFactory, context);
-                final BigDecimal requestedChargedBackAmout = (amount == null) ? maxChargedBackAmount : amount;
-                if (requestedChargedBackAmout.compareTo(BigDecimal.ZERO) <= 0) {
+                final BigDecimal requestedChargedBackAmount = (amount == null) ? maxChargedBackAmount : amount;
+                if (requestedChargedBackAmount.compareTo(BigDecimal.ZERO) <= 0) {
                     throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_IS_NEGATIVE);
                 }
-                if (requestedChargedBackAmout.compareTo(maxChargedBackAmount) > 0) {
-                    throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_TOO_HIGH, requestedChargedBackAmout, maxChargedBackAmount);
+                if (requestedChargedBackAmount.compareTo(maxChargedBackAmount) > 0) {
+                    throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_TOO_HIGH, requestedChargedBackAmount, maxChargedBackAmount);
                 }
 
                 final InvoicePaymentModelDao payment = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getById(invoicePaymentId.toString(), context);
@@ -397,7 +392,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                 }
                 final InvoicePaymentModelDao chargeBack = new InvoicePaymentModelDao(UUID.randomUUID(), context.getCreatedDate(), InvoicePaymentType.CHARGED_BACK,
                                                                                      payment.getInvoiceId(), payment.getPaymentId(), context.getCreatedDate(),
-                                                                                     requestedChargedBackAmout.negate(), payment.getCurrency(), null, payment.getId());
+                                                                                     requestedChargedBackAmount.negate(), payment.getCurrency(), null, payment.getId());
                 transactional.create(chargeBack, context);
 
                 // Notify the bus since the balance of the invoice changed
@@ -424,7 +419,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId, final InternalTenantContext context) throws InvoiceApiException {
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<UUID>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<UUID>() {
             @Override
             public UUID inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final UUID accountId = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getAccountIdFromInvoicePaymentId(invoicePaymentId.toString(), context);
@@ -459,7 +454,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public InvoicePaymentModelDao getChargebackById(final UUID chargebackId, final InternalTenantContext context) throws InvoiceApiException {
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
             @Override
             public InvoicePaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final InvoicePaymentModelDao chargeback = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getById(chargebackId.toString(), context);
@@ -474,10 +469,15 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public InvoiceItemModelDao getExternalChargeById(final UUID externalChargeId, final InternalTenantContext context) throws InvoiceApiException {
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoiceItemModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoiceItemModelDao>() {
             @Override
             public InvoiceItemModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
-                return entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class).getById(externalChargeId.toString(), context);
+                final InvoiceItemSqlDao invoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
+                final InvoiceItemModelDao invoiceItemModelDao = invoiceItemSqlDao.getById(externalChargeId.toString(), context);
+                if (invoiceItemModelDao == null) {
+                    throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, externalChargeId.toString());
+                }
+                return invoiceItemModelDao;
             }
         });
     }
@@ -532,10 +532,15 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public InvoiceItemModelDao getCreditById(final UUID creditId, final InternalTenantContext context) throws InvoiceApiException {
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoiceItemModelDao>() {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoiceItemModelDao>() {
             @Override
             public InvoiceItemModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
-                return entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class).getById(creditId.toString(), context);
+                final InvoiceItemSqlDao invoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
+                final InvoiceItemModelDao invoiceItemModelDao = invoiceItemSqlDao.getById(creditId.toString(), context);
+                if (invoiceItemModelDao == null) {
+                    throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, creditId.toString());
+                }
+                return invoiceItemModelDao;
             }
         });
     }
@@ -595,7 +600,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     @Override
     public void deleteCBA(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final InternalCallContext context) throws InvoiceApiException {
-        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+        transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
             public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final InvoiceSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
@@ -716,5 +721,4 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
             log.warn("Failed to post adjustment event for invoice " + invoiceId, e);
         }
     }
-
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index 52e780e..fee49c7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -141,14 +141,60 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
     }
 
     @Test(groups = "slow")
-    public void testRetrievalForNonExistentInvoiceId() throws InvoiceApiException {
+    public void testRetrievalForNonExistentInvoiceOrInvoiceItem() throws InvoiceApiException {
         try {
             invoiceDao.getById(UUID.randomUUID(), internalCallContext);
             Assert.fail();
         } catch (TransactionFailedException e) {
+            // TODO FIXME getById defined in EntityDaoBase
             Assert.assertTrue(e.getCause() instanceof InvoiceApiException);
             Assert.assertEquals(((InvoiceApiException) e.getCause()).getCode(), ErrorCode.INVOICE_NOT_FOUND.getCode());
         }
+
+        try {
+            invoiceDao.getByNumber(null, internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_INVALID_NUMBER.getCode());
+        }
+
+        try {
+            invoiceDao.getByNumber(Integer.MIN_VALUE, internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_NUMBER_NOT_FOUND.getCode());
+        }
+
+        try {
+            invoiceDao.getChargebackById(UUID.randomUUID(), internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.CHARGE_BACK_DOES_NOT_EXIST.getCode());
+        }
+
+        try {
+            invoiceDao.getExternalChargeById(UUID.randomUUID(), internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_ITEM_NOT_FOUND.getCode());
+        }
+
+        try {
+            invoiceDao.getCreditById(UUID.randomUUID(), internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_ITEM_NOT_FOUND.getCode());
+        }
+    }
+
+    @Test(groups = "slow")
+    public void testCreateRefundOnNonExistingPayment() throws Exception {
+        try {
+            invoiceDao.createRefund(UUID.randomUUID(), BigDecimal.TEN, false, ImmutableMap.<UUID, BigDecimal>of(), null, internalCallContext);
+            Assert.fail();
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_PAYMENT_BY_ATTEMPT_NOT_FOUND.getCode());
+        }
     }
 
     @Test(groups = "slow")
@@ -755,7 +801,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
-        invoiceDao.insertCredit(accountId, null,  new BigDecimal("20.0"), new LocalDate(), Currency.USD, internalCallContext);
+        invoiceDao.insertCredit(accountId, null, new BigDecimal("20.0"), new LocalDate(), Currency.USD, internalCallContext);
 
         final InvoiceItemModelDao charge = invoiceDao.insertExternalCharge(accountId, null, bundleId, "bla", new BigDecimal("15.0"), clock.getUTCNow().toLocalDate(), Currency.USD, internalCallContext);
 
@@ -1038,8 +1084,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0);
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan1, phase1, null,
-                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent1", 1L, SubscriptionTransitionType.CREATE);
 
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
@@ -1056,8 +1102,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan2, phase2, null,
-                                                           recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                                                           "testEvent2", 2L, SubscriptionTransitionType.CREATE);
+                                                                       recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent2", 2L, SubscriptionTransitionType.CREATE);
         events.add(event2);
 
         // second invoice should be for one half (14/28 days) the difference between the rate plans
@@ -1088,8 +1134,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final DateTime effectiveDate = invoiceUtil.buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate, plan, phase, null,
-                                                          recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
-                                                          "testEvent", 1L, SubscriptionTransitionType.CREATE);
+                                                                      recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+                                                                      "testEvent", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event);
 
@@ -1127,8 +1173,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final DateTime effectiveDate1 = invoiceUtil.buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1, fixedPrice.getPrice(currency),
-                                                           null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                                       null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent1", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
@@ -1145,8 +1191,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                                                           "testEvent2", 2L, SubscriptionTransitionType.PHASE);
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent2", 2L, SubscriptionTransitionType.PHASE);
         events.add(event2);
 
         final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), Currency.USD);
@@ -1192,16 +1238,16 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final DateTime effectiveDate1 = invoiceUtil.buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1,
-                                                           fixedPrice.getPrice(currency), null, currency,
-                                                           BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                                                           "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+                                                                       fixedPrice.getPrice(currency), null, currency,
+                                                                       BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent1", 1L, SubscriptionTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                                                           recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                                                           "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), Currency.USD);
@@ -1275,9 +1321,9 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         Mockito.when(phase2.getName()).thenReturn("plan-phase2");
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, recuringStartDate.toDateTimeAtStartOfDay(), plan, phase1, null,
-                                                           TEN, Currency.USD,
-                                                           BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
-                                                           "new-event", 1L, SubscriptionTransitionType.CREATE);
+                                                                       TEN, Currency.USD,
+                                                                       BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       "new-event", 1L, SubscriptionTransitionType.CREATE);
         events.add(event1);
         final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, Currency.USD);
         invoiceUtil.createInvoice(newInvoice, true, internalCallContext);
@@ -1309,9 +1355,9 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final List<Invoice> invoices = new ArrayList<Invoice>();
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
-                                                           TEN, currency,
-                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                                                           "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+                                                                       TEN, currency,
+                                                                       BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
         events.add(event1);
 
         Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), Currency.USD);
@@ -1321,9 +1367,9 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         assertNotNull(invoice1.getInvoiceNumber());
 
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, targetDate1, plan, phase2, null,
-                                                           TWENTY, currency,
-                                                           BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
-                                                           "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+                                                                       TWENTY, currency,
+                                                                       BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
         Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), Currency.USD);
         invoiceUtil.createInvoice(invoice2, true, internalCallContext);
@@ -1419,7 +1465,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         invoiceUtil.verifyInvoice(invoice2.getId(), 0.00, -5.00);
 
         // Refund Payment before we can deleted CBA
-        invoiceDao.createRefund(paymentId, new BigDecimal("10.0"), false, ImmutableMap.<UUID,BigDecimal>of(), UUID.randomUUID(), internalCallContext);
+        invoiceDao.createRefund(paymentId, new BigDecimal("10.0"), false, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), internalCallContext);
 
         // Verify all three invoices were affected
         Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
@@ -1530,9 +1576,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         try {
             invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
             Assert.fail();
-        } catch (TransactionFailedException e) {
-            Assert.assertTrue(e.getCause() instanceof InvoiceApiException);
-            Assert.assertEquals(((InvoiceApiException) e.getCause()).getCode(), ErrorCode.INVOICE_WOULD_BE_NEGATIVE.getCode());
+        } catch (InvoiceApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_WOULD_BE_NEGATIVE.getCode());
         }
 
         // Verify the result
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
index 55a181a..4f24e46 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
@@ -20,7 +20,6 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 import org.testng.annotations.Test;
 
 import com.ning.billing.ErrorCode;
@@ -73,29 +72,21 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow", expectedExceptions = InvoiceApiException.class)
     public void testChargeBackLargerThanPaymentAmount() throws InvoiceApiException {
-        try {
-            final Invoice invoice = createAndPersistInvoice(invoiceDao, clock, THIRTY, CURRENCY, internalCallContext);
-            final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
-
-            // create a large charge back
-            invoicePaymentApi.createChargeback(payment.getId(), ONE_MILLION, callContext);
-            fail("Expected a failure...");
-        } catch (TransactionFailedException expected) {
-            throw (InvoiceApiException) expected.getCause();
-        }
+        final Invoice invoice = createAndPersistInvoice(invoiceDao, clock, THIRTY, CURRENCY, internalCallContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
+
+        // create a large charge back
+        invoicePaymentApi.createChargeback(payment.getId(), ONE_MILLION, callContext);
+        fail("Expected a failure...");
     }
 
     @Test(groups = "slow", expectedExceptions = InvoiceApiException.class)
     public void testNegativeChargeBackAmount() throws InvoiceApiException {
-        try {
-            final Invoice invoice = createAndPersistInvoice(invoiceDao, clock, THIRTY, CURRENCY, internalCallContext);
-            final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
+        final Invoice invoice = createAndPersistInvoice(invoiceDao, clock, THIRTY, CURRENCY, internalCallContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
-            // create a partial charge back
-            invoicePaymentApi.createChargeback(payment.getId(), BigDecimal.ONE.negate(), callContext);
-        } catch (TransactionFailedException expected) {
-            throw (InvoiceApiException) expected.getCause();
-        }
+        // create a partial charge back
+        invoicePaymentApi.createChargeback(payment.getId(), BigDecimal.ONE.negate(), callContext);
     }
 
     @Test(groups = "slow")
@@ -111,9 +102,8 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
         try {
             invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.randomUUID(), callContext);
             fail();
-        } catch (TransactionFailedException e) {
-            assertTrue(e.getCause() instanceof InvoiceApiException);
-            assertEquals(((InvoiceApiException) e.getCause()).getCode(), ErrorCode.CHARGE_BACK_COULD_NOT_FIND_ACCOUNT_ID.getCode());
+        } catch (InvoiceApiException e) {
+            assertEquals(e.getCode(), ErrorCode.CHARGE_BACK_COULD_NOT_FIND_ACCOUNT_ID.getCode());
         }
     }
 

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

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index e733bd9..8ab6270 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-jaxrs</artifactId>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/NotificationJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/NotificationJson.java
index 87c1a66..85aa6f6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/NotificationJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/NotificationJson.java
@@ -33,21 +33,22 @@ public class NotificationJson {
 
     @JsonCreator
     public NotificationJson(@JsonProperty("eventType") final String eventType,
-            @JsonProperty("accountId") final String accountId,
-            @JsonProperty("objectType") final String objectType,
-            @JsonProperty("objectId") final String objectId) {
+                            @JsonProperty("accountId") final String accountId,
+                            @JsonProperty("objectType") final String objectType,
+                            @JsonProperty("objectId") final String objectId) {
         this.eventType = eventType;
         this.accountId = accountId;
         this.objectType = objectType;
         this.objectId = objectId;
     }
 
-
     public NotificationJson(final ExtBusEvent event) {
-        this(event.getEventType().toString(), event.getAccountId().toString(), event.getObjectType().toString(), event.getObjectId() != null ?  event.getObjectId().toString() : null);
+        this(event.getEventType().toString(),
+             event.getAccountId() != null ? event.getAccountId().toString() : null,
+             event.getObjectType().toString(),
+             event.getObjectId() != null ? event.getObjectId().toString() : null);
     }
 
-
     public String getEventType() {
         return eventType;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagJson.java
index fa62e86..12581cb 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagJson.java
@@ -13,26 +13,28 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.json;
 
 import java.util.List;
 
 import javax.annotation.Nullable;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.tag.TagDefinition;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class TagJson extends JsonBase {
 
     private final String tagDefinitionId;
     private final String tagDefinitionName;
 
     @JsonCreator
-    public TagJson(@JsonProperty("tagDefinitionId")  final String tagDefinitionId,
-            @JsonProperty("tagDefinitionName") final String tagDefinitionName,
-            @JsonProperty("auditLogs") @Nullable List<AuditLogJson> auditLogs) {
+    public TagJson(@JsonProperty("tagDefinitionId") final String tagDefinitionId,
+                   @JsonProperty("tagDefinitionName") final String tagDefinitionName,
+                   @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.tagDefinitionId = tagDefinitionId;
         this.tagDefinitionName = tagDefinitionName;
@@ -49,4 +51,41 @@ public class TagJson extends JsonBase {
     public String getTagDefinitionName() {
         return tagDefinitionName;
     }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("TagJson{");
+        sb.append("tagDefinitionId='").append(tagDefinitionId).append('\'');
+        sb.append(", tagDefinitionName='").append(tagDefinitionName).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final TagJson tagJson = (TagJson) o;
+
+        if (tagDefinitionId != null ? !tagDefinitionId.equals(tagJson.tagDefinitionId) : tagJson.tagDefinitionId != null) {
+            return false;
+        }
+        if (tagDefinitionName != null ? !tagDefinitionName.equals(tagJson.tagDefinitionName) : tagJson.tagDefinitionName != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = tagDefinitionId != null ? tagDefinitionId.hashCode() : 0;
+        result = 31 * result + (tagDefinitionName != null ? tagDefinitionName.hashCode() : 0);
+        return result;
+    }
 }
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
index 977f427..6dc12e4 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/InvoiceApiExceptionMapper.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/InvoiceApiExceptionMapper.java
@@ -62,6 +62,8 @@ public class InvoiceApiExceptionMapper extends ExceptionMapperBase implements Ex
             return buildBadRequestResponse(exception, uriInfo);
         } else if (exception.getCode() == ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_SHOULD_BE_POSITIVE.getCode()) {
             return buildBadRequestResponse(exception, uriInfo);
+        } else if (exception.getCode() == ErrorCode.INVOICE_ITEM_NOT_FOUND.getCode()) {
+            return buildNotFoundResponse(exception, uriInfo);
         } else if (exception.getCode() == ErrorCode.INVOICE_NO_SUCH_EXTERNAL_CHARGE.getCode()) {
             return buildBadRequestResponse(exception, uriInfo);
         } else if (exception.getCode() == ErrorCode.EXTERNAL_CHARGE_AMOUNT_INVALID.getCode()) {
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 40092a2..7af0b3d 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
@@ -130,6 +130,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
                                   final CallContext context) throws TagApiException {
         final Collection<UUID> input = getTagDefinitionUUIDs(tagList);
         tagUserApi.addTags(id, getObjectType(), input, context);
+        // TODO This will always return 201, even if some (or all) tags already existed (in which case we don't do anything)
         return uriBuilder.buildResponse(this.getClass(), "getTags", id, uriInfo.getBaseUri().toString());
     }
 
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 e0a9db9..5f78fcd 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
@@ -42,6 +42,7 @@ import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.tag.TagDefinition;
 
+import com.google.common.base.Preconditions;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -91,6 +92,10 @@ public class TagResource extends JaxRsResourceBase {
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+        // Checked as the database layer as well, but bail early and return 400 instead of 500
+        Preconditions.checkNotNull(json.getName(), String.format("TagDefinition name needs to be set"));
+        Preconditions.checkNotNull(json.getDescription(), String.format("TagDefinition description needs to be set"));
+
         final TagDefinition createdTagDef = tagUserApi.createTagDefinition(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment, request));
         return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getId());
     }

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

diff --git a/junction/pom.xml b/junction/pom.xml
index ad02848..e1e2d64 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-junction</artifactId>

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

diff --git a/osgi/pom.xml b/osgi/pom.xml
index 8c8d095..9cee110 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi</artifactId>
diff --git a/osgi-bundles/bundles/jruby/pom.xml b/osgi-bundles/bundles/jruby/pom.xml
index 0f97153..3eb4772 100644
--- a/osgi-bundles/bundles/jruby/pom.xml
+++ b/osgi-bundles/bundles/jruby/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill-osgi-bundles</artifactId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-jruby</artifactId>
diff --git a/osgi-bundles/bundles/logger/pom.xml b/osgi-bundles/bundles/logger/pom.xml
index bfb1baf..82cc8b4 100644
--- a/osgi-bundles/bundles/logger/pom.xml
+++ b/osgi-bundles/bundles/logger/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-logger</artifactId>
diff --git a/osgi-bundles/bundles/pom.xml b/osgi-bundles/bundles/pom.xml
index b9e76d1..5e99fb1 100644
--- a/osgi-bundles/bundles/pom.xml
+++ b/osgi-bundles/bundles/pom.xml
@@ -19,17 +19,15 @@
     <parent>
         <artifactId>killbill-osgi-all-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles</artifactId>
     <packaging>pom</packaging>
     <name>Killbill billing platform: OSGI bundles</name>
     <modules>
-        <module>analytics</module>
         <module>jruby</module>
         <module>logger</module>
-        <module>meter</module>
         <module>webconsolebranding</module>
     </modules>
 </project>
diff --git a/osgi-bundles/bundles/webconsolebranding/pom.xml b/osgi-bundles/bundles/webconsolebranding/pom.xml
index 68f2b8e..ca4ff10 100644
--- a/osgi-bundles/bundles/webconsolebranding/pom.xml
+++ b/osgi-bundles/bundles/webconsolebranding/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-webconsolebranding</artifactId>
diff --git a/osgi-bundles/defaultbundles/pom.xml b/osgi-bundles/defaultbundles/pom.xml
index 4e62e1c..6aa056c 100644
--- a/osgi-bundles/defaultbundles/pom.xml
+++ b/osgi-bundles/defaultbundles/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-all-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-defaultbundles</artifactId>
diff --git a/osgi-bundles/libs/killbill/pom.xml b/osgi-bundles/libs/killbill/pom.xml
index 3cba7da..6d48498 100644
--- a/osgi-bundles/libs/killbill/pom.xml
+++ b/osgi-bundles/libs/killbill/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-lib-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-lib-killbill</artifactId>
diff --git a/osgi-bundles/libs/pom.xml b/osgi-bundles/libs/pom.xml
index 7d20cc9..3f28414 100644
--- a/osgi-bundles/libs/pom.xml
+++ b/osgi-bundles/libs/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-all-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-lib-bundles</artifactId>
diff --git a/osgi-bundles/libs/slf4j-osgi/pom.xml b/osgi-bundles/libs/slf4j-osgi/pom.xml
index 9abd603..a9e0331 100644
--- a/osgi-bundles/libs/slf4j-osgi/pom.xml
+++ b/osgi-bundles/libs/slf4j-osgi/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-lib-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-lib-slf4j-osgi</artifactId>
diff --git a/osgi-bundles/pom.xml b/osgi-bundles/pom.xml
index 8e17c3e..5911dff 100644
--- a/osgi-bundles/pom.xml
+++ b/osgi-bundles/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-all-bundles</artifactId>
diff --git a/osgi-bundles/tests/beatrix/pom.xml b/osgi-bundles/tests/beatrix/pom.xml
index 15b97cb..a38d2ae 100644
--- a/osgi-bundles/tests/beatrix/pom.xml
+++ b/osgi-bundles/tests/beatrix/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-test-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-test-beatrix</artifactId>
diff --git a/osgi-bundles/tests/payment/pom.xml b/osgi-bundles/tests/payment/pom.xml
index 50caf19..f2dc983 100644
--- a/osgi-bundles/tests/payment/pom.xml
+++ b/osgi-bundles/tests/payment/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-test-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-test-payment</artifactId>
diff --git a/osgi-bundles/tests/pom.xml b/osgi-bundles/tests/pom.xml
index f8f7489..415d224 100644
--- a/osgi-bundles/tests/pom.xml
+++ b/osgi-bundles/tests/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-osgi-all-bundles</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-test-bundles</artifactId>

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

diff --git a/overdue/pom.xml b/overdue/pom.xml
index 02f3a83..f77ce0e 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-overdue</artifactId>

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

diff --git a/payment/pom.xml b/payment/pom.xml
index 8889360..afd43ab 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
index 3e88a00..2318459 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
@@ -114,14 +114,6 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    private PaymentPluginApi getPaymentPluginApi(final String pluginName) throws PaymentApiException {
-        final PaymentPluginApi pluginApi = pluginRegistry.getServiceForName(pluginName);
-        if (pluginApi == null) {
-            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_PLUGIN, pluginName);
-        }
-        return pluginApi;
-    }
-
     public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginInfo, final InternalTenantContext context) throws PaymentApiException {
 
         final List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId(), context);
diff --git a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
index 8055594..3f5ea77 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
@@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.bus.api.PersistentBus;
 import com.ning.billing.bus.api.PersistentBus.EventBusException;
 import com.ning.billing.invoice.api.Invoice;
@@ -109,24 +108,21 @@ public abstract class ProcessorBase {
         }
     }
 
+    protected PaymentPluginApi getPaymentPluginApi(final String pluginName) throws PaymentApiException {
+        final PaymentPluginApi pluginApi = pluginRegistry.getServiceForName(pluginName);
+        if (pluginApi == null) {
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_PLUGIN, pluginName);
+        }
+        return pluginApi;
+    }
+
     protected PaymentPluginApi getPaymentProviderPlugin(final UUID paymentMethodId, final InternalTenantContext context) throws PaymentApiException {
         final PaymentMethodModelDao methodDao = paymentDao.getPaymentMethodIncludedDeleted(paymentMethodId, context);
         if (methodDao == null) {
-            log.error("PaymentMethod dpes not exist", paymentMethodId);
+            log.error("PaymentMethod does not exist", paymentMethodId);
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
-        return pluginRegistry.getServiceForName(methodDao.getPluginName());
-    }
-
-    protected PaymentPluginApi getPaymentProviderPlugin(final String accountKey, final InternalTenantContext context)
-            throws AccountApiException, PaymentApiException {
-
-        final String paymentProviderName = null;
-        if (accountKey != null) {
-            final Account account = accountInternalApi.getAccountByKey(accountKey, context);
-            return getPaymentProviderPlugin(account, context);
-        }
-        return pluginRegistry.getServiceForName(paymentProviderName);
+        return getPaymentPluginApi(methodDao.getPluginName());
     }
 
     protected PaymentPluginApi getPaymentProviderPlugin(final Account account, final InternalTenantContext context) throws PaymentApiException {

pom.xml 4(+2 -2)

diff --git a/pom.xml b/pom.xml
index 1eadbc7..50c60e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,10 +19,10 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.1-SNAPSHOT</version>
+        <version>0.3.2-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
-    <version>0.3.2-SNAPSHOT</version>
+    <version>0.3.3-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>killbill</name>
     <description>Library for managing recurring subscriptions and the associated billing</description>

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

diff --git a/server/pom.xml b/server/pom.xml
index b62ca34..cda2834 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-server</artifactId>
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 f469837..4c90eab 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -34,13 +34,11 @@ import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.json.TagJson;
 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.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import static org.testng.Assert.assertEquals;
@@ -252,21 +250,32 @@ public class TestAccount extends TestJaxrsBase {
 
     @Test(groups = "slow")
     public void testTags() throws Exception {
-
+        final String accountId = UUID.randomUUID().toString();
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TAGS;
+        final String accountTagsUrl = getUrlFromUri(uri);
         // Use tag definition for AUTO_PAY_OFF
-        final TagDefinitionJson input = new TagDefinitionJson(new UUID(0, 1).toString(), false, "AUTO_PAY_OFF",
-                                                              "nothing more to say", ImmutableList.<String>of());
+        final String autoPayOffId = new UUID(0, 1).toString();
 
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_TAGS, input.getId());
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + UUID.randomUUID().toString() + "/" + JaxrsResource.TAGS;
-        Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        // Add a tag
+        Response response = doPost(uri, null, ImmutableMap.<String, String>of(JaxrsResource.QUERY_TAGS, autoPayOffId), DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        // Retrieves by Id based on Location returned
-        final String url = getUrlFromUri(uri);
-        response = doGetWithUrl(url, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        // Retrieves all tags
+        response = doGetWithUrl(accountTagsUrl, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final List<TagJson> tags1 = mapper.readValue(response.getResponseBody(), new TypeReference<List<TagJson>>() {});
+        Assert.assertEquals(tags1.size(), 1);
+        Assert.assertEquals(tags1.get(0).getTagDefinitionId(), autoPayOffId);
+
+        // Verify adding the same tag a second time doesn't do anything
+        response = doPost(uri, null, ImmutableMap.<String, String>of(JaxrsResource.QUERY_TAGS, autoPayOffId), DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        // Retrieves all tags again
+        response = doGetWithUrl(accountTagsUrl, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final List<TagJson> tags2 = mapper.readValue(response.getResponseBody(), new TypeReference<List<TagJson>>() {});
+        Assert.assertEquals(tags2, tags1);
     }
 
     @Test(groups = "slow")
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 ebea9ae..9003537 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -31,11 +31,22 @@ import com.google.common.collect.ImmutableList;
 
 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")
+    public void testTagErrorHandling() throws Exception {
+        final TagDefinitionJson[] tags = new TagDefinitionJson[]{new TagDefinitionJson(null, false, null, null, null),
+                                                                 new TagDefinitionJson(null, false, "something", null, null),
+                                                                 new TagDefinitionJson(null, false, null, "something", null)};
+        for (final TagDefinitionJson tag : tags) {
+            final String baseJson = mapper.writeValueAsString(tag);
+            final Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+            assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode());
+        }
+    }
+
+    @Test(groups = "slow")
     public void testTagDefinitionOk() throws Exception {
         final TagDefinitionJson input = new TagDefinitionJson(null, false, "blue", "relaxing color", ImmutableList.<String>of());
         String baseJson = mapper.writeValueAsString(input);

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

diff --git a/tenant/pom.xml b/tenant/pom.xml
index a5f393b..9800894 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-tenant</artifactId>

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

diff --git a/usage/pom.xml b/usage/pom.xml
index 139178e..39734b6 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-usage</artifactId>

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

diff --git a/util/pom.xml b/util/pom.xml
index 9116dce..c83eaa0 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -12,7 +12,7 @@
     <parent>
         <artifactId>killbill</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.3.2-SNAPSHOT</version>
+        <version>0.3.3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntityDaoBase.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntityDaoBase.java
index e4718c3..e69c388 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntityDaoBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntityDaoBase.java
@@ -38,12 +38,16 @@ public abstract class EntityDaoBase<M extends EntityModelDao<E>, E extends Entit
 
     @Override
     public void create(final M entity, final InternalCallContext context) throws U {
-        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+        transactionalSqlDao.execute(getCreateEntitySqlDaoTransactionWrapper(entity, context));
+    }
+
+    protected EntitySqlDaoTransactionWrapper<Void> getCreateEntitySqlDaoTransactionWrapper(final M entity, final InternalCallContext context) {
+        return new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
             public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final EntitySqlDao<M, E> transactional = entitySqlDaoWrapperFactory.become(realSqlDao);
 
-                if (transactional.getById(entity.getId().toString(), context) != null) {
+                if (checkEntityAlreadyExists(transactional, entity, context)) {
                     throw generateAlreadyExistsException(entity, context);
                 }
                 transactional.create(entity, context);
@@ -53,7 +57,11 @@ public abstract class EntityDaoBase<M extends EntityModelDao<E>, E extends Entit
                 postBusEventFromTransaction(entity, refreshedEntity, ChangeType.INSERT, entitySqlDaoWrapperFactory, context);
                 return null;
             }
-        });
+        };
+    }
+
+    protected boolean checkEntityAlreadyExists(final EntitySqlDao<M, E> transactional, final M entity, final InternalCallContext context) {
+        return transactional.getById(entity.getId().toString(), context) != null;
     }
 
     protected void postBusEventFromTransaction(final M entity, final M savedEntity, final ChangeType changeType,
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
index d562aa0..db23b1f 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
@@ -70,4 +70,24 @@ public class EntitySqlDaoTransactionalJdbiWrapper {
         final EntitySqlDao<EntityModelDao<Entity>, Entity> entitySqlDao = dbi.onDemand(InitialEntitySqlDao.class);
         return entitySqlDao.inTransaction(TransactionIsolationLevel.READ_COMMITTED, new JdbiTransaction<ReturnType, EntityModelDao<Entity>, Entity>(entitySqlDaoTransactionWrapper));
     }
+
+    /**
+     * @param entitySqlDaoTransactionWrapper transaction to execute
+     * @param <ReturnType>                   object type to return from the transaction
+     * @param <E>                            checked exception which can be thrown from the transaction
+     * @return result from the transaction fo type ReturnType
+     */
+    public <ReturnType, E extends Exception> ReturnType execute(final Class<E> exception, final EntitySqlDaoTransactionWrapper<ReturnType> entitySqlDaoTransactionWrapper) throws E {
+        try {
+            return execute(entitySqlDaoTransactionWrapper);
+        } catch (RuntimeException e) {
+            if (e.getCause() != null && e.getCause().getClass().isAssignableFrom(exception)) {
+                throw (E) e.getCause();
+            } else if (e.getCause() != null && e.getCause() instanceof RuntimeException) {
+                throw (RuntimeException) e.getCause();
+            } else {
+                throw e;
+            }
+        }
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
index de54c35..6c5f150 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
@@ -20,6 +20,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
@@ -110,7 +111,14 @@ public class DefaultTagUserApi implements TagUserApi {
     public void addTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final CallContext context) throws TagApiException {
         final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(objectId, objectType, context);
         final TagModelDao tag = new TagModelDao(context.getCreatedDate(), tagDefinitionId, objectId, objectType);
-        tagDao.create(tag, internalContext);
+        try {
+            tagDao.create(tag, internalContext);
+        } catch (TagApiException e) {
+            // Be lenient here and make the addTag method idempotent
+            if (ErrorCode.TAG_ALREADY_EXISTS.getCode() != e.getCode()) {
+                throw e;
+            }
+        }
     }
 
     @Override
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
index 70532ff..a3ceef1 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
@@ -49,6 +49,7 @@ import com.ning.billing.util.tag.api.user.TagEventBuilder;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
 public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiException> implements TagDao {
@@ -135,8 +136,22 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
     }
 
     @Override
+    protected boolean checkEntityAlreadyExists(final EntitySqlDao<TagModelDao, Tag> transactional, final TagModelDao entity, final InternalCallContext context) {
+        return Iterables.find(transactional.getByAccountRecordId(context),
+                              new Predicate<TagModelDao>() {
+                                  @Override
+                                  public boolean apply(final TagModelDao existingTag) {
+                                      return entity.equals(existingTag) || entity.isSame(existingTag);
+                                  }
+                              },
+                              null) != null;
+    }
+
+    @Override
     protected TagApiException generateAlreadyExistsException(final TagModelDao entity, final InternalCallContext context) {
-        return new TagApiException(ErrorCode.TAG_ALREADY_EXISTS, entity.getId());
+        // Print the tag details, not the id here, as we throw this exception when checking if a tag already exists
+        // by using the isSame(TagModelDao) method (see above)
+        return new TagApiException(ErrorCode.TAG_ALREADY_EXISTS, entity.toString());
     }
 
     private TagDefinitionModelDao getTagDefinitionFromTransaction(final UUID tagDefinitionId, final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InternalTenantContext context) throws TagApiException {
@@ -159,6 +174,11 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
     }
 
     @Override
+    public void create(final TagModelDao entity, final InternalCallContext context) throws TagApiException {
+        transactionalSqlDao.execute(TagApiException.class, getCreateEntitySqlDaoTransactionWrapper(entity, context));
+    }
+
+    @Override
     public void deleteTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final InternalCallContext context) throws TagApiException {
 
         transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
index ea6ce3f..d88163f 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
@@ -95,6 +95,10 @@ public class TagModelDao extends EntityBase implements EntityModelDao<Tag> {
 
         final TagModelDao that = (TagModelDao) o;
 
+        return isSame(that);
+    }
+
+    public boolean isSame(final TagModelDao that) {
         if (isActive != null ? !isActive.equals(that.isActive) : that.isActive != null) {
             return false;
         }
diff --git a/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
index af975cd..5ee87d6 100644
--- a/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
@@ -162,11 +162,12 @@ where <recordIdField("t.")> = :recordId
 ;
 >>
 
+/** Use NULL-safe equal to operator in case account_record_id is NULL **/
 getByAccountRecordId(accountRecordId) ::= <<
 select
 <allTableFields("t.")>
 from <tableName()> t
-where <accountRecordIdField("t.")> = :accountRecordId
+where <accountRecordIdField("t.")> \<=\> :accountRecordId
 <AND_CHECK_TENANT("t.")>
 ;
 >>