HashMap intermediateMap = new HashMap();
// Fill intermediate map and prime results map with stroke counts of stand-alone glyphs
Iterator iter = elements.values().iterator();
while (iter.hasNext()) {
ElementEntity element = (ElementEntity)iter.next();
for (int i = 1; i <= element.glyphs.size(); i++) {
ElementEntity.Glyph glyph = element.glyphs.get (new Integer (i));
existsSet.add ("" + element.elementId + "-" + i);
if (glyph.standalone) {
resultsMap.put ("" + element.elementId + "-" + i, new Integer (glyph.strokes.size()));
} else {
ArrayList containsList = new ArrayList();
for (int j = 0; j < 4; j++) {
if (element.pElementId[j] != 0) {
containsList.add ("" + element.pElementId[j] + "-" + glyph.pGlyphVariant[j]);
}
}
intermediateMap.put ("" + element.elementId + "-" + i, containsList);
}
}
}
// Iterate over intermediate map until all results known
// In theory this is nasty, in practice it only needs about 3 iterations
do {
Iterator iter2 = ((HashMap)intermediateMap.clone()).keySet().iterator();
while (iter2.hasNext()) {
String elementGlyph = (String)iter2.next();
ArrayList elementGlyphSubElements = (ArrayList)intermediateMap.get (elementGlyph);
boolean complete = true;
int count = 0;
Iterator iter3 = elementGlyphSubElements.iterator();
while (iter3.hasNext()) {
String containedElementGlyph = (String)iter3.next();
Integer containedCount = (Integer)resultsMap.get (containedElementGlyph);
if (containedCount != null) {
count += containedCount.intValue();
} else {
// Fallback in case of dangling references
if (existsSet.contains (containedElementGlyph)) {
complete = false;
} else {
System.err.println ("recalculateAllElementStrokeCounts(): Dangling reference to " + containedElementGlyph + " in " + elementGlyph);
}
}
}
if (complete) {
resultsMap.put (elementGlyph, new Integer (count));
intermediateMap.remove (elementGlyph);
}
}
} while (intermediateMap.size() > 0);
// Update all stroke counts
Iterator iter4 = resultsMap.keySet().iterator();
while (iter4.hasNext()) {
String elementGlyph = (String)iter4.next();
int strokeCount = ((Integer)resultsMap.get (elementGlyph)).intValue();
String[] parts = elementGlyph.split ("-");
Integer elementId = new Integer (parts[0]);
Integer glyphVariant = new Integer (parts[1]);
ElementEntity element = (ElementEntity)elements.get (elementId);
ElementEntity.Glyph glyph = element.glyphs.get (glyphVariant);
glyph.strokeCount = strokeCount;
element.glyphs.set (glyphVariant, glyph);
}