class ProductSearchResultDTOImpl implements ProductSearchResultDTO {

    @Override
    public ProductSearchResultDTOImpl copy() {
        /*
            DO NOT copy skus as this must be set through FT search - we need them to be
            sorted by relevancy
         */
        final ProductSearchResultDTOImpl copy = new ProductSearchResultDTOImpl();
        copy.setId(this.id);
        copy.setCode(this.code);
        copy.setManufacturerCode(this.manufacturerCode);
        copy.setFulfilmentCentreCode(this.fulfilmentCentreCode);
        copy.setDefaultSkuCode(this.defaultSkuCode);
        copy.setName(this.name);
        if (this.displayName != null) {
            copy.setDisplayName(this.displayName.copy());
        }
        copy.setDescription(this.description);
        if (this.displayDescription != null) {
            copy.setDisplayDescription(this.displayDescription.copy());
        }
        copy.setTypeId(this.typeId);
        copy.setType(this.type);
        if (this.displayType != null) {
            copy.setDisplayType(this.displayType.copy());
        }
        copy.setTypeMask(this.typeMask);
        copy.setTag(this.tag);
        copy.setBrand(this.brand);
        copy.setDefaultImage(this.defaultImage);
        copy.setCreatedTimestamp(this.createdTimestamp);
        copy.setUpdatedTimestamp(this.updatedTimestamp);
        final Map<Long, ProductSkuSearchResultDTO> copyBaseSku = new HashMap<>();
        if (this.baseSkus != null) {
            for (final Map.Entry<Long, ProductSkuSearchResultDTO> skuDTO : this.baseSkus.entrySet()) {
                copyBaseSku.put(skuDTO.getKey(), skuDTO.getValue().copy());
            }
        }
        copy.setBaseSkus(copyBaseSku);
        if (this.attributes != null) {
            copy.setAttributes(new StoredAttributesDTOImpl(this.attributes.toString()));
        }
        return copy;
    }

}