public interface Country extends BaseEntity {

    void setCode(final String code);

    String getCode();

    void setName(final String name);

    String getName();

    void setVatPercent(final BigDecimal vat);

    BigDecimal getVatPercent();

    void setIsEu(final boolean isEu);

    boolean getIsEu();
} public interface License extends BaseEntity {

    // Methods for working with properties

    String getName();

    void setName(String name);

    BigDecimal getPrice();

    void setPrice(BigDecimal price);

    Currency getCurrency();

    void setCurrency(Currency currency);

    Boolean getHidden();

    void setHidden(Boolean hidden);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getLicenseProperties();

    // Methods for interacting with other entities

    Licensee getLicensee();

    void setLicensee(Licensee licensee);

    LicenseTemplate getLicenseTemplate();

    void setLicenseTemplate(LicenseTemplate licenseTemplate);
} public interface LicenseTemplate extends BaseEntity {

    // Methods for working with properties

    String getName();

    void setName(String name);

    LicenseType getLicenseType();

    void setLicenseType(LicenseType licenseType);

    BigDecimal getPrice();

    void setPrice(BigDecimal price);

    Currency getCurrency();

    void setCurrency(Currency currency);

    Boolean getAutomatic();

    void setAutomatic(Boolean automatic);

    Boolean getHidden();

    void setHidden(Boolean hidden);

    Boolean getHideLicenses();

    void setHideLicenses(Boolean hideLicenses);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getLicenseTemplateProperties();

    // Methods for interacting with other entities

    ProductModule getProductModule();

    void setProductModule(ProductModule productModule);

    Collection<License> getLicenses();

} public interface Licensee extends BaseEntity {

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getLicenseeProperties();

    // Methods for interacting with other entities

    Product getProduct();

    void setProduct(Product product);

    Collection<License> getLicenses();

} public interface PaymentMethod extends BaseEntity {

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getPaymentMethodProperties();

} public interface Product extends BaseEntity {

    // Methods for working with properties

    String getName();

    void setName(String name);

    String getVersion();

    void setVersion(String version);

    Boolean getLicenseeAutoCreate();

    void setLicenseeAutoCreate(Boolean licenseeAutoCreate);

    String getDescription();

    void setDescription(String description);

    String getLicensingInfo();

    void setLicensingInfo(String licensingInfo);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getProductProperties();

    // Methods for interacting with other entities

    Collection<ProductModule> getProductModules();

    Collection<Licensee> getLicensees();

    List<ProductDiscount> getProductDiscounts();

    void addDiscount(ProductDiscount discount);
} public interface ProductModule extends BaseEntity {

    // Methods for working with properties

    String getName();

    void setName(String name);

    String getLicensingModel();

    void setLicensingModel(String licensingModel);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getProductModuleProperties();

    // Methods for interacting with other entities

    Product getProduct();

    void setProduct(Product product);

    Collection<LicenseTemplate> getLicenseTemplates();

} public interface Token extends BaseEntity {

    // Methods for working with properties

    String getVendorNumber();

    void setVendorNumber(String vendorNumber);

    Date getExpirationTime();

    void setExpirationTime(Date expirationTime);

    ITokenType getTokenType();

    void setTokenType(ITokenType tokenType);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getTokenProperties();

} public interface Transaction extends BaseEntity {

    // Methods for working with properties

    TransactionStatus getStatus();

    void setStatus(TransactionStatus status);

    TransactionSource getSource();

    void setSource(TransactionSource source);

    BigDecimal getGrandTotal();

    void setGrandTotal(BigDecimal grandTotal);

    BigDecimal getDiscount();

    void setDiscount(BigDecimal discount);

    Currency getCurrency();

    void setCurrency(Currency currency);

    Date getDateCreated();

    void setDateCreated(Date dateCreated);

    Date getDateClosed();

    void setDateClosed(Date dateClosed);

    List<LicenseTransactionJoin> getLicenseTransactionJoins();

    void setLicenseTransactionJoins(List<LicenseTransactionJoin> licenseTransactionJoins);

    // Methods for working with custom properties

    @Deprecated
    Map<String, String> getTransactionProperties();

} public class CountryImpl extends BaseEntityImpl implements Country {

    private static final long serialVersionUID = -6890659657570098474L;

    private String code;

    private String name;

    private BigDecimal vatPercent;

    private boolean isEu;

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public void setCode(final String code) {
        this.code = code;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public void setVatPercent(final BigDecimal vatPercent) {
        this.vatPercent = vatPercent;
    }

    @Override
    public BigDecimal getVatPercent() {
        return vatPercent;
    }

    @Override
    public void setIsEu(final boolean isEu) {
        this.isEu = isEu;
    }

    @Override
    public boolean getIsEu() {
        return isEu;
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.Country.CODE, getCode());
        map.add(Constants.Country.NAME, getName());
        map.add(Constants.Country.VAT_PERCENT, getVatPercent());
        map.add(Constants.Country.IS_EU, getIsEu());
        return map;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("Country [");
        builder.append(Constants.Country.CODE);
        builder.append("=");
        builder.append(getCode());
        builder.append(", ");
        builder.append(Constants.Country.NAME);
        builder.append("=");
        builder.append(getName());
        builder.append(", ");
        builder.append(Constants.Country.VAT_PERCENT);
        builder.append("=");
        builder.append(getVatPercent());
        builder.append(", ");
        builder.append(Constants.Country.IS_EU);
        builder.append("=");
        builder.append(getIsEu());
        builder.append("]");
        return builder.toString();
    }
} public class LicenseImpl extends BaseEntityImpl implements License {

    private static final long serialVersionUID = -1255007603439878867L;

    private String name;

    private BigDecimal price;

    private Currency currency;

    private Boolean hidden = Boolean.FALSE;

    private Licensee licensee;

    private LicenseTemplate licenseTemplate;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.NAME);
        reserved.add(Constants.PRICE);
        reserved.add(Constants.CURRENCY);
        reserved.add(Constants.License.HIDDEN);
        reserved.add(Constants.Licensee.LICENSEE_NUMBER); // maps to 'licensee'
        reserved.add(Constants.LicenseTemplate.LICENSE_TEMPLATE_NUMBER); // maps to 'licenseTemplate'
        reserved.add(Constants.Transaction.TRANSACTION_NUMBER); // maps to 'licenseTransactionJoins'
        reserved.add(Constants.Shop.PROP_SHOP_LICENSE_ID); // used by shop, therefore disallowed for user
        reserved.add(Constants.Shop.PROP_SHOPPING_CART); // used by shop, therefore disallowed for user
        reserved.add(Constants.Vendor.VENDOR_NUMBER); // used by shop, therefore disallowed for user
        return reserved;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public void setPrice(final BigDecimal price) {
        this.price = price;
    }

    @Override
    public Currency getCurrency() {
        return currency;
    }

    @Override
    public void setCurrency(final Currency currency) {
        this.currency = currency;
    }

    @Override
    public Boolean getHidden() {
        return hidden;
    }

    @Override
    public void setHidden(final Boolean hidden) {
        this.hidden = hidden;
    }

    @Override
    public Licensee getLicensee() {
        return licensee;
    }

    @Override
    public void setLicensee(final Licensee licensee) {
        licensee.getLicenses().add(this);
        this.licensee = licensee;
    }

    @Override
    public LicenseTemplate getLicenseTemplate() {
        return licenseTemplate;
    }

    @Override
    public void setLicenseTemplate(final LicenseTemplate licenseTemplate) {
        licenseTemplate.getLicenses().add(this);
        this.licenseTemplate = licenseTemplate;
    }

    @Override
    public Map<String, String> getLicenseProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.NAME, getName());
        map.add(Constants.PRICE, getPrice());
        map.add(Constants.CURRENCY, getCurrency());
        map.add(Constants.License.HIDDEN, getHidden());
        return map;
    }

} public class LicenseTemplateImpl extends BaseEntityImpl implements LicenseTemplate {

    private static final long serialVersionUID = -6957717868558780419L;

    private ProductModule productModule;

    private String name;

    private LicenseType licenseType;

    private BigDecimal price;

    private Currency currency;

    private Boolean automatic = Boolean.FALSE;

    private Boolean hidden = Boolean.FALSE;

    private Boolean hideLicenses = Boolean.FALSE;

    private Collection<License> licenses;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.ProductModule.PRODUCT_MODULE_NUMBER); // maps to 'productModule'
        reserved.add(Constants.ProductModule.PRODUCT_MODULE_NAME); // maps to 'productModule'
        reserved.add(Constants.NAME);
        reserved.add(Constants.LicenseTemplate.LICENSE_TYPE);
        reserved.add(Constants.PRICE);
        reserved.add(Constants.CURRENCY);
        reserved.add(Constants.IN_USE);
        reserved.add(Constants.LicenseTemplate.AUTOMATIC);
        reserved.add(Constants.LicenseTemplate.HIDDEN);
        reserved.add(Constants.LicenseTemplate.HIDE_LICENSES);
        reserved.add(Constants.Shop.PROP_SHOP_LICENSE_ID); // used by shop in licenses, therefore disallowed for user
        reserved.add(Constants.Shop.PROP_SHOPPING_CART); // used by shop in licenses, therefore disallowed for user
        return reserved;
    }

    @Override
    public ProductModule getProductModule() {
        return productModule;
    }

    @Override
    public void setProductModule(final ProductModule productModule) {
        productModule.getLicenseTemplates().add(this);
        this.productModule = productModule;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public LicenseType getLicenseType() {
        return licenseType;
    }

    @Override
    public void setLicenseType(final LicenseType licenseType) {
        this.licenseType = licenseType;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public void setPrice(final BigDecimal price) {
        this.price = price;
    }

    @Override
    public Currency getCurrency() {
        return currency;
    }

    @Override
    public void setCurrency(final Currency currency) {
        this.currency = currency;
    }

    @Override
    public Boolean getAutomatic() {
        return automatic;
    }

    @Override
    public void setAutomatic(final Boolean automatic) {
        this.automatic = automatic;
    }

    @Override
    public Boolean getHidden() {
        return hidden;
    }

    @Override
    public void setHidden(final Boolean hidden) {
        this.hidden = hidden;
    }

    @Override
    public Boolean getHideLicenses() {
        return hideLicenses;
    }

    @Override
    public void setHideLicenses(final Boolean hideLicenses) {
        this.hideLicenses = hideLicenses;
    }

    @Override
    public Collection<License> getLicenses() {
        if (licenses == null) {
            licenses = new ArrayList<License>();
        }
        return licenses;
    }

    public void setLicenses(final Collection<License> licenses) {
        this.licenses = licenses;
    }

    @Override
    public Map<String, String> getLicenseTemplateProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.NAME, getName());
        map.add(Constants.LicenseTemplate.LICENSE_TYPE, getLicenseType());
        map.add(Constants.PRICE, getPrice());
        map.add(Constants.CURRENCY, getCurrency());
        map.add(Constants.LicenseTemplate.AUTOMATIC, getAutomatic());
        map.add(Constants.LicenseTemplate.HIDDEN, getHidden());
        map.add(Constants.LicenseTemplate.HIDE_LICENSES, getHideLicenses());
        return map;
    }

} public class LicenseeImpl extends BaseEntityImpl implements Licensee {

    private static final long serialVersionUID = 2704374141788131247L;

    private Product product;

    private Collection<License> licenses;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.Product.PRODUCT_NUMBER); // maps to 'product'
        reserved.add(Constants.IN_USE);
        reserved.add(Constants.Vendor.VENDOR_NUMBER); // used by shop, therefore disallowed for user
        return reserved;
    }

    @Override
    public Product getProduct() {
        return product;
    }

    @Override
    public void setProduct(final Product product) {
        product.getLicensees().add(this);
        this.product = product;
    }

    @Override
    public Collection<License> getLicenses() {
        if (licenses == null) {
            licenses = new ArrayList<License>();
        }
        return licenses;
    }

    public void setLicenses(final Collection<License> licenses) {
        this.licenses = licenses;
    }

    @Override
    public Map<String, String> getLicenseeProperties() {
        return getProperties();
    }

} public class PaymentMethodImpl extends BaseEntityImpl implements PaymentMethod {

    private static final long serialVersionUID = -529417516632266683L;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        return BaseEntityImpl.getReservedProps();
    }

    @Override
    public Map<String, String> getPaymentMethodProperties() {
        return getProperties();
    }

} public class ProductImpl extends BaseEntityImpl implements Product {

    private static final long serialVersionUID = 7030811820855516068L;

    private String name;

    private String version;

    private Boolean licenseeAutoCreate;

    private String description;

    private String licensingInfo;

    private Collection<ProductModule> productModules;

    private Collection<Licensee> licensees;

    private List<ProductDiscount> productDiscounts;

    private Boolean productDiscountsTouched = false;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.NAME);
        reserved.add(Constants.VERSION);
        reserved.add(Constants.Product.LICENSEE_AUTO_CREATE);
        reserved.add(Constants.Product.DESCRIPTION);
        reserved.add(Constants.Product.LICENSING_INFO);
        reserved.add(Constants.DISCOUNT);
        reserved.add(Constants.IN_USE);
        return reserved;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public String getVersion() {
        return version;
    }

    @Override
    public void setVersion(final String version) {
        this.version = version;
    }

    @Override
    public Boolean getLicenseeAutoCreate() {
        return licenseeAutoCreate;
    }

    @Override
    public void setLicenseeAutoCreate(final Boolean licenseeAutoCreate) {
        this.licenseeAutoCreate = licenseeAutoCreate;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public void setDescription(final String description) {
        this.description = description;
    }

    @Override
    public String getLicensingInfo() {
        return licensingInfo;
    }

    @Override
    public void setLicensingInfo(final String licensingInfo) {
        this.licensingInfo = licensingInfo;
    }

    @Override
    public Collection<ProductModule> getProductModules() {
        if (productModules == null) {
            productModules = new ArrayList<>();
        }
        return productModules;
    }

    public void setProductModules(final Collection<ProductModule> productModules) {
        this.productModules = productModules;
    }

    @Override
    public Collection<Licensee> getLicensees() {
        if (licensees == null) {
            licensees = new ArrayList<>();
        }
        return licensees;
    }

    public void setLicensees(final Collection<Licensee> licensees) {
        this.licensees = licensees;
    }

    @Override
    public List<ProductDiscount> getProductDiscounts() {
        if (productDiscounts == null) {
            productDiscounts = new ArrayList<>();
        }
        return productDiscounts;
    }

    public void setProductDiscounts(final List<ProductDiscount> productDiscounts) {
        this.productDiscounts = productDiscounts;
        for (final ProductDiscount productDiscount : this.productDiscounts) {
            productDiscount.setProduct(this);
        }
        productDiscountsTouched = true;
    }

    public void setProductDiscounts() {
        this.productDiscounts = new ArrayList<>();
        productDiscountsTouched = true;
    }

    @Override
    public void addDiscount(final ProductDiscount discount) {
        discount.setProduct(this);
        getProductDiscounts().add(discount);
        productDiscountsTouched = true;
    }

    @Override
    public Map<String, String> getProductProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.NAME, getName());
        map.add(Constants.VERSION, getVersion());
        map.add(Constants.Product.LICENSEE_AUTO_CREATE, getLicenseeAutoCreate());
        map.add(Constants.Product.DESCRIPTION, getDescription());
        map.add(Constants.Product.LICENSING_INFO, getLicensingInfo());
        if (productDiscounts != null) {
            for (final ProductDiscount productDiscount : productDiscounts) {
                map.add(Constants.DISCOUNT, productDiscount.toString());
            }
        }

        if (map.get(Constants.DISCOUNT) == null && productDiscountsTouched) {
            map.add(Constants.DISCOUNT, "");
        }

        return map;
    }

} public class ProductModuleImpl extends BaseEntityImpl implements ProductModule {

    private static final long serialVersionUID = 6327895102315403718L;

    private Product product;

    private String name;

    private String licensingModel;

    private Collection<LicenseTemplate> licenseTemplates;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.NAME);
        reserved.add(Constants.ProductModule.LICENSING_MODEL);
        reserved.add(Constants.Product.PRODUCT_NUMBER);
        reserved.add(Constants.IN_USE);
        return reserved;
    }

    @Override
    public Product getProduct() {
        return product;
    }

    @Override
    public void setProduct(final Product product) {
        product.getProductModules().add(this);
        this.product = product;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public String getLicensingModel() {
        return licensingModel;
    }

    @Override
    public void setLicensingModel(final String licensingModel) {
        this.licensingModel = licensingModel;
    }

    @Override
    public Collection<LicenseTemplate> getLicenseTemplates() {
        if (licenseTemplates == null) {
            licenseTemplates = new ArrayList<LicenseTemplate>();
        }
        return licenseTemplates;
    }

    public void setLicenseTemplates(final Collection<LicenseTemplate> licenseTemplates) {
        this.licenseTemplates = licenseTemplates;
    }

    @Override
    public Map<String, String> getProductModuleProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.NAME, getName());
        map.add(Constants.ProductModule.LICENSING_MODEL, getLicensingModel());
        return map;
    }

} public class TokenImpl extends BaseEntityImpl implements Token {

    private static final long serialVersionUID = 6688976030475491351L;

    private String vendorNumber;

    private Date expirationTime;

    private ITokenType tokenType;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.Token.EXPIRATION_TIME);
        reserved.add(Constants.Token.TOKEN_TYPE);
        return reserved;
    }

    @Override
    public String getVendorNumber() {
        return vendorNumber;
    }

    @Override
    public void setVendorNumber(final String vendorNumber) {
        this.vendorNumber = vendorNumber;
    }

    @Override
    public Date getExpirationTime() {
        if (expirationTime == null) {
            return null;
        } else {
            return new Date(expirationTime.getTime());
        }
    }

    @Override
    public void setExpirationTime(final Date expirationTime) {
        if (expirationTime == null) {
            this.expirationTime = null;
        } else {
            this.expirationTime = new Date(expirationTime.getTime());
        }
    }

    @Override
    public ITokenType getTokenType() {
        return tokenType;
    }

    @Override
    public void setTokenType(final ITokenType tokenType) {
        this.tokenType = tokenType;
    }

    @Override
    public Map<String, String> getTokenProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.Token.EXPIRATION_TIME, getExpirationTime());
        map.add(Constants.Token.TOKEN_TYPE, getTokenType());
        map.add(Constants.Token.TOKEN_PROP_VENDORNUMBER, getVendorNumber());
        return map;
    }

} public class TransactionImpl extends BaseEntityImpl implements Transaction {

    private static final long serialVersionUID = 7675242025748195251L;

    private TransactionStatus status;

    private TransactionSource source;

    private BigDecimal grandTotal;

    private BigDecimal discount;

    private Currency currency;

    private Date dateCreated;

    private Date dateClosed;

    private List<LicenseTransactionJoin> licenseTransactionJoins;

    /**
     * @see BaseEntityImpl#getReservedProps()
     */
    public static List<String> getReservedProps() {
        final List<String> reserved = BaseEntityImpl.getReservedProps();
        reserved.add(Constants.Transaction.SOURCE);
        reserved.add(Constants.Transaction.STATUS);
        reserved.add(Constants.Transaction.DATE_CREATED);
        reserved.add(Constants.Transaction.DATE_CLOSED);
        reserved.add(Constants.IN_USE);
        reserved.add(Constants.Transaction.GRAND_TOTAL);
        reserved.add(Constants.DISCOUNT);
        reserved.add(Constants.CURRENCY);
        return reserved;
    }

    @Override
    public TransactionStatus getStatus() {
        return status;
    }

    @Override
    public void setStatus(final TransactionStatus status) {
        this.status = status;
    }

    @Override
    public TransactionSource getSource() {
        return source;
    }

    @Override
    public void setSource(final TransactionSource source) {
        this.source = source;
    }

    @Override
    public BigDecimal getGrandTotal() {
        return grandTotal;
    }

    @Override
    public void setGrandTotal(final BigDecimal grandTotal) {
        this.grandTotal = grandTotal;
    }

    @Override
    public BigDecimal getDiscount() {
        return discount;
    }

    @Override
    public void setDiscount(final BigDecimal discount) {
        this.discount = discount;
    }

    @Override
    public Currency getCurrency() {
        return currency;
    }

    @Override
    public void setCurrency(final Currency currency) {
        this.currency = currency;
    }

    @Override
    public Date getDateCreated() {
        if (dateCreated == null) {
            return null;
        } else {
            return new Date(dateCreated.getTime());
        }
    }

    @Override
    public void setDateCreated(final Date dateCreated) {
        if (dateCreated == null) {
            this.dateCreated = new Date();
        } else {
            this.dateCreated = new Date(dateCreated.getTime());
        }
    }

    @Override
    public Date getDateClosed() {
        if (dateClosed == null) {
            return null;
        } else {
            return new Date(dateClosed.getTime());
        }
    }

    @Override
    public void setDateClosed(final Date dateClosed) {
        if (dateClosed == null) {
            this.dateClosed = null;
        } else {
            this.dateClosed = new Date(dateClosed.getTime());
        }
    }

    @Override
    public Map<String, String> getTransactionProperties() {
        return getProperties();
    }

    @Override
    protected MultivaluedMap<String, Object> asPropertiesMap() {
        final MultivaluedMap<String, Object> map = super.asPropertiesMap();
        map.add(Constants.Transaction.STATUS, getStatus());
        map.add(Constants.Transaction.SOURCE, getSource());
        map.add(Constants.Transaction.GRAND_TOTAL, getGrandTotal());
        map.add(Constants.DISCOUNT, getDiscount());
        map.add(Constants.CURRENCY, getCurrency());
        return map;
    }

    @Override
    public List<LicenseTransactionJoin> getLicenseTransactionJoins() {
        if (licenseTransactionJoins == null) {
            licenseTransactionJoins = new ArrayList<>();
        }
        return licenseTransactionJoins;
    }

    @Override
    public void setLicenseTransactionJoins(final List<LicenseTransactionJoin> licenseTransactionJoins) {
        this.licenseTransactionJoins = licenseTransactionJoins;
    }

} public class Context extends GenericContext<String> {

    private String publicKey;

    public Context() {
        super(String.class);
    }

    public Context setBaseUrl(final String baseUrl) {
        return (Context) this.setValue(Constants.BASE_URL, baseUrl);
    }

    public String getBaseUrl() {
        return getValue(Constants.BASE_URL);
    }

    public Context setUsername(final String username) {
        return (Context) this.setValue(Constants.USERNAME, username);
    }

    public String getUsername() {
        return getValue(Constants.USERNAME);
    }

    public Context setPassword(final String password) {
        return (Context) this.setValue(Constants.PASSWORD, password);
    }

    public String getPassword() {
        return getValue(Constants.PASSWORD);
    }

    public Context setApiKey(final String apiKey) {
        return (Context) this.setValue(Constants.Token.API_KEY, apiKey);
    }

    public String getApiKey() {
        return getValue(Constants.Token.API_KEY);
    }

    public Context setSecurityMode(final SecurityMode securityMode) {
        return (Context) this.setValue(Constants.SECURITY_MODE, securityMode.toString());
    }

    public SecurityMode getSecurityMode() {
        final String securityMode = getValue(Constants.SECURITY_MODE);
        return securityMode != null ? SecurityMode.valueOf(securityMode) : null;
    }

    public Context setVendorNumber(final String vendorNumber) {
        return (Context) this.setValue(Constants.Vendor.VENDOR_NUMBER, vendorNumber);
    }

    public String getVendorNumber() {
        return getValue(Constants.Vendor.VENDOR_NUMBER);
    }

    /**
     * Add public key to be used for validate signed NetLicensing response.
     *
     * @param publicKey
     *            client publicKey.
     */
    public void setPublicKey(final String publicKey) {
        this.publicKey = publicKey;
    }

    public String getPublicKey() {
        return publicKey;
    }

} public interface Page<Entity> extends Iterable<Entity> {

    /**
     * Returns the number of the current page. Is always non-negative.
     * 
     * @return the number of the current page.
     */
    int getPageNumber();

    /**
     * Returns the number of elements on the page.
     * 
     * @return the number of elements on the page.
     */
    int getItemsNumber();

    /**
     * Returns the number of total pages.
     * 
     * @return the number of total pages
     */
    int getTotalPages();

    /**
     * Returns the total amount of elements.
     * 
     * @return the total amount of elements
     */
    long getTotalItems();

    /**
     * Returns if there is a next page exists.
     * 
     * @return true if there is a next page exists, otherwise false.
     */
    boolean hasNext();

    /**
     * Return container content.
     * 
     * @return container content
     */
    List<Entity> getContent();

    /**
     * Returns if there is a content exists.
     * 
     * @return true if there is a content exists, otherwise false
     */
    boolean hasContent();

} public class ConversionException extends NetLicensingException {

    private static final long serialVersionUID = -3798344733724547819L;

    /**
     * Construct a <code>ConversionException</code> with the specified detail message.
     * 
     * @param msg
     *            the detail message
     */
    public ConversionException(final String msg) {
        super(msg);
    }

    /**
     * Construct a <code>ConversionException</code> with the specified detail message and cause exception.
     * 
     * @param msg
     *            the detail message
     * @param cause
     *            the cause exception
     */
    public ConversionException(final String msg, final Throwable cause) {
        super(msg, cause);
    }

} public abstract class NetLicensingException extends Exception {

    private static final long serialVersionUID = -1101213597571076128L;

    /**
     * Construct a <code>NetLicensingException</code> with the specified detail message.
     * 
     * @param msg
     *            the detail message
     */
    public NetLicensingException(final String msg) {
        super(msg);
    }

    /**
     * Construct a <code>NetLicensingException</code> with the specified detail message and cause exception.
     * 
     * @param msg
     *            the detail message
     * @param cause
     *            the cause exception
     */
    public NetLicensingException(final String msg, final Throwable cause) {
        super(msg, cause);
    }

    /**
     * Return the detail message, including the message from the cause exception if there is one.
     * 
     * @return error detail message
     */
    @Override
    public String getMessage() {
        return ExceptionUtils.buildMessage(super.getMessage(), getCause());
    }

    /**
     * Retrieve the innermost cause of this exception, if any.
     * 
     * @return the innermost exception, or <code>null</code> if none
     */
    public Throwable getRootCause() {
        Throwable rootCause = null;
        Throwable cause = getCause();
        while ((cause != null) && (cause != rootCause)) {
            rootCause = cause;
            cause = cause.getCause();
        }
        return rootCause;
    }

    /**
     * Retrieve the most specific cause of this exception, that is, either the innermost cause (root cause) or this
     * exception itself.
     * <p>
     * Differs from {@link #getRootCause()} in that it falls back to the present exception if there is no root cause.
     * 
     * @return the most specific cause (never <code>null</code>)
     */
    public Throwable getMostSpecificCause() {
        final Throwable rootCause = getRootCause();
        if (rootCause == null) {
            return this;
        } else {
            return rootCause;
        }
    }

    /**
     * Check whether this exception contains an exception of the given type: either it is of the given class itself or
     * it contains a cause cause of the given type.
     * 
     * @param exType
     *            the exception type to look for
     * @return whether there is a cause exception of the specified type
     */
    public boolean contains(final Class<Throwable> exType) {
        if (exType == null) {
            return false;
        }
        if (exType.isInstance(this)) {
            return true;
        }
        Throwable cause = getCause();
        if (cause == this) {
            return false;
        }
        if (cause instanceof NetLicensingException) {
            return ((NetLicensingException) cause).contains(exType);
        } else {
            while (cause != null) {
                if (exType.isInstance(cause)) {
                    return true;
                }
                if (cause.getCause() == cause) {
                    break;
                }
                cause = cause.getCause();
            }
            return false;
        }
    }

} public class LicenseService {

    /**
     * Creates new license object with given properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param licenseeNumber
     *            parent licensee to which the new license is to be added
     * @param licenseTemplateNumber
     *            license template that the license is created from
     * @param transactionNumber
     *            For privileged logins specifies transaction for the license creation. For regular logins new
     *            transaction always created implicitly, and the operation will be in a separate transaction.
     *            Transaction is generated with the provided transactionNumber, or, if transactionNumber is null, with
     *            auto-generated number.
     * @param license
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created license object
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static License create(final Context context, final String licenseeNumber,
            final String licenseTemplateNumber,
            final String transactionNumber, final License license) throws NetLicensingException {

        CheckUtils.paramNotNull(license, "license");

        final Form form = license.asRequestForm();
        if (StringUtils.isNotBlank(licenseeNumber)) {
            form.param(Constants.Licensee.LICENSEE_NUMBER, licenseeNumber);
        }
        if (StringUtils.isNotBlank(licenseTemplateNumber)) {
            form.param(Constants.LicenseTemplate.LICENSE_TEMPLATE_NUMBER, licenseTemplateNumber);
        }
        if (StringUtils.isNotBlank(transactionNumber)) {
            form.param(Constants.Transaction.TRANSACTION_NUMBER, transactionNumber);
        }
        return NetLicensingService.getInstance().post(context, Constants.License.ENDPOINT_PATH, form, License.class);
    }

    /**
     * Gets license by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the license number
     * @return the license
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static License get(final Context context, final String number) throws NetLicensingException {
        return NetLicensingService.getInstance().get(context, Constants.License.ENDPOINT_PATH + "/" + number, null, License.class);
    }

    /**
     * Returns licenses of a vendor.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return list of licenses (of all products) or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Page<License> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.License.ENDPOINT_PATH, params, License.class);
    }

    /**
     * Updates license properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            license number
     * @param transactionNumber
     *            transaction for the license update. Created implicitly if transactionNumber is null. In this case the
     *            operation will be in a separate transaction.
     * @param license
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated license.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static License update(final Context context, final String number, final String transactionNumber,
            final License license) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(license, "license");

        final Form form = license.asRequestForm();
        if (StringUtils.isNotBlank(transactionNumber)) {
            form.param(Constants.Transaction.TRANSACTION_NUMBER, transactionNumber);
        }
        return NetLicensingService.getInstance().post(context, Constants.License.ENDPOINT_PATH + "/" + number, form, License.class);
    }

    /**
     * Deletes license.
     * <p>
     * When any license is deleted, corresponding transaction is created automatically.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            license number
     * @param forceCascade
     *            if true, any entities that depend on the one being deleted will be deleted too
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static void delete(final Context context, final String number, final boolean forceCascade)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        final Map<String, Object> params = new HashMap<String, Object>();
        params.put(Constants.CASCADE, forceCascade);
        NetLicensingService.getInstance().delete(context, Constants.License.ENDPOINT_PATH + "/" + number, params);
    }

} public class LicenseTemplateService {

    /**
     * Creates new license template object with given properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param productModuleNumber
     *            parent product module to which the new license template is to be added
     * @param licenseTemplate
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created license template object
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static LicenseTemplate create(final Context context, final String productModuleNumber,
            final LicenseTemplate licenseTemplate) throws NetLicensingException {
        CheckUtils.paramNotNull(licenseTemplate, "licenseTemplate");

        final Form form = licenseTemplate.asRequestForm();
        if (StringUtils.isNotBlank(productModuleNumber)) {
            form.param(Constants.ProductModule.PRODUCT_MODULE_NUMBER, productModuleNumber);
        }
        return NetLicensingService.getInstance().post(context, Constants.LicenseTemplate.ENDPOINT_PATH, form, LicenseTemplate.class);
    }

    /**
     * Gets license template by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the license template number
     * @return the license template
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static LicenseTemplate get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.LicenseTemplate.ENDPOINT_PATH + "/" + number, null, LicenseTemplate.class);
    }

    /**
     * Returns all license templates of a vendor.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return list of license templates (of all products/modules) or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Page<LicenseTemplate> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.LicenseTemplate.ENDPOINT_PATH, params, LicenseTemplate.class);
    }

    /**
     * Updates license template properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            license template number
     * @param licenseTemplate
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated license template.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static LicenseTemplate update(final Context context, final String number,
            final LicenseTemplate licenseTemplate) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(licenseTemplate, "licenseTemplate");

        return NetLicensingService.getInstance().post(context, Constants.LicenseTemplate.ENDPOINT_PATH + "/" + number,
                licenseTemplate.asRequestForm(), LicenseTemplate.class);
    }

    /**
     * Deletes license template.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            license template number
     * @param forceCascade
     *            if true, any entities that depend on the one being deleted will be deleted too
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static void delete(final Context context, final String number, final boolean forceCascade)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        final Map<String, Object> params = new HashMap<String, Object>();
        params.put(Constants.CASCADE, forceCascade);
        NetLicensingService.getInstance().delete(context, Constants.LicenseTemplate.ENDPOINT_PATH + "/" + number, params);
    }

} public class LicenseeService {

    /**
     * Creates new licensee object with given properties.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param productNumber
     *            parent product to which the new licensee is to be added
     * @param licensee
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created licensee object
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static Licensee create(final Context context, final String productNumber, final Licensee licensee)
            throws NetLicensingException {
        CheckUtils.paramNotNull(licensee, "licensee");

        final Form form = licensee.asRequestForm();
        if (StringUtils.isNotBlank(productNumber)) {
            form.param(Constants.Product.PRODUCT_NUMBER, productNumber);
        }
        return NetLicensingService.getInstance().post(context, Constants.Licensee.ENDPOINT_PATH, form, Licensee.class);
    }

    /**
     * Gets licensee by its number.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the licensee number
     * @return the licensee
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static Licensee get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.Licensee.ENDPOINT_PATH + "/" + number, null, Licensee.class);
    }

    /**
     * Returns all licensees of a vendor.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return list of licensees (of all products) or null/empty list if nothing found.
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static Page<Licensee> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.Licensee.ENDPOINT_PATH, params, Licensee.class);
    }

    /**
     * Updates licensee properties.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            licensee number
     * @param licensee
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated licensee.
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static Licensee update(final Context context, final String number, final Licensee licensee)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(licensee, "licensee");

        return NetLicensingService.getInstance().post(context, Constants.Licensee.ENDPOINT_PATH + "/" + number, licensee.asRequestForm(),
                Licensee.class);
    }

    /**
     * Deletes licensee.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            licensee number
     * @param forceCascade
     *            if true, any entities that depend on the one being deleted will be deleted too
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static void delete(final Context context, final String number, final boolean forceCascade)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        final Map<String, Object> params = new HashMap<>();
        params.put(Constants.CASCADE, forceCascade);
        NetLicensingService.getInstance().delete(context, Constants.Licensee.ENDPOINT_PATH + "/" + number, params);
    }

    /**
     * Validates active licenses of the licensee.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            licensee number
     * @param productNumber
     *            optional productNumber, must be provided in case licensee auto-create is enabled
     * @param licenseeName
     *            optional human-readable licensee name in case licensee will be auto-created
     * @param validationParameters
     *            optional validation parameters, specific to licensing model. See licensing model documentation for
     *            details.
     * @param meta
     *            optional parameter, receiving messages returned within response <infos> section.
     * @return result of the validation
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    @Deprecated
    public static ValidationResult validate(final Context context, final String number, final String productNumber,
            final String licenseeName, final ValidationParameters validationParameters, final MetaInfo... meta)
                    throws NetLicensingException {
        validationParameters.setProductNumber(productNumber);
        validationParameters.setLicenseeName(licenseeName);
        return validate(context, number, validationParameters, meta);
    }

    /**
     * Validates active licenses of the licensee.
     * In the case of multiple product modules validation,
     * required parameters indexes will be added automatically.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            licensee number
     * @param validationParameters
     *            optional validation parameters. See ValidationParameters and licensing model documentation for
     *            details.
     * @param meta
     *            optional parameter, receiving messages returned within response <infos> section.
     * @return result of the validation
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static ValidationResult validate(final Context context, final String number,
            final ValidationParameters validationParameters, final MetaInfo... meta) throws NetLicensingException {
        return ValidationService.validate(context, number, validationParameters, meta);
    }

    /**
     * Transfer licenses between licensees.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the number of the licensee receiving licenses
     * @param sourceLicenseeNumber
     *            the number of the licensee delivering licenses
     * @throws NetLicensingException
     *             in case of a service error. Check subclass and message for details.
     */
    public static void transfer(final Context context, final String number, final String sourceLicenseeNumber)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotEmpty(sourceLicenseeNumber, Constants.Licensee.SOURCE_LICENSEE_NUMBER);

        final Form form = new Form();
        form.param(Constants.Licensee.SOURCE_LICENSEE_NUMBER, sourceLicenseeNumber);

        NetLicensingService.getInstance().post(context,
                Constants.Licensee.ENDPOINT_PATH + "/" + number + "/" + Constants.Licensee.ENDPOINT_PATH_TRANSFER, form,
                Licensee.class);
    }

} public class PaymentMethodService {

    /**
     * Gets payment method by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the payment method number
     * @return the payment method
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static PaymentMethod get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.PaymentMethod.ENDPOINT_PATH + "/" + number, null, PaymentMethod.class);
    }

    /**
     * Returns payment methods of a vendor.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return collection of payment method entities or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Page<PaymentMethod> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.PaymentMethod.ENDPOINT_PATH, params, PaymentMethod.class);
    }

    /**
     * Updates payment method properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            payment method number
     * @param paymentMethod
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated PaymentMethod.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static PaymentMethod update(final Context context, final String number, final PaymentMethod paymentMethod)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(paymentMethod, "paymentMethod");

        return NetLicensingService.getInstance().post(context, Constants.PaymentMethod.ENDPOINT_PATH + "/" + number,
                paymentMethod.asRequestForm(), PaymentMethod.class);
    }

} public class ProductModuleService {

    /**
     * Creates new product module object with given properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param productNumber
     *            parent product to which the new product module is to be added
     * @param productModule
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created product module object
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static ProductModule create(final Context context, final String productNumber,
            final ProductModule productModule) throws NetLicensingException {
        CheckUtils.paramNotNull(productModule, "productNumber");

        final Form form = productModule.asRequestForm();
        if (StringUtils.isNotBlank(productNumber)) {
            form.param(Constants.Product.PRODUCT_NUMBER, productNumber);
        }
        return NetLicensingService.getInstance().post(context, Constants.ProductModule.ENDPOINT_PATH, form, ProductModule.class);
    }

    /**
     * Gets product module by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the product module number
     * @return the product module
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static ProductModule get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.ProductModule.ENDPOINT_PATH + "/" + number, null, ProductModule.class);
    }

    /**
     * Returns all product modules of a vendor.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return list of product modules (of all products) or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Page<ProductModule> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.ProductModule.ENDPOINT_PATH, params, ProductModule.class);
    }

    /**
     * Updates product module properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            product module number
     * @param productModule
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated product module.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static ProductModule update(final Context context, final String number, final ProductModule productModule)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(productModule, "productModule");

        return NetLicensingService.getInstance().post(context, Constants.ProductModule.ENDPOINT_PATH + "/" + number,
                productModule.asRequestForm(), ProductModule.class);
    }

    /**
     * Deletes product module.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            product module number
     * @param forceCascade
     *            if true, any entities that depend on the one being deleted will be deleted too
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static void delete(final Context context, final String number, final boolean forceCascade)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        final Map<String, Object> params = new HashMap<String, Object>();
        params.put(Constants.CASCADE, forceCascade);
        NetLicensingService.getInstance().delete(context, Constants.ProductModule.ENDPOINT_PATH + "/" + number, params);
    }

} public class ProductService {

    /**
     * Creates new product with given properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param product
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created product object
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Product create(final Context context, final Product product) throws NetLicensingException {
        CheckUtils.paramNotNull(product, "product");

        return NetLicensingService.getInstance().post(context, Constants.Product.ENDPOINT_PATH, product.asRequestForm(), Product.class);
    }

    /**
     * Gets product by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the product number
     * @return the product
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Product get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.Product.ENDPOINT_PATH + "/" + number, null, Product.class);
    }

    /**
     * Returns products of a vendor.
     * 
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return collection of product entities or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Page<Product> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.Product.ENDPOINT_PATH, params, Product.class);
    }

    /**
     * Updates product properties.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            product number
     * @param product
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated product.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static Product update(final Context context, final String number, final Product product)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(product, "product");

        return NetLicensingService.getInstance().post(context, Constants.Product.ENDPOINT_PATH + "/" + number, product.asRequestForm(),
                Product.class);
    }

    /**
     * Deletes product.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            product number
     * @param forceCascade
     *            if true, any entities that depend on the one being deleted will be deleted too
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions will be transformed to the
     *             corresponding service response messages.
     */
    public static void delete(final Context context, final String number, final boolean forceCascade)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        final Map<String, Object> params = new HashMap<String, Object>();
        params.put(Constants.CASCADE, forceCascade);
        NetLicensingService.getInstance().delete(context, Constants.Product.ENDPOINT_PATH + "/" + number, params);
    }

} public class TokenService {

    /**
     * Gets token by its number.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the token number
     * @return the token
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Token get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.Token.ENDPOINT_PATH + "/" + number, null, Token.class);
    }

    /**
     * Returns tokens of a vendor.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            additional criteria to filter type of tokens to return, if NULL return tokens of all types
     * @return collection of token entities or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Page<Token> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.Token.ENDPOINT_PATH, params, Token.class);
    }

    /**
     * Creates new token.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param token
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return created token
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Token create(final Context context, final Token token) throws NetLicensingException {
        CheckUtils.paramNotNull(token, "token");

        return NetLicensingService.getInstance().post(context, Constants.Token.ENDPOINT_PATH, token.asRequestForm(), Token.class);
    }

    /**
     * Delete token by its number.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the token number
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static void delete(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        NetLicensingService.getInstance().delete(context, Constants.Token.ENDPOINT_PATH + "/" + number, null);
    }

} public class TransactionService {

    /**
     * Creates new transaction object with given properties.
     * <p>
     * This routine is for internal use by NetLicensing. Where appropriate, transactions will be created by NetLicensing
     * automatically.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param transaction
     *            non-null properties will be taken for the new object, null properties will either stay null, or will
     *            be set to a default value, depending on property.
     * @return the newly created transaction object
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Transaction create(final Context context, final Transaction transaction) throws NetLicensingException {
        CheckUtils.paramNotNull(transaction, "transaction");

        return NetLicensingService.getInstance().post(context, Constants.Transaction.ENDPOINT_PATH,
                transaction.asRequestForm(),
                Transaction.class);
    }

    /**
     * Gets transaction by its number.
     * <p>
     * Use this operation for getting details about certain transaction. List of all transactions can be obtained by the
     * {@link #list(Context, String)} operation.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            the transaction number
     * @return the transaction
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Transaction get(final Context context, final String number) throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");

        return NetLicensingService.getInstance().get(context, Constants.Transaction.ENDPOINT_PATH + "/" + number, null,
                Transaction.class);
    }

    /**
     * Returns all transactions of a vendor.
     * <p>
     * Use this operation to get the list of all transactions.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return list of transactions (of all products/licensees) or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Page<Transaction> list(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context, Constants.Transaction.ENDPOINT_PATH, params,
                Transaction.class);
    }

    /**
     * Updates transaction properties.
     * <p>
     * This routine is for internal use by NetLicensing. Where appropriate, transactions will be modified by
     * NetLicensing automatically.
     * 
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param number
     *            transaction number
     * @param transaction
     *            non-null properties will be updated to the provided values, null properties will stay unchanged.
     * @return updated transaction.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Transaction update(final Context context, final String number, final Transaction transaction)
            throws NetLicensingException {
        CheckUtils.paramNotEmpty(number, "number");
        CheckUtils.paramNotNull(transaction, "transaction");

        return NetLicensingService.getInstance().post(context, Constants.Transaction.ENDPOINT_PATH + "/" + number,
                transaction.asRequestForm(), Transaction.class);
    }

} public class UtilityService {

    /**
     * Returns all license types.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @return collection of available license types or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions
     *             will be transformed to the corresponding service response messages.
     */
    public static Page<String> listLicenseTypes(final Context context) throws NetLicensingException {
        final Page<LicenseTypeProperties> licenseTypes = NetLicensingService.getInstance().list(context,
                Constants.Utility.ENDPOINT_PATH + "/licenseTypes", null, LicenseTypeProperties.class);
        return new PageImpl<String>(
                (List<String>) CollectionUtils.collect(licenseTypes.getContent(),
                        new Transformer<LicenseTypeProperties, String>() {

                    @Override
                    public String transform(final LicenseTypeProperties licenseType) {
                        return licenseType.getName();
                    }
                }),
                licenseTypes.getPageNumber(),
                licenseTypes.getItemsNumber(),
                licenseTypes.getTotalPages(),
                licenseTypes.getTotalItems(),
                licenseTypes.hasNext());
    }

    /**
     * Returns all licensing models.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @return collection of available license models or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These exceptions
     *             will be transformed to the corresponding service response messages.
     */
    public static Page<String> listLicensingModels(final Context context) throws NetLicensingException {

        final Page<LicensingModelProperties> licensingModels = NetLicensingService.getInstance().list(context,
                Constants.Utility.ENDPOINT_PATH + "/licensingModels", null, LicensingModelProperties.class);
        return new PageImpl<String>(
                (List<String>) CollectionUtils.collect(licensingModels.getContent(),
                        new Transformer<LicensingModelProperties, String>() {

                    @Override
                    public String transform(final LicensingModelProperties licensingModel) {
                        return licensingModel.getName();
                    }
                }),
                licensingModels.getPageNumber(),
                licensingModels.getItemsNumber(),
                licensingModels.getTotalPages(),
                licensingModels.getTotalItems(),
                licensingModels.hasNext());
    }

    /**
     * Returns all countries.
     *
     * @param context
     *            determines the vendor on whose behalf the call is performed
     * @param filter
     *            reserved for the future use, must be omitted / set to NULL
     * @return collection of available countries or null/empty list if nothing found.
     * @throws com.labs64.netlicensing.exception.NetLicensingException
     *             any subclass of {@linkplain com.labs64.netlicensing.exception.NetLicensingException}. These
     *             exceptions will be transformed to the corresponding service response messages.
     */
    public static Page<Country> listCountries(final Context context, final String filter) throws NetLicensingException {
        final Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(filter)) {
            params.put(Constants.FILTER, filter);
        }
        return NetLicensingService.getInstance().list(context,
                Constants.Utility.ENDPOINT_PATH + "/" + Constants.Country.ENDPOINT_PATH, params,
                Country.class);
    }

}
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import com.labs64.netlicensing.domain.entity.Country;
import com.labs64.netlicensing.domain.entity.License;
import com.labs64.netlicensing.domain.entity.LicenseTemplate;
import com.labs64.netlicensing.domain.entity.Licensee;
import com.labs64.netlicensing.domain.entity.PaymentMethod;
import com.labs64.netlicensing.domain.entity.Product;
import com.labs64.netlicensing.domain.entity.ProductModule;
import com.labs64.netlicensing.domain.entity.Token;
import com.labs64.netlicensing.domain.entity.Transaction;
import com.labs64.netlicensing.domain.entity.impl.CountryImpl;
import com.labs64.netlicensing.domain.entity.impl.LicenseImpl;
import com.labs64.netlicensing.domain.entity.impl.LicenseTemplateImpl;
import com.labs64.netlicensing.domain.entity.impl.LicenseeImpl;
import com.labs64.netlicensing.domain.entity.impl.PaymentMethodImpl;
import com.labs64.netlicensing.domain.entity.impl.ProductImpl;
import com.labs64.netlicensing.domain.entity.impl.ProductModuleImpl;
import com.labs64.netlicensing.domain.entity.impl.TokenImpl;
import com.labs64.netlicensing.domain.entity.impl.TransactionImpl;
import com.labs64.netlicensing.domain.vo.Context;
import com.labs64.netlicensing.domain.vo.Page;
import com.labs64.netlicensing.exception.ConversionException;
import com.labs64.netlicensing.exception.NetLicensingException;
import com.labs64.netlicensing.service.LicenseService;
import com.labs64.netlicensing.service.LicenseTemplateService;
import com.labs64.netlicensing.service.LicenseeService;
import com.labs64.netlicensing.service.PaymentMethodService;
import com.labs64.netlicensing.service.ProductModuleService;
import com.labs64.netlicensing.service.ProductService;
import com.labs64.netlicensing.service.TokenService;
import com.labs64.netlicensing.service.TransactionService;
import com.labs64.netlicensing.service.UtilityService;
package com.labs64.netlicensing.util;




public class ServiceHelper {

    // @formatter:off
    private static final Map<Class<?>, Visitable> entityTypeDispatch = Stream.of(
            new AbstractMap.SimpleEntry<>(Product.class,         new ProductImpl()),
            new AbstractMap.SimpleEntry<>(ProductModule.class,   new ProductModuleImpl()),
            new AbstractMap.SimpleEntry<>(LicenseTemplate.class, new LicenseTemplateImpl()),
            new AbstractMap.SimpleEntry<>(Licensee.class,        new LicenseeImpl()),
            new AbstractMap.SimpleEntry<>(License.class,         new LicenseImpl()),
            new AbstractMap.SimpleEntry<>(Transaction.class,     new TransactionImpl()),
            new AbstractMap.SimpleEntry<>(Token.class,           new TokenImpl()),