+ @SuppressWarnings("synthetic-access")
+ public Iterator<Part> iterator() {
+ return new Iterator<Part>() {
+
+ private Deque<Iterator<Part>> partStack = new ArrayDeque<Iterator<Part>>();
+ private Part nextPart;
+ private boolean foundNextPart;
+ private boolean noNextPart;
+
+ {
+ partStack.push(parts.iterator());
+ }
+
+ private void findNext() {
+ if (foundNextPart) {
+ return;
+ }
+ noNextPart = true;
+ while (!partStack.isEmpty()) {
+ Iterator<Part> parts = partStack.pop();
+ if (parts.hasNext()) {
+ nextPart = parts.next();
+ partStack.push(parts);
+ if (nextPart instanceof PartContainer) {
+ partStack.push(((PartContainer) nextPart).iterator());
+ } else {
+ noNextPart = false;
+ break;
+ }
+ }
+ }
+ foundNextPart = true;
+ }
+
+ @Override
+ public boolean hasNext() {
+ findNext();
+ return !noNextPart;
+ }
+
+ @Override
+ public Part next() {
+ findNext();
+ if (noNextPart) {
+ throw new NoSuchElementException();
+ }
+ foundNextPart = false;
+ return nextPart;
+ }
+
+ @Override
+ public void remove() {
+ /* ignore. */
+ }
+
+ };