System.out.println("** Creating trace with first filter = " + filterContent);
    public Trace[] partition() {        LinkedList queue = new LinkedList();        HashSet visited = new HashSet();        LinkedList traces = new LinkedList();        LinkedList topTracesList = new LinkedList(); // traces with no        // incoming dependencies        HashSet topUnflat = new HashSet();        // map unflatEdges -> Edge?        HashMap edges = new HashMap();        // add the top filters to the queue        for (int i = 0; i < topFilters.length; i++) {            topUnflat.add(topFilters[i]);            queue.add(topFilters[i]);        }        while (!queue.isEmpty()) {            UnflatFilter unflatFilter = (UnflatFilter) queue.removeFirst();            if (!visited.contains(unflatFilter)) {                visited.add(unflatFilter);                // the filter content for the new filter                FilterContent filterContent = getFilterContent(unflatFilter);                // remember the work estimation based on the filter content                int workEstimate = getWorkEstimate(unflatFilter);                workEstimation.put(filterContent, new Integer(workEstimate));                TraceNode node;                Trace trace;                int filtersInTrace = 1;                System.out.println("** Creating trace with first filter = "                                   + filterContent);                // create the input trace node                if (unflatFilter.in != null && unflatFilter.in.length > 0) {                    Edge[] inEdges = new Edge[unflatFilter.in.length];                    node = new InputTraceNode(unflatFilter.inWeights, inEdges);                    for (int i = 0; i < unflatFilter.in.length; i++) {                        UnflatEdge unflatEdge = unflatFilter.in[i];                        // get the edge                        Edge edge = (Edge) edges.get(unflatEdge);                        // we haven't see the edge before                        if (edge == null) { // set dest?, wouldn't this always                                            // be the dest                            edge = new Edge((InputTraceNode) node);                            edges.put(unflatEdge, edge);                        } else                            // we've seen this edge before, set the dest to this                            // node                            edge.setDest((InputTraceNode) node);                        inEdges[i] = edge;                    }                    trace = new Trace((InputTraceNode) node);                    if (filterContent.isLinear()) { // Jasper's linear stuff??                        System.out                            .println("******** Found linear fitler, array is of length "                                     + filterContent.getArray().length                                     + " pop is "                                     + filterContent.getPopCount());                        // The number of "times" to fiss this linear filter...                        int times = filterContent.getArray().length                            / filterContent.getPopCount();                        if (times > 1) {                            assert rawChip.getTotalTiles() == 16 : "Only 4x4 layouts supported right now";                            // for now force to execute on 16 tiles                            if (times > rawChip.getTotalTiles())                                times = rawChip.getTotalTiles();                            // fiss the filter into times elements                            FilterContent[] fissedFilters = LinearFission.fiss(                                                                               filterContent, times);                            // remove the original linear filter from the work                            // estimation                            workEstimation.remove(filterContent);                            // now add the fissed filters to the trace                            for (int i = 0; i < fissedFilters.length; i++) {                                FilterContent fissedContent = fissedFilters[i];                                FilterTraceNode filterNode = new FilterTraceNode(                                                                                 fissedContent);                                node.setNext(filterNode);                                filterNode.setPrevious(node);                                node = filterNode;                                // Dummy work estimate for now                                workEstimation.put(fissedContent, new Integer(                                                                              workEstimate / times));                            }                        } else {                            FilterTraceNode filterNode = new FilterTraceNode(                                                                             filterContent);                            node.setNext(filterNode);                            filterNode.setPrevious(node);                            node = filterNode;                        }                    } else {                        FilterTraceNode filterNode = new FilterTraceNode(                                                                         filterContent);                        node.setNext(filterNode);                        filterNode.setPrevious(node);                        node = filterNode;                    }                } else { // null incoming arcs                    node = new FilterTraceNode(filterContent);                    trace = new Trace(node);                }                if (topUnflat.contains(unflatFilter)) {                    assert unflatFilter.in == null                        || unflatFilter.in.length == 0;                    topTracesList.add(trace);                } else                    assert unflatFilter.in.length > 0;                // should be at least one filter in the trace by now, don't                // worry about                // linear stuff right now...                traces.add(trace);                int bottleNeckWork = getWorkEstimate(unflatFilter);                // try to add more filters to the trace...                while (continueTrace(unflatFilter, filterContent.isLinear(),                                     bottleNeckWork, ++filtersInTrace)) { // tell continue                    // trace you are                    // trying to put                    // another filter in the trace                    UnflatFilter downstream = unflatFilter.out[0][0].dest;                    FilterContent dsContent = getFilterContent(downstream);                    // remember the work estimation based on the filter content                    workEstimation.put(dsContent, new Integer(                                                              getWorkEstimate(downstream)));                    if (getWorkEstimate(downstream) > bottleNeckWork)                        bottleNeckWork = getWorkEstimate(downstream);                    // if we get here we are contecting another linear filters                    // to a                    // previous linear filter                    if (dsContent.isLinear()) {                        assert false : "Trying to add a 2 different linear filters to a trace (Not supported Yet)";                        // the code for this case is broken                        // the number of times to fiss the linear filter                        int times = dsContent.getArray().length                            / dsContent.getPopCount();                        if (times > 1) {                            if (times > 16)                                times = 16;                            FilterContent[] fissedFilters = LinearFission.fiss(                                                                               dsContent, times);                            workEstimation.remove(dsContent);                            // create filter nodes for each row of the matrix?                            for (int i = 0; i < fissedFilters.length; i++) {                                FilterContent fissedContent = fissedFilters[i];                                FilterTraceNode filterNode = new FilterTraceNode(                                                                                 fissedContent);                                node.setNext(filterNode);                                filterNode.setPrevious(node);                                node = filterNode;                                unflatFilter = downstream;                                // Dummy work estimate for now                                workEstimation.put(fissedContent, new Integer(                                                                              workEstimate / times));                            }                        } else if (!(downstream.filter instanceof SIRPredefinedFilter)) {                            FilterTraceNode filterNode = new FilterTraceNode(                                                                             dsContent);                            node.setNext(filterNode);                            filterNode.setPrevious(node);                            node = filterNode;                            unflatFilter = downstream;                        }                    } else if (!(downstream.filter instanceof SIRPredefinedFilter)) {                        FilterTraceNode filterNode = new FilterTraceNode(                                                                         dsContent);                        node.setNext(filterNode);                        filterNode.setPrevious(node);                        node = filterNode;                        unflatFilter = downstream;                    }                }                traceBNWork.put(trace, new Integer(bottleNeckWork));                // we are finished the current trace, create the outputtracenode                if (unflatFilter.out != null && unflatFilter.out.length > 0) {                    Edge[][] outEdges = new Edge[unflatFilter.out.length][];                    OutputTraceNode outNode = new OutputTraceNode(                                                                  unflatFilter.outWeights, outEdges);                    node.setNext(outNode);                    outNode.setPrevious(node);                    for (int i = 0; i < unflatFilter.out.length; i++) {                        UnflatEdge[] inner = unflatFilter.out[i];                        Edge[] innerEdges = new Edge[inner.length];                        outEdges[i] = innerEdges;                        for (int j = 0; j < inner.length; j++) {                            UnflatEdge unflatEdge = inner[j];                            UnflatFilter dest = unflatEdge.dest;                            // if we didn't visit one of the dests, add it                            if (!visited.contains(dest))                                queue.add(dest);                            Edge edge = (Edge) edges.get(unflatEdge);                            if (edge == null) {                                edge = new Edge(outNode);                                edges.put(unflatEdge, edge);                            } else                                edge.setSrc(outNode);                            innerEdges[j] = edge;                        }                    }                }                trace.finish();            }        }        traceGraph = new Trace[traces.size()];        traces.toArray(traceGraph);        topTracesList.toArray(topTraces);        setupIO();        return traceGraph;    }