Converting between backend object and object suitable for JSON I wrote this method that does the job and passes the assertion tests for a large java backend project but I'm not all happy with the way it reads, perhaps you can tell me how to refactor and/or improve this method?

public Set&lt;ProductOfferingJsonDto&gt; getJsonProductOfferings() {
    Set&lt;ProductOfferingJsonDto&gt; set = new HashSet&lt;ProductOfferingJsonDto&gt;();
    ProductOfferingJsonDto pjson = null;
    Iterator iter = productOfferings.iterator();
    while(iter.hasNext()){
        ProductOfferingDto pdto = (ProductOfferingDto) iter.next();
        if(pdto instanceof BundledProductOfferingDto) {
            Set&lt;ProductOfferingDto&gt; tmp = ((BundledProductOfferingDto) pdto).getProductOfferings();
            Iterator piter = tmp.iterator();
            Set&lt;ProductOfferingJsonDto&gt; tmpset = new HashSet&lt;ProductOfferingJsonDto&gt;();
            while(piter.hasNext()){
                SimpleProductOfferingDto piterdto = (SimpleProductOfferingDto) piter.next();
                tmpset.add(new SimpleProductOfferingJsonDto(piterdto.getId(), piterdto.getName(), piterdto.getDescription(), piterdto.getStatus(),
                        piterdto.getBrand(), piterdto.getValidFor(),
                        piterdto.getProductSpecification(),
                        piterdto.getDescriptorId(), piterdto.getTags(), piterdto.getProductOfferingPrice()));
   }
            BundledProductOfferingDto bpod = (BundledProductOfferingDto) pdto;
            pjson = new BundledProductOfferingJsonDto(bpod.getId(), bpod.getName(), bpod.getDescription(), bpod.getStatus(),
                    bpod.getBrand(), bpod.getValidFor(),
                    tmpset,
                    bpod.getDescriptorId(), bpod.getTags(), bpod.getProductOfferingPrice());
        }
      if(pjson != null) {
        set.add((ProductOfferingJsonDto) pjson);
      }
    }
    return set;
}
I would move the construction of the JSON objects into factory methods like this:

public class BundledProductOfferingJsonDto
{
    ....
    public static BundledProductOfferingJsonDto fromDto(BundledProductOfferingDto dto, Set&lt;ProductOfferingJsonDto&gt; productOfferings)
    {
        return new BundledProductOfferingJsonDto(dto.getId(), dto.getName(), dto.getDescription(), dto.getStatus(),
                dto.getBrand(), dto.getValidFor(),
                productOfferings,
                dto.getDescriptorId(), dto.getTags(), dto.getProductOfferingPrice());
    }
}


Similar for SimpleProductOfferingJsonDto

Also, is there a reason why your are using the while loops with the iterators instead of for example for (ProductOfferingDto piter : tmp)?

The method could then read something like this:

public Set&lt;ProductOfferingJsonDto&gt; getJsonProductOfferings() {
    Set&lt;ProductOfferingJsonDto&gt; set = new HashSet&lt;ProductOfferingJsonDto&gt;();
    ProductOfferingJsonDto pjson = null;
    for (ProductOfferingDto pdto : productOfferings) {
        if (pdto instanceof BundledProductOfferingDto) {
            Set&lt;ProductOfferingDto&gt; tmp = ((BundledProductOfferingDto) pdto).getProductOfferings();
            Set&lt;ProductOfferingJsonDto&gt; tmpset = new HashSet&lt;ProductOfferingJsonDto&gt;();
            for (ProductOfferingDto piter : tmp) {
                SimpleProductOfferingDto piterdto = (SimpleProductOfferingDto)piter;
                tmpset.add(SimpleProductOfferingJsonDto.fromDto(piterdto));
            }
            BundledProductOfferingDto bpod = (BundledProductOfferingDto) pdto;
            BundledProductOfferingJsonDto pjson = BundledProductOfferingJsonDto.fromDto(bpod, tmpset));
            set.add(pjson);
        }
    }
    return set;
}