Consider two lists A and B, of equal size 3. A1 corresponds to B1, A2 to B2, etc, for instance A are image scans from 2007 and B from 2008, and the index indicates the patient number. There's then two lists of possible parameters P and Q, of different lengths, P has 2 and Q has 4 items. Each of the A items should be processed in "ap" using each of the P parameters, and each of the B items processed in "bq" using each of the Q parameters. The problem then is how to compare AnPp against the all BnQq - but notice that An and Bn have to match. The normal crossproduct would compare all AaPp against all BbQq - but we want to restrict the iteration strategy. We can't use the dot product directly because for a given patient n we want to compare all Ps against all Qs using the cross product. This is solved in t2 using staged iteration, but here is a hack showing how this can be achieved in t1 using a nested workflow. The nested workflow basically "stops" the iteration at list level, due to the echo_lists inside that makes the nested workflow excpect lists. There's explicit crossproduct(p,a) strategy set on ap and crossproduct(q,b) on bq to make sure they output with a/b iteration at the top-level lists, ie. "ap" outputs: [ [ a0p0, a0p1], [ a1p0, a1p1], [ a2p0, a2p1] ] So the top level lists from "ap" corresponds to each item of A. The same trick applies to "bq" - if we don't do this the implicit iteration might output the opposite with the highest list corresponding to the Ps and Qs. The second part is to use a nested workflow that takes the outputs from ap and bq, but through the "Echo list" local worker. This worker doesn't do anything except it forces the nested workflow to take a list of items as inputs instead of single inputs. Hence we can set a dotproduct(pq, ap) on the processor for the nested workflow "apbq_iter" - since the nested workflow consumes lists at both ports this means it will be iterated over with these inputs: ap = [ a0p0, a0p1] bq = [b0q0, b0q1, b0q2, b0q3] ap = [ a1p0, a1p1] bq = [b1q0, b1q1, b1q2, b1q3] ap = [ a2p0, a2p1] bq = [b2q0, b2q1, b2q2, b2q3] Inside the nested workflow there's the normal crossproduct(pq, ap) so that it could (in theory) do an all-to-all comparison. (The beanshell inside apbq here only returns the string ap+bq.) With this hack we can run a dotproduct for the outermost list, and a crossproduct for the innermost list. The output of running this should be: { [ (a0p0b0q0, a0p0b0q1, a0p0b0q2, a0p0b0q3), (a0p1b0q0, a0p1b0q1, a0p1b0q2, a0p1b0q3) ], [ (a1p0b1q0, a1p0b1q1, a1p0b1q2, a1p0b1q3), (a1p1b1q0, a1p1b1q1, a1p1b1q2, a1p1b1q3) ], [ (a2p0b2q0, a2p0b2q1, a2p0b2q2, a2p0b2q3), (a2p1b2q0, a2p1b2q1, a2p1b2q2, a2p1b2q3) ] } So in the final output {} (depth=3) there's three big [] lists of depth 2, responding to a0/b0, a1/b1 and b2/b2. Within each of these are two () lists of depth 1 corresponding two p0 and p1. The content of these lists (depth 0) are the actual items returned from "apbq" - one for each of q0,q1,q2,q3. List P = new ArrayList(); P.add("p0"); P.add("p1"); P List A = new ArrayList(); A.add("a0"); A.add("a1"); A.add("a2"); A List Q = new ArrayList(); Q.add("q0"); Q.add("q1"); Q.add("q2"); Q.add("q3"); Q List B = new ArrayList(); B.add("b0"); B.add("b1"); B.add("b2"); B bq = b+q; b q bq ap = a+p; a p ap org.embl.ebi.escience.scuflworkers.java.EchoList org.embl.ebi.escience.scuflworkers.java.EchoList apbq = ap + bq; ap bq apbq org.embl.ebi.escience.scuflworkers.java.FlattenList org.embl.ebi.escience.scuflworkers.java.StringListMerge