]> source.dussan.org Git - aspectj.git/commitdiff
polish
authorAndy Clement <aclement@pivotal.io>
Fri, 29 Nov 2019 19:36:58 +0000 (11:36 -0800)
committerAndy Clement <aclement@pivotal.io>
Fri, 29 Nov 2019 19:36:58 +0000 (11:36 -0800)
ajde/src/main/java/org/aspectj/ajde/ui/internal/TreeStructureViewBuilder.java
ajde/src/main/java/org/aspectj/ajde/ui/internal/UserPreferencesStore.java
ajde/src/main/java/org/aspectj/ajde/ui/javaoptions/JavaComplianceOptionsPanel.java
ajde/src/main/java/org/aspectj/ajde/ui/javaoptions/JavaDebugOptionsPanel.java
testing-drivers/src/test/java/org/aspectj/testing/drivers/AjctestsAdapter.java
testing-drivers/src/test/java/org/aspectj/testing/drivers/Harness.java
testing/src/test/java/org/aspectj/testing/harness/bridge/AbstractRunSpec.java
testing/src/test/java/org/aspectj/testing/harness/bridge/AjcSpecTest.java
testing/src/test/java/org/aspectj/testing/harness/bridge/JavaRun.java
testing/src/test/java/org/aspectj/testing/harness/bridge/Validator.java

index 9021cbfe7268c10fcd99181e55d0a180b4f82fc1..728ed9069faa677af6300b0ed89a49795117b4e6 100644 (file)
@@ -1,14 +1,14 @@
 /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
+ * Copyright (c) 1999-2001 Xerox Corporation,
  *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xerox/PARC     initial implementation
  * ******************************************************************/
 
 
@@ -46,132 +46,132 @@ public class TreeStructureViewBuilder {
         * @todo        get rid of instanceof tests
         */
        public void buildView(StructureView view, IHierarchy model) {
-//             StructureViewProperties properties = view.getViewProperties();
+               //              StructureViewProperties properties = view.getViewProperties();
                IProgramElement modelRoot = null;
-//             boolean noStructure = false;
+               //              boolean noStructure = false;
                if (isFileView(view)) {
                        FileStructureView fileView = (FileStructureView)view;
-                       if (fileView.getSourceFile() == null) { 
+                       if (fileView.getSourceFile() == null) {
                                modelRoot = IHierarchy.NO_STRUCTURE;
-//                             noStructure = true;
+                               //                              noStructure = true;
                        } else {
                                modelRoot = model.findElementForSourceFile(fileView.getSourceFile());
                        }
                } else {
                        modelRoot = model.getRoot();
                }
-               
+
                IStructureViewNode viewRoot = null;
                if (!isFileView(view)) {
-                       StructureViewProperties.Hierarchy hierarchy 
-                               = ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy();
-                       if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING) 
-                               || hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
-                               viewRoot = buildCustomTree((GlobalStructureView)view, model);           
-                       }               
-               } 
+                       StructureViewProperties.Hierarchy hierarchy
+                       = ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy();
+                       if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)
+                                       || hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
+                               viewRoot = buildCustomTree((GlobalStructureView)view, model);
+                       }
+               }
                if (viewRoot == null) {
                        viewRoot = createViewNode(modelRoot, view.getViewProperties());//modelRoot;
-               }  
-               
+               }
+
                if (view.getViewProperties().getSorting() == StructureViewProperties.Sorting.ALPHABETICAL
-                       || (!isFileView(view) && 
-                        ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.DECLARATION))) {
+                               || (!isFileView(view) &&
+                                               ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.DECLARATION))) {
                        sortView(viewRoot, ALPHABETICAL_COMPARATOR);
                } else {
                        sortView(viewRoot, DECLARATIONAL_COMPARATOR);
-               }  
-               
+               }
+
                addPackageNode(view, viewRoot);
                view.setRootNode(viewRoot);
        }
 
        private void addPackageNode(StructureView view, IStructureViewNode viewRoot) {
                if (isFileView(view)) {
-//                     IProgramElement fileNode = viewRoot.getStructureNode();
-//                     IProgramElement parentNode = fileNode.getParent();
-//                     
-//                     if (parentNode.getKind() == IProgramElement.Kind.PACKAGE) {
-//                             String name = parentNode.getName();
-//                             IProgramElement packageNode = new ProgramElement(name, IProgramElement.Kind.PACKAGE, null);
-//                             packageNode.setSourceLocation(fileNode.getSourceLocation());
-//                             StructureViewNode packageViewNode = createViewNode(
-//                                     packageNode, 
-//                                     view.getViewProperties()
-//                             );
-//                             viewRoot.getChildren().add(0, packageViewNode);
-//                     };
+                       //                      IProgramElement fileNode = viewRoot.getStructureNode();
+                       //                      IProgramElement parentNode = fileNode.getParent();
+                       //
+                       //                      if (parentNode.getKind() == IProgramElement.Kind.PACKAGE) {
+                       //                              String name = parentNode.getName();
+                       //                              IProgramElement packageNode = new ProgramElement(name, IProgramElement.Kind.PACKAGE, null);
+                       //                              packageNode.setSourceLocation(fileNode.getSourceLocation());
+                       //                              StructureViewNode packageViewNode = createViewNode(
+                       //                                      packageNode,
+                       //                                      view.getViewProperties()
+                       //                              );
+                       //                              viewRoot.getChildren().add(0, packageViewNode);
+                       //                      };
                }
        }
-       
+
        private IStructureViewNode createViewNode(IProgramElement node, StructureViewProperties properties) {
                if (node == null) return null;
                List children = new ArrayList();
-//             IProgramElement pNode = node;
-//             if (node.getRelations() != null) {
-//                     for (Iterator it = node.getRelations().iterator(); it.hasNext(); ) {
-//                             IProgramElement IProgramElement = (IProgramElement)it.next();
-//                             if (acceptNode(IProgramElement, properties)) {
-//                                     children.add(createViewNode(IProgramElement, properties));
-//                             }
-//                     }       
-//             }
+               //              IProgramElement pNode = node;
+               //              if (node.getRelations() != null) {
+               //                      for (Iterator it = node.getRelations().iterator(); it.hasNext(); ) {
+               //                              IProgramElement IProgramElement = (IProgramElement)it.next();
+               //                              if (acceptNode(IProgramElement, properties)) {
+               //                                      children.add(createViewNode(IProgramElement, properties));
+               //                              }
+               //                      }
+               //              }
                if (node.isRunnable() && node.getParent() != null) {
                        IProgramElement parent = node.getParent();
                        if (parent.getKind().equals(IProgramElement.Kind.CLASS)
-                               || parent.getKind().equals(IProgramElement.Kind.ASPECT)) {
-                               parent.setRunnable(true);       
+                                       || parent.getKind().equals(IProgramElement.Kind.ASPECT)) {
+                               parent.setRunnable(true);
                                node.setRunnable(false);
                        }
                }
                if (node.getChildren() != null) {
-                       for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
-                               IProgramElement IProgramElement = (IProgramElement)it.next();
+                       for (Object element : node.getChildren()) {
+                               IProgramElement IProgramElement = (IProgramElement)element;
                                if (acceptNode(IProgramElement, properties)) {
                                        children.add(createViewNode(IProgramElement, properties));
                                }
-                       }       
+                       }
                }
 
                IStructureViewNode viewNode = nodeFactory.createNode(node, children);//new TreeViewNode(root, null, children);
-               return viewNode;        
+               return viewNode;
        }
-       
+
        /**
         * @todo        get rid of this test, fix polymorphism
         */
        private boolean isFileView(StructureView view) {
                return view instanceof FileStructureView
-                       && !(view instanceof GlobalStructureView);
+                               && !(view instanceof GlobalStructureView);
        }
-       
+
        private boolean acceptGranularity(IProgramElement.Kind kind, StructureViewProperties.Granularity granularity) {
-               
+
                if (granularity == StructureViewProperties.Granularity.DECLARED_ELEMENTS) {
                        return true;
-               } else if (granularity == StructureViewProperties.Granularity.MEMBER && 
-                       (kind != IProgramElement.Kind.CODE)) {
+               } else if (granularity == StructureViewProperties.Granularity.MEMBER &&
+                               (kind != IProgramElement.Kind.CODE)) {
                        return true;
                } else if (granularity == StructureViewProperties.Granularity.TYPE
-                       && (kind == IProgramElement.Kind.PROJECT
+                               && (kind == IProgramElement.Kind.PROJECT
                                || kind == IProgramElement.Kind.PACKAGE
                                || kind.isSourceFile()
                                || kind.isType())) {
-                       return true;                    
+                       return true;
                } else if (granularity == StructureViewProperties.Granularity.FILE
-                       && (kind == IProgramElement.Kind.PROJECT
+                               && (kind == IProgramElement.Kind.PROJECT
                                || kind == IProgramElement.Kind.PACKAGE
                                || kind.isSourceFile())) {
-                       return true;                    
+                       return true;
                } else if (granularity == StructureViewProperties.Granularity.PACKAGE
-                       && (kind == IProgramElement.Kind.PROJECT
+                               && (kind == IProgramElement.Kind.PROJECT
                                || kind == IProgramElement.Kind.PACKAGE)) {
-                       return true;                    
+                       return true;
                } else {
                        return false;
                }
        }
-       
+
        private boolean acceptNode(IProgramElement node, StructureViewProperties properties) {
                if (node!=null) {
                        IProgramElement pNode = node;
@@ -179,250 +179,249 @@ public class TreeStructureViewBuilder {
                                return false;
                        } else if (pNode.getKind().isMember()) {
                                if (properties.getFilteredMemberAccessibility().contains(pNode.getAccessibility())) {
-                                       return false;   
+                                       return false;
                                }
                                if (properties.getFilteredMemberKinds().contains(pNode.getKind())) {
-                                       return false;   
+                                       return false;
                                }
-                               for (Iterator it = pNode.getModifiers().iterator(); it.hasNext(); ) {
-                                       if (properties.getFilteredMemberModifiers().contains(it.next())) {
-                                               return false;   
-                                       }       
+                               for (Object element : pNode.getModifiers()) {
+                                       if (properties.getFilteredMemberModifiers().contains(element)) {
+                                               return false;
+                                       }
                                }
                        }
                }
                return true;
        }
 
-       private void sortView(IStructureViewNode node, Comparator comparator) {
+       private void sortView(IStructureViewNode node, Comparator<IStructureViewNode> comparator) {
                if (node == null || node.getChildren() == null) return;
                Collections.sort(node.getChildren(), comparator);
                for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
                        IStructureViewNode nextNode = (IStructureViewNode)it.next();
-                       if (nextNode != null) sortView(nextNode, comparator);   
+                       if (nextNode != null) sortView(nextNode, comparator);
                }
        }
 
-    private IStructureViewNode buildCustomTree(GlobalStructureView view, IHierarchy model) {
-        IProgramElement rootNode = model.getRoot();
-        IStructureViewNode treeNode = nodeFactory.createNode(rootNode);
-
-        List rootNodes = new ArrayList();
-        getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy());
-               
-        for (Iterator it = rootNodes.iterator(); it.hasNext(); ) {
-            if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
-                treeNode.add(getCrosscuttingChildren((IProgramElement)it.next()));
-            } else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
-                treeNode.add(getInheritanceChildren(
-                       (IProgramElement)it.next(),
-                       view.getViewProperties().getRelations())        
-                );
-            }
-        }
-        return treeNode;
-    }
-
-    private void getRoots(IProgramElement rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) {
-//        if (rootNode != null && rootNode.getChildren() != null) {
-//            for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) {
-//                IProgramElement node = (IProgramElement)it.next();
-//                if (node instanceof IProgramElement) {
-//                    if (acceptNodeAsRoot((IProgramElement)node, hierarchy)) {
-//                        IProgramElement pNode = (IProgramElement)node;
-//                        List relations = pNode.getRelations();
-//                        String delimiter = "";
-//                        if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
-//                            delimiter = "uses pointcut";
-//                        } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
-//                            delimiter = "inherits";
-//                        } 
-//                        if (relations != null && relations.toString().indexOf(delimiter) == -1) {
-//                            boolean found = false;
-//                            for (Iterator it2 = roots.iterator(); it2.hasNext(); ) {
-//                                if (((IProgramElement)it2.next()).equals(pNode)) found = true;
-//                            }
-//                            if (!found) roots.add(pNode);
-//                        } 
-//                    } 
-//                }
-//                getRoots(node, roots, hierarchy);
-//            }
-//        }
-    }
-
-    public boolean acceptNodeAsRoot(IProgramElement node, StructureViewProperties.Hierarchy hierarchy) {
-        if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
-            return node.getKind().equals(IProgramElement.Kind.ADVICE)
-                || node.getKind().equals(IProgramElement.Kind.POINTCUT);
-        } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
-            return node.getKind().equals(IProgramElement.Kind.CLASS);
-        } else {       
-            return false;
-        }
-    }
-
-    private IStructureViewNode getInheritanceChildren(IProgramElement node, List associations) {
-//     IStructureViewNode treeNode = nodeFactory.createNode(node);
-//        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
-//        List relations = ((IProgramElement)node).getRelations();
-        throw new RuntimeException("unimplemented");
-//        if (relations != null) {
-//            for (Iterator it = relations.iterator(); it.hasNext(); ) {
-//                             IRelationship relation = (IRelationship)it.next();
-//                if (relation.getName().equals("is inherited by")) {
-//                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
-////                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
-////                        StructureViewNode newNode = getInheritanceChildren(pNode, associations);
-//                        StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations);
-//                        for (int i = 0; i < typeChildren.getChildren().size(); i++) {
-//                            newNode.add((StructureViewNode)typeChildren.getChildren().get(i));
-//                        }
-//                                             treeNode.add(newNode);
-//                    }
-//                }
-//            }
-//        }
-//        return treeNode;
-    }
-
-    private IStructureViewNode getCrosscuttingChildren(IProgramElement node) {
-        //StructureViewNodeAdapter treeNode = new StructureViewNodeAdapter(node);
-//        IStructureViewNode treeNode = nodeFactory.createNode(node);
-//        List relations = ((IProgramElement)node).getRelations();
-        throw new RuntimeException("unimplemented");
-//        if (relations != null) {
-//            for (Iterator it = relations.iterator(); it.hasNext(); ) {
-//                             IRelationship relation = (IRelationship)it.next();
-//                if (relation.getName().equals("pointcut used by")) {
-//                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
-//                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
-//                        StructureViewNode newNode = getCrosscuttingChildren(pNode);
-//                        for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) {
-//                                                     IRelationship relationNode = (IRelation)it3.next();
-//                            if (relationNode.getName().indexOf("pointcut") == -1) {
-//                                newNode.add(getRelations(relationNode));
-//                            }
-//                        }
-//                        treeNode.add(newNode);
-//                    }
-//                } else if (relations.toString().indexOf("uses pointcut") == -1) {
-//                    for (Iterator it4 = relations.iterator(); it4.hasNext(); ) {
-//                        IRelation relationNode = (IRelationship)it4.next();
-//                        if (relationNode.getName().indexOf("pointcut") == -1) {
-//                            treeNode.add(getRelations(relationNode));
-//                        }
-//                    }
-//                }
-//            }
-//        }
-//        return treeNode;
-    }
-
-//    private IStructureViewNode buildTree(IProgramElement node, List associations) {
-//        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
-//        IStructureViewNode treeNode = nodeFactory.createNode(node);
-////        if (node instanceof IProgramElement) {
-//            List relations = ((IProgramElement)node).getRelations();
-//            if (relations != null) {
-//                for (Iterator it = relations.iterator(); it.hasNext(); ) {
-//                                     IRelationship relationNode = (IRelationship)it.next();
-//                    if (associations.contains(relationNode.toString())) {
-//                        treeNode.add(buildTree(relationNode, associations));
-//                    }
-//                }
-//            }
-//        }
-//        if (node != null) {
-//            List children = null;
-//            children = node.getChildren();
-//            if (children != null) {
-//                List childList = new ArrayList();
-//                for (Iterator itt = children.iterator(); itt.hasNext(); ) {
-//                    IProgramElement child = (IProgramElement)itt.next();
-//                    if (child instanceof IProgramElement) {
-//                        IProgramElement progNode = (IProgramElement)child;
-////                        if (progNode.getKind() != IProgramElement.Kind.CODE) {
-//                            childList.add(buildTree(child, associations));
-////                        }
-//                    } else {
-//                        childList.add(buildTree(child, associations));
-//                    }
-//                }
-//                //sortNodes(childList);
-//                for (Iterator it = childList.iterator(); it.hasNext(); ) {
-//                    treeNode.add((IStructureViewNode)it.next());
-//                }
-//            }
-//
-//        }
-//        return treeNode;
-//    }
+       private IStructureViewNode buildCustomTree(GlobalStructureView view, IHierarchy model) {
+               IProgramElement rootNode = model.getRoot();
+               IStructureViewNode treeNode = nodeFactory.createNode(rootNode);
 
-//    private IStructureViewNode getRelations(IRelationship node) {
-//     return null;
-//        //StructureViewNode treeNode = new StructureViewNode(node);
-////        IStructureViewNode treeNode = nodeFactory.c(node);
-////        for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
-////            treeNode.add(
-////                   nodeFactory.createNode((IProgramElement)it.next())
-////            );
-////        } 
-////        return treeNode;
-//    }
-//
-//     /**
-//      * For debugging only.
-//      */
-//     private void dumpView(IStructureViewNode root, int level) {
-//             System.out.println(root.getStructureNode());
-//             for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) {
-//                     dumpView((IStructureViewNode)it.next(), level++);       
-//             }
-//             for (int i = 0; i < level; i++) {
-//                     System.out.print(' ');
-//             }               
-//     }
+               List rootNodes = new ArrayList();
+               getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy());
+
+               for (Iterator it = rootNodes.iterator(); it.hasNext(); ) {
+                       if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
+                               treeNode.add(getCrosscuttingChildren((IProgramElement)it.next()));
+                       } else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
+                               treeNode.add(getInheritanceChildren(
+                                               (IProgramElement)it.next(),
+                                               view.getViewProperties().getRelations())
+                                               );
+                       }
+               }
+               return treeNode;
+       }
+
+       private void getRoots(IProgramElement rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) {
+               //        if (rootNode != null && rootNode.getChildren() != null) {
+               //            for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) {
+               //                IProgramElement node = (IProgramElement)it.next();
+               //                if (node instanceof IProgramElement) {
+               //                    if (acceptNodeAsRoot((IProgramElement)node, hierarchy)) {
+               //                        IProgramElement pNode = (IProgramElement)node;
+               //                        List relations = pNode.getRelations();
+               //                        String delimiter = "";
+               //                        if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
+               //                            delimiter = "uses pointcut";
+               //                        } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
+               //                            delimiter = "inherits";
+               //                        }
+               //                        if (relations != null && relations.toString().indexOf(delimiter) == -1) {
+               //                            boolean found = false;
+               //                            for (Iterator it2 = roots.iterator(); it2.hasNext(); ) {
+               //                                if (((IProgramElement)it2.next()).equals(pNode)) found = true;
+               //                            }
+               //                            if (!found) roots.add(pNode);
+               //                        }
+               //                    }
+               //                }
+               //                getRoots(node, roots, hierarchy);
+               //            }
+               //        }
+       }
+
+       public boolean acceptNodeAsRoot(IProgramElement node, StructureViewProperties.Hierarchy hierarchy) {
+               if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
+                       return node.getKind().equals(IProgramElement.Kind.ADVICE)
+                                       || node.getKind().equals(IProgramElement.Kind.POINTCUT);
+               } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
+                       return node.getKind().equals(IProgramElement.Kind.CLASS);
+               } else {
+                       return false;
+               }
+       }
+
+       private IStructureViewNode getInheritanceChildren(IProgramElement node, List associations) {
+               //      IStructureViewNode treeNode = nodeFactory.createNode(node);
+               //        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
+               //        List relations = ((IProgramElement)node).getRelations();
+               throw new RuntimeException("unimplemented");
+               //        if (relations != null) {
+               //            for (Iterator it = relations.iterator(); it.hasNext(); ) {
+               //                              IRelationship relation = (IRelationship)it.next();
+               //                if (relation.getName().equals("is inherited by")) {
+               //                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
+               ////                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
+               ////                        StructureViewNode newNode = getInheritanceChildren(pNode, associations);
+               //                        StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations);
+               //                        for (int i = 0; i < typeChildren.getChildren().size(); i++) {
+               //                            newNode.add((StructureViewNode)typeChildren.getChildren().get(i));
+               //                        }
+               //                                              treeNode.add(newNode);
+               //                    }
+               //                }
+               //            }
+               //        }
+               //        return treeNode;
+       }
+
+       private IStructureViewNode getCrosscuttingChildren(IProgramElement node) {
+               //StructureViewNodeAdapter treeNode = new StructureViewNodeAdapter(node);
+               //        IStructureViewNode treeNode = nodeFactory.createNode(node);
+               //        List relations = ((IProgramElement)node).getRelations();
+               throw new RuntimeException("unimplemented");
+               //        if (relations != null) {
+               //            for (Iterator it = relations.iterator(); it.hasNext(); ) {
+               //                              IRelationship relation = (IRelationship)it.next();
+               //                if (relation.getName().equals("pointcut used by")) {
+               //                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
+               //                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
+               //                        StructureViewNode newNode = getCrosscuttingChildren(pNode);
+               //                        for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) {
+               //                                                      IRelationship relationNode = (IRelation)it3.next();
+               //                            if (relationNode.getName().indexOf("pointcut") == -1) {
+               //                                newNode.add(getRelations(relationNode));
+               //                            }
+               //                        }
+               //                        treeNode.add(newNode);
+               //                    }
+               //                } else if (relations.toString().indexOf("uses pointcut") == -1) {
+               //                    for (Iterator it4 = relations.iterator(); it4.hasNext(); ) {
+               //                        IRelation relationNode = (IRelationship)it4.next();
+               //                        if (relationNode.getName().indexOf("pointcut") == -1) {
+               //                            treeNode.add(getRelations(relationNode));
+               //                        }
+               //                    }
+               //                }
+               //            }
+               //        }
+               //        return treeNode;
+       }
+
+       //    private IStructureViewNode buildTree(IProgramElement node, List associations) {
+       //        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
+       //        IStructureViewNode treeNode = nodeFactory.createNode(node);
+       ////        if (node instanceof IProgramElement) {
+       //            List relations = ((IProgramElement)node).getRelations();
+       //            if (relations != null) {
+       //                for (Iterator it = relations.iterator(); it.hasNext(); ) {
+       //                                      IRelationship relationNode = (IRelationship)it.next();
+       //                    if (associations.contains(relationNode.toString())) {
+       //                        treeNode.add(buildTree(relationNode, associations));
+       //                    }
+       //                }
+       //            }
+       //        }
+       //        if (node != null) {
+       //            List children = null;
+       //            children = node.getChildren();
+       //            if (children != null) {
+       //                List childList = new ArrayList();
+       //                for (Iterator itt = children.iterator(); itt.hasNext(); ) {
+       //                    IProgramElement child = (IProgramElement)itt.next();
+       //                    if (child instanceof IProgramElement) {
+       //                        IProgramElement progNode = (IProgramElement)child;
+       ////                        if (progNode.getKind() != IProgramElement.Kind.CODE) {
+       //                            childList.add(buildTree(child, associations));
+       ////                        }
+       //                    } else {
+       //                        childList.add(buildTree(child, associations));
+       //                    }
+       //                }
+       //                //sortNodes(childList);
+       //                for (Iterator it = childList.iterator(); it.hasNext(); ) {
+       //                    treeNode.add((IStructureViewNode)it.next());
+       //                }
+       //            }
+       //
+       //        }
+       //        return treeNode;
+       //    }
+
+       //    private IStructureViewNode getRelations(IRelationship node) {
+       //      return null;
+       //        //StructureViewNode treeNode = new StructureViewNode(node);
+       ////        IStructureViewNode treeNode = nodeFactory.c(node);
+       ////        for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
+       ////            treeNode.add(
+       ////                    nodeFactory.createNode((IProgramElement)it.next())
+       ////            );
+       ////        }
+       ////        return treeNode;
+       //    }
+       //
+       //      /**
+       //       * For debugging only.
+       //       */
+       //      private void dumpView(IStructureViewNode root, int level) {
+       //              System.out.println(root.getStructureNode());
+       //              for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) {
+       //                      dumpView((IStructureViewNode)it.next(), level++);
+       //              }
+       //              for (int i = 0; i < level; i++) {
+       //                      System.out.print(' ');
+       //              }
+       //      }
 
        /**
         * Does not sort imports alphabetically.
         */
-    private static final Comparator ALPHABETICAL_COMPARATOR = new Comparator() {
-        public int compare(Object o1, Object o2) {  
-               IProgramElement sv1 = ((IStructureViewNode)o1).getStructureNode();
-               IProgramElement sv2 = ((IStructureViewNode)o2).getStructureNode();        
-                       
-            if (sv1!=null && sv2!=null) {
-         
+       private static final Comparator<IStructureViewNode> ALPHABETICAL_COMPARATOR = new Comparator<IStructureViewNode>() {
+               @Override
+               public int compare(IStructureViewNode o1, IStructureViewNode o2) {
+                       IProgramElement sv1 = o1.getStructureNode();
+                       IProgramElement sv2 = o2.getStructureNode();
+                       if (sv1!=null && sv2!=null) {
                                if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
                                if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
-               
                                return sv1.getName().compareTo(sv2.getName());
-            } else {
-               return 0;       
-           }
-        }
-    };
-    
-    private static final Comparator DECLARATIONAL_COMPARATOR = new Comparator() {
-        public int compare(Object o1, Object o2) {            
-               IProgramElement sv1 = ((IStructureViewNode)o1).getStructureNode();
-               IProgramElement sv2 = ((IStructureViewNode)o2).getStructureNode();      
-            if (sv1!=null && sv2!=null) {
-               if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
+                       } else {
+                               return 0;
+                       }
+               }
+       };
+
+       private static final Comparator<IStructureViewNode> DECLARATIONAL_COMPARATOR = new Comparator<IStructureViewNode>() {
+               @Override
+               public int compare(IStructureViewNode o1, IStructureViewNode o2) {
+                       IProgramElement sv1 = o1.getStructureNode();
+                       IProgramElement sv2 = o2.getStructureNode();
+                       if (sv1!=null && sv2!=null) {
+                               if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
                                if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
-               if (sv1.getSourceLocation() == null || sv2.getSourceLocation() == null) {
-                       return 0;
-               } else if (sv1.getSourceLocation().getLine() < sv2.getSourceLocation().getLine()) {
-                       return -1;
-               } else {
-                       return 1;
-               }
-            } else {
-               return 0;       
-           }
-        }
-    };
+                               if (sv1.getSourceLocation() == null || sv2.getSourceLocation() == null) {
+                                       return 0;
+                               } else if (sv1.getSourceLocation().getLine() < sv2.getSourceLocation().getLine()) {
+                                       return -1;
+                               } else {
+                                       return 1;
+                               }
+                       } else {
+                               return 0;
+                       }
+               }
+       };
 }
 
 //    private boolean acceptNode(ProgramElementNode node) {
index b1120f0fbd5c9ecba608e7f1128e19ba11f3081f..572506aed96dd4f5403b9eb9be601bf8cd172253 100644 (file)
@@ -1,19 +1,19 @@
 /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
+ * Copyright (c) 1999-2001 Xerox Corporation,
  *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
  *     Xerox/PARC     initial implementation
- *     Helen Hawkins  Converted to new interface (bug 148190) 
+ *     Helen Hawkins  Converted to new interface (bug 148190)
  * ******************************************************************/
 
+
+
 package org.aspectj.ajde.ui.internal;
 
 import java.io.File;
@@ -33,121 +33,129 @@ import org.aspectj.bridge.Message;
 import org.aspectj.util.LangUtil;
 
 public class UserPreferencesStore implements UserPreferencesAdapter {
-    public static final String FILE_NAME = "/.ajbrowser";
-    private static final String VALUE_SEP = ";";
-    private Properties properties = new Properties();
-    private boolean persist = true;
-       
+       public static final String FILE_NAME = "/.ajbrowser";
+       private static final String VALUE_SEP = ";";
+       private Properties properties = new Properties();
+       private boolean persist = true;
+
        public UserPreferencesStore() {
-        this(true);
+               this(true);
+       }
+
+       public UserPreferencesStore(boolean loadDefault) {
+               persist = loadDefault;
+               if (persist) {
+                       loadProperties(getPropertiesFilePath());
+               }
+       }
+
+       @Override
+       public String getProjectPreference(String name) {
+               return properties.getProperty(name);
+       }
+
+       @Override
+       public List<String> getProjectMultivalPreference(String name) {
+               List<String> values = new ArrayList<>();
+               String valuesString = properties.getProperty(name);
+               if (valuesString != null && !valuesString.trim().equals("")) {
+                       StringTokenizer st = new StringTokenizer(valuesString, VALUE_SEP);
+                       while (st.hasMoreTokens()) {
+                               values.add(st.nextToken());
+                       }
+               }
+               return values;
+       }
+
+       @Override
+       public void setProjectPreference(String name, String value) {
+               properties.setProperty(name, value);
+               saveProperties();
+       }
+
+       @Override
+       public void setProjectMultivalPreference(String name, List values) {
+               String valuesString = "";
+               for (Iterator it = values.iterator(); it.hasNext(); ) {
+                       valuesString += (String)it.next() + ';';
+               }
+               properties.setProperty(name, valuesString);
+               saveProperties();
+       }
+
+       public static String getPropertiesFilePath() {
+               String path = System.getProperty("user.home");
+               if (path == null) {
+                       path = ".";
+               }
+               return path + FILE_NAME;
        }
 
-    public UserPreferencesStore(boolean loadDefault) {
-       persist = loadDefault;
-        if (persist) {
-            loadProperties(getPropertiesFilePath());
-        }
-    }
-       
-    public String getProjectPreference(String name) {
-        return properties.getProperty(name);
-    }
-
-    public List getProjectMultivalPreference(String name) {
-        List values = new ArrayList();
-        String valuesString = properties.getProperty(name);
-        if (valuesString != null && !valuesString.trim().equals("")) {
-            StringTokenizer st = new StringTokenizer(valuesString, VALUE_SEP);
-            while (st.hasMoreTokens()) {
-                values.add(st.nextToken());
-            }
-        }
-        return values;
-    }
-
-    public void setProjectPreference(String name, String value) {
-        properties.setProperty(name, value); 
-        saveProperties();
-    }
-
-    public void setProjectMultivalPreference(String name, List values) {
-        String valuesString = "";
-        for (Iterator it = values.iterator(); it.hasNext(); ) {
-            valuesString += (String)it.next() + ';';
-        }
-        properties.setProperty(name, valuesString);
-        saveProperties();
-    }
-
-    public static String getPropertiesFilePath() {
-        String path = System.getProperty("user.home");
-        if (path == null) {
-            path = ".";
-        }
-        return path + FILE_NAME;
-    }
-    
+       @Override
        public String getGlobalPreference(String name) {
                return getProjectPreference(name);
        }
-       
+
+       @Override
        public List getGlobalMultivalPreference(String name) {
                return getProjectMultivalPreference(name);
        }
-       
+
+       @Override
        public void setGlobalPreference(String name, String value) {
                setProjectPreference(name, value);
        }
-       
+
+       @Override
        public void setGlobalMultivalPreference(String name, List values) {
                setProjectMultivalPreference(name, values);
        }
        private void loadProperties(String path) {
-        if (LangUtil.isEmpty(path)) {
-            return;
-        }
-        File file = new File(path);
-        if (!file.canRead()) {
-            return;
-        }
-        FileInputStream in = null;
-        try {
-            path = getPropertiesFilePath();
-            in = new FileInputStream(file);
-            properties.load(in);
-        } catch (IOException ioe) {
-               Message msg = new Message("Error reading properties from " + path,IMessage.ERROR,ioe,null);
-               Ajde.getDefault().getMessageHandler().handleMessage(msg);
-        } finally {
-            if (null != in) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
+               if (LangUtil.isEmpty(path)) {
+                       return;
+               }
+               File file = new File(path);
+               if (!file.canRead()) {
+                       return;
+               }
+               FileInputStream in = null;
+               try {
+                       path = getPropertiesFilePath();
+                       in = new FileInputStream(file);
+                       properties.load(in);
+               } catch (IOException ioe) {
+                       Message msg = new Message("Error reading properties from " + path,IMessage.ERROR,ioe,null);
+                       Ajde.getDefault().getMessageHandler().handleMessage(msg);
+               } finally {
+                       if (null != in) {
+                               try {
+                                       in.close();
+                               } catch (IOException e) {
+                                       // ignore
+                               }
+                       }
+               }
+       }
+       public void saveProperties() {
+               if (!persist) return;
+
+               FileOutputStream out = null;
+               String path = null;
+               try {
+                       path = getPropertiesFilePath();
+                       out = new FileOutputStream(path);
+                       properties.store(out, "AJDE Settings");
+               } catch (IOException ioe) {
+                       Message msg = new Message("Error writing properties to " + path,IMessage.ERROR,ioe,null);
+                       Ajde.getDefault().getMessageHandler().handleMessage(msg);
+               } finally {
+                       if (null != out) {
+                               try {
+                                       out.close();
+                               } catch (IOException e) {
+                                       // ignore
+                               }
+                       }
+               }
        }
-    public void saveProperties() {
-       if (!persist) return;
-       
-        FileOutputStream out = null;
-        String path = null;
-        try {
-            path = getPropertiesFilePath();
-            out = new FileOutputStream(path);
-            properties.store(out, "AJDE Settings");
-        } catch (IOException ioe) {
-               Message msg = new Message("Error writing properties to " + path,IMessage.ERROR,ioe,null);
-               Ajde.getDefault().getMessageHandler().handleMessage(msg);
-        } finally {
-            if (null != out) {
-                try {
-                    out.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
-    }
 }
index 1d8dba9581ff3f851621922a84842b2aa23eb127..667e673ae4344390d964b5daa65aef95d1595c3b 100644 (file)
@@ -1,11 +1,11 @@
 /********************************************************************
- * Copyright (c) 2007 Contributors. All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: IBM Corporation - initial API and implementation 
+ * Copyright (c) 2007 Contributors. All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
  *                              Helen Hawkins   - initial version (bug 148190)
  *******************************************************************/
 package org.aspectj.ajde.ui.javaoptions;
@@ -14,9 +14,7 @@ import java.awt.BorderLayout;
 import java.awt.Color;
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.swing.BorderFactory;
@@ -37,9 +35,9 @@ import org.aspectj.ajde.ui.swing.OptionsPanel;
 public class JavaComplianceOptionsPanel extends OptionsPanel {
 
        private final String[] complianceLevels = new String[] {JavaOptions.VERSION_13, JavaOptions.VERSION_14, JavaOptions.VERSION_15, JavaOptions.VERSION_16};
-       
+
        private static final long serialVersionUID = 4491319302490183151L;
-       
+
        private JPanel parentPanel;
 
        private Border complianceEtchedBorder;
@@ -47,11 +45,11 @@ public class JavaComplianceOptionsPanel extends OptionsPanel {
        private Border complianceCompoundBorder;
        private JPanel compliancePanel;
        private Box complianceBox = Box.createVerticalBox();
-               
+
        private JavaBuildOptions javaBuildOptions;
 
-       private Map/*String --> JComboBox*/ complianceComboBoxes = new HashMap();
-       
+       private Map<String,JComboBox<String>> complianceComboBoxes = new HashMap<>();
+
        public JavaComplianceOptionsPanel(JavaBuildOptions javaBuildOptions) {
                this.javaBuildOptions = javaBuildOptions;
                try {
@@ -62,20 +60,21 @@ public class JavaComplianceOptionsPanel extends OptionsPanel {
                }
        }
 
+       @Override
        public void loadOptions() throws IOException {
                createComplianceContents();
        }
-       
-       public void saveOptions() throws IOException {          
-               Set s = complianceComboBoxes.entrySet();
-               for (Iterator iterator = s.iterator(); iterator.hasNext();) {
-                       Map.Entry entry = (Entry) iterator.next();
-                       String javaOption = (String) entry.getKey();
-                       JComboBox combo = (JComboBox)entry.getValue();
+
+       @Override
+       public void saveOptions() throws IOException {
+               Set<Map.Entry<String,JComboBox<String>>> s = complianceComboBoxes.entrySet();
+               for (Map.Entry<String,JComboBox<String>> entry : s) {
+                       String javaOption = entry.getKey();
+                       JComboBox<String> combo = entry.getValue();
                        String value = (String) combo.getSelectedItem();
                        javaBuildOptions.setOption(javaOption, value);
                }
-       }       
+       }
 
        private void jbInit() throws Exception {
                this.setLayout(new BorderLayout());
@@ -95,32 +94,32 @@ public class JavaComplianceOptionsPanel extends OptionsPanel {
        private void createComplianceEntry(String labelText, String javaOptionToSet) {
                JPanel panel = new JPanel();
                panel.setLayout(new BorderLayout());
-               
+
                JLabel label = new JLabel();
                label.setFont(new java.awt.Font("Dialog", 0, 11));
                label.setText(labelText);
                panel.add(label,BorderLayout.WEST);
-               
-               JComboBox levels = new JComboBox(complianceLevels);
-               String value = (String) javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
+
+               JComboBox<String> levels = new JComboBox<>(complianceLevels);
+               String value = javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
                if (value == null) {
                        // default to 1.5
                        levels.setSelectedIndex(2);
                } else if (value.equals(JavaOptions.VERSION_13)) {
                        levels.setSelectedIndex(0);
                } else if (value.equals(JavaOptions.VERSION_14)){
-                       levels.setSelectedIndex(1);                     
+                       levels.setSelectedIndex(1);
                } else if (value.equals(JavaOptions.VERSION_15)){
-                       levels.setSelectedIndex(2);                     
+                       levels.setSelectedIndex(2);
                } else if (value.equals(JavaOptions.VERSION_16)){
-                       levels.setSelectedIndex(3);                     
-               }                       
+                       levels.setSelectedIndex(3);
+               }
                panel.add(levels,BorderLayout.EAST);
                complianceBox.add(panel,null);
                complianceComboBoxes.put(javaOptionToSet,levels);
        }
 
-       
+
        private void createBorders() {
                complianceEtchedBorder = BorderFactory.createEtchedBorder(Color.white, new Color(156, 156, 158));
                complianceTitleBorder = new TitledBorder(complianceEtchedBorder, "Compliance Options");
@@ -128,11 +127,11 @@ public class JavaComplianceOptionsPanel extends OptionsPanel {
                                BorderFactory.createEmptyBorder(5, 5, 5, 5));
                complianceTitleBorder.setTitleFont(new java.awt.Font("Dialog", 0, 11));
        }
-       
+
        private void addBordersToPanel() {
                parentPanel = new JPanel();
                parentPanel.setLayout(new BorderLayout());
-               
+
                compliancePanel = new JPanel();
                compliancePanel.setBorder(complianceCompoundBorder);
 
index 9678e3a0decdba0ae16936b22cf27f70c16430df..86f7a50252c87f0c90723b5d6efa572c0959c727 100644 (file)
@@ -1,11 +1,11 @@
 /********************************************************************
- * Copyright (c) 2007 Contributors. All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: IBM Corporation - initial API and implementation 
+ * Copyright (c) 2007 Contributors. All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
  *                              Helen Hawkins   - initial version (bug 148190)
  *******************************************************************/
 package org.aspectj.ajde.ui.javaoptions;
@@ -14,9 +14,7 @@ import java.awt.BorderLayout;
 import java.awt.Color;
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.swing.BorderFactory;
@@ -38,9 +36,9 @@ public class JavaDebugOptionsPanel extends OptionsPanel {
 
        private final String[] debugOptions = new String[] {JavaOptions.GENERATE,JavaOptions.DO_NOT_GENERATE};
        private final String[] preserveOptions = new String[] {JavaOptions.PRESERVE,JavaOptions.OPTIMIZE};
-       
+
        private static final long serialVersionUID = 4491319302490183151L;
-       
+
        private JPanel parentPanel;
 
        private Border debugEtchedBorder;
@@ -48,11 +46,11 @@ public class JavaDebugOptionsPanel extends OptionsPanel {
        private Border debugCompoundBorder;
        private JPanel debugPanel;
        private Box debugBox = Box.createVerticalBox();
-       
+
        private JavaBuildOptions javaBuildOptions;
 
-       private Map/*String --> JComboBox*/ debugComboBoxes = new HashMap();
-       
+       private Map<String,JComboBox<String>> debugComboBoxes = new HashMap();
+
        public JavaDebugOptionsPanel(JavaBuildOptions javaBuildOptions) {
                this.javaBuildOptions = javaBuildOptions;
                try {
@@ -63,20 +61,21 @@ public class JavaDebugOptionsPanel extends OptionsPanel {
                }
        }
 
+       @Override
        public void loadOptions() throws IOException {
                createDebugContents();
        }
-       
-       public void saveOptions() throws IOException {          
-               Set s = debugComboBoxes.entrySet();
-               for (Iterator iterator = s.iterator(); iterator.hasNext();) {
-                       Map.Entry entry = (Entry) iterator.next();
-                       String javaOption = (String) entry.getKey();
-                       JComboBox combo = (JComboBox)entry.getValue();
+
+       @Override
+       public void saveOptions() throws IOException {
+               Set<Map.Entry<String,JComboBox<String>>> s = debugComboBoxes.entrySet();
+               for (Map.Entry<String,JComboBox<String>> entry : s) {
+                       String javaOption = entry.getKey();
+                       JComboBox<String> combo = entry.getValue();
                        String value = (String) combo.getSelectedItem();
                        javaBuildOptions.setOption(javaOption, value);
                }
-       }       
+       }
 
        private void jbInit() throws Exception {
                this.setLayout(new BorderLayout());
@@ -88,7 +87,7 @@ public class JavaDebugOptionsPanel extends OptionsPanel {
        private void createDebugContents() {
                createDebugEntry("Add line number attributes to generated class files",JavaOptions.DEBUG_LINES);
                createDebugEntry("Add source file name to generated class file",JavaOptions.DEBUG_SOURCE);
-               createDebugEntry("Add variable attributes to generated class files",JavaOptions.DEBUG_VARS);    
+               createDebugEntry("Add variable attributes to generated class files",JavaOptions.DEBUG_VARS);
                createDebugEntry("Preserve unused (never read) local variables",JavaOptions.PRESERVE_ALL_LOCALS);
                debugPanel.add(debugBox);
        }
@@ -96,48 +95,48 @@ public class JavaDebugOptionsPanel extends OptionsPanel {
        private void createDebugEntry(String labelText, String javaOptionToSet) {
                JPanel panel = new JPanel();
                panel.setLayout(new BorderLayout());
-               
+
                JLabel label = new JLabel();
                label.setFont(new java.awt.Font("Dialog", 0, 11));
                label.setText(labelText);
                panel.add(label,BorderLayout.WEST);
-               
-               JComboBox debug = null;
+
+               JComboBox<String> debug = null;
                if (javaOptionToSet.equals(JavaOptions.PRESERVE_ALL_LOCALS)) {
-                       debug = new JComboBox(preserveOptions);
-                       String value = (String) javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
+                       debug = new JComboBox<String>(preserveOptions);
+                       String value = javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
                        if (value.equals(JavaOptions.PRESERVE)) {
                                debug.setSelectedIndex(0);
                        } else {
-                               debug.setSelectedIndex(1);                      
-                       }       
+                               debug.setSelectedIndex(1);
+                       }
                } else {
-                       debug = new JComboBox(debugOptions);
-                       String value = (String) javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
+                       debug = new JComboBox<String>(debugOptions);
+                       String value = javaBuildOptions.getJavaBuildOptionsMap().get(javaOptionToSet);
                        if (value.equals(JavaOptions.GENERATE)) {
                                debug.setSelectedIndex(0);
                        } else {
-                               debug.setSelectedIndex(1);                      
-                       }       
-               }       
+                               debug.setSelectedIndex(1);
+                       }
+               }
                panel.add(debug,BorderLayout.EAST);
                debugBox.add(panel,null);
-               debugComboBoxes.put(javaOptionToSet,debug);     
+               debugComboBoxes.put(javaOptionToSet,debug);
        }
 
-       
-       private void createBorders() {          
+
+       private void createBorders() {
                debugEtchedBorder = BorderFactory.createEtchedBorder(Color.white, new Color(156, 156, 158));
                debugTitleBorder = new TitledBorder(debugEtchedBorder, "Debug Options");
                debugCompoundBorder = BorderFactory.createCompoundBorder(debugTitleBorder,
                                BorderFactory.createEmptyBorder(5, 5, 5, 5));
                debugTitleBorder.setTitleFont(new java.awt.Font("Dialog", 0, 11));
        }
-       
+
        private void addBordersToPanel() {
                parentPanel = new JPanel();
                parentPanel.setLayout(new BorderLayout());
-               
+
                debugPanel = new JPanel();
                debugPanel.setBorder(debugCompoundBorder);
 
index 05efb60e6c17b6b2297db768f0f862eb37e62320..fea887cb6b9dd89a5c5515c13eb75a05388081b0 100644 (file)
@@ -1,12 +1,12 @@
 /* *******************************************************************
  * Copyright (c) 2003 Contributors
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
  *     Wes Isberg     initial implementation
  * ******************************************************************/
 
@@ -18,17 +18,13 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-
 import org.aspectj.ajdt.internal.core.builder.AjState;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.IMessageHolder;
 import org.aspectj.bridge.MessageHandler;
 import org.aspectj.bridge.MessageUtil;
 import org.aspectj.testing.harness.bridge.AjcTest;
+import org.aspectj.testing.harness.bridge.AjcTest.Spec;
 import org.aspectj.testing.harness.bridge.RunSpecIterator;
 import org.aspectj.testing.harness.bridge.Sandbox;
 import org.aspectj.testing.harness.bridge.Validator;
@@ -36,6 +32,11 @@ import org.aspectj.testing.run.IRunIterator;
 import org.aspectj.testing.run.RunStatus;
 import org.aspectj.testing.run.Runner;
 
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
 /*
  * Adapt Harness tests to JUnit driver. This renders suite files as TestSuite
  * and AjcTest as TestCase. When run, aborts are reported as error and fails as
@@ -47,336 +48,344 @@ import org.aspectj.testing.run.Runner;
  * the test.
  */
 public class AjctestsAdapter extends TestSuite {
-    public static final String VERBOSE_NAME = AjctestsAdapter.class.getName()
-            + ".VERBOSE";
-
-    private static final boolean VERBOSE = HarnessJUnitUtil
-            .readBooleanSystemProperty(VERBOSE_NAME);
-
-    /**
-     * Factory to make and populate suite without options.
-     * 
-     * @param suitePath
-     *            the String path to a harness suite file
-     * @return AjctestJUnitSuite populated with tests
-     */
-    public static AjctestsAdapter make(String suitePath) {
-        return make(suitePath, null);
-    }
-
-    /**
-     * Factory to make and populate suite
-     * 
-     * @param suitePath
-     *            the String path to a harness suite file
-     * @param options
-     *            the String[] options to use when creating tests
-     * @return AjctestJUnitSuite populated with tests
-     */
-    public static AjctestsAdapter make(String suitePath, String[] options) {
-        AjctestsAdapter result = new AjctestsAdapter(suitePath, options);
-        AjcTest.Spec[] tests = AjcTest.Suite.getTests(result.getSpec());
-        if (VERBOSE) {
-            log("loading " + tests.length + " tests in " + suitePath);
-        }
-        for (int i = 0; i < tests.length; i++) {
-            AjcTest.Spec ajcTest = tests[i];
-            result.addTest(new AjcTestSpecAsTest(ajcTest, result));
-        }
-        return result;
-    }
-    
-    private static void log(String message) {
-        System.err.println(message);
-        System.err.flush();
-    }
-
-    private final String suitePath;
-
-    private final String[] options;
-
-    private AjcTest.Suite.Spec spec;
-
-    private Runner runner;
-
-    private Validator validator;
-
-    private IMessageHolder holder;
-
-    private Sandbox sandbox;
-
-    private File suiteDir;
-
-    private String name;
-
-    private AjctestsAdapter(String suitePath, String[] options) {
-        this.suitePath = suitePath;
-        String[] opts = new String[0];
-        if (!HarnessJUnitUtil.isEmpty(options)) {
-            opts = new String[options.length];
-            System.arraycopy(options, 0, opts, 0, opts.length);
-        }
-        this.options = opts;
-    }
-
-    public void addTest(Test test) {
-        if (!(test instanceof AjcTestSpecAsTest)) {
-            String m = "expecting AjcTestSpecAsTest, got "
-                    + (null == test ? "null test" : test.getClass().getName()
-                            + ": " + test);
-            throw new IllegalArgumentException(m);
-        }
-        super.addTest(test);
-    }
-
-    public void addTestSuite(Class testClass) {
-        throw new Error("unimplemented");
-    }
-
-    public String getName() {
-        if (null == name) {
-            name = HarnessJUnitUtil.cleanTestName(suitePath
-                    + Arrays.asList(options));
-        }
-        return name;
-    }
-
-    /**
-     * Callback from test to run it using suite-wide holder, etc. The caller is
-     * responsible for calling result.startTest(test) and result.endTest(test);
-     * 
-     * @param test
-     *            the AjcTestSpecAsTest to run
-     * @param result
-     *            the TestResult for any result messages (may be null)
-     */
-    protected void runTest(AjcTestSpecAsTest test, TestResult result) {
-        final Runner runner = getRunner();
-        final Sandbox sandbox = getSandbox();
-        final Validator validator = getValidator();
-        int numIncomplete = 0;
-        final RunStatus status = new RunStatus(new MessageHandler(), runner);
-        status.setIdentifier(test.toString());
-        try {
-            IMessageHolder holder = getHolder();
-            holder.clearMessages();
-            IRunIterator steps = test.spec.makeRunIterator(sandbox, validator);
-            if (0 < holder.numMessages(IMessage.ERROR, true)) {
-                MessageUtil.handleAll(status, holder, IMessage.INFO, true,
-                        false);
-            } else {
-                runner.runIterator(steps, status, null);
-            }
-            if (steps instanceof RunSpecIterator) {
-                numIncomplete = ((RunSpecIterator) steps).getNumIncomplete();
-            }
-        } finally {
-            try {
-                // reportResult handles null TestResult
-                HarnessJUnitUtil
-                        .reportResult(null, status, test, numIncomplete);
-            } finally {
-                validator.deleteTempFiles(true);
-            }
-        }
-    }
-
-    private File getSuiteDir() {
-        if (null == suiteDir) {
-            File file = new File(suitePath);
-            file = file.getParentFile();
-            if (null == file) {
-                file = new File(".");
-            }
-            suiteDir = file;
-        }
-        return suiteDir;
-    }
-
-    private Validator getValidator() {
-        if (null == validator) {
-            validator = new Validator(getHolder());
-            // XXX lock if keepTemp?
-        }
-        return validator;
-    }
-
-    private Runner getRunner() {
-        if (null == runner) {
-            runner = new Runner();
-        }
-        return runner;
-    }
-
-    private IMessageHolder getHolder() {
-        if (null == holder) {
-            holder = new MessageHandler();
-        }
-        return holder;
-    }
-
-    private AjcTest.Suite.Spec getSpec() {
-        if (null == spec) {
-            IMessageHolder holder = getHolder();
-            spec = HarnessJUnitUtil.getSuiteSpec(suitePath, options,
-                    getHolder());
-            if (VERBOSE && holder.hasAnyMessage(null, true)) {
-                MessageUtil.print(System.err, holder, "skip ",
-                        MessageUtil.MESSAGE_MOST);
-            }
-            holder.clearMessages();
-        }
-        return spec;
-    }
-
-    private Sandbox getSandbox() {
-        if (null == sandbox) {
-            sandbox = new Sandbox(spec.getSuiteDirFile(), getValidator());
-        }
-        return sandbox;
-    }
-
-    /**
-     * Wrap AjcTest.Spec for lookup by description
-     * 
-     * @author wes
-     */
-    public static class SpecTests {
-        private static final HashMap TESTS = new HashMap();
-
-//        private static void putSpecTestsFor(String id, SpecTests tests) {
-//            TESTS.put(id, tests);
-//        }
-
-        private static SpecTests getSpecTestsFor(String id) {
-            SpecTests result = (SpecTests) TESTS.get(id);
-            if (null == result) {
-                throw new Error("no tests found for " + id);
-            }
-            return result;
-        }
-        
-        // ------------------------------------
-        final AjctestsAdapter mAjctestsAdapter;
-
-        private final Map mDescriptionToAjcTestSpec;
-
-        // ------------------------------------
-        private SpecTests(AjctestsAdapter ajctestsAdapter, AjcTest.Spec[] tests) {
-            mAjctestsAdapter = ajctestsAdapter;
-            Map map = new HashMap();
-            for (int i = 0; i < tests.length; i++) {
-                map.put(tests[i].getDescription(), tests[i]);
-            }
-            
-            mDescriptionToAjcTestSpec = Collections.unmodifiableMap(map);
-        }
-
-        /**
-         * @param description
-         *            the String description of the test
-         * @throws IllegalArgumentException
-         *             if testName is not found
-         */
-        protected void runTest(String description) {
-            AjcTest.Spec spec = getSpec(description);
-            AjctestsAdapter.AjcTestSpecAsTest ajcTestAsSpec = new AjctestsAdapter.AjcTestSpecAsTest(
-                    spec, mAjctestsAdapter);
-            // runTest handles null TestResult
-            mAjctestsAdapter.runTest(ajcTestAsSpec, null);
-        }
-
-        /**
-         * @param description
-         *            the String description of the test
-         * @throws IllegalArgumentException
-         *             if testName is not found
-         */
-        private AjcTest.Spec getSpec(String description) {
-            AjcTest.Spec spec = (AjcTest.Spec) mDescriptionToAjcTestSpec
-                    .get(description);
-            if (null == spec) {
-                throw new IllegalArgumentException("no test for " + description);
-            }
-            return spec;
-        }
-
-        /**
-         * makeUsingTestClass(..) extends this to create TestCase with
-         * test_{name} for each test case.
-         */
-        public static class TestClass extends TestCase {
-            public TestClass() {                
-            }
-            private SpecTests mTests;
-
-            /**
-             * Called by code generated in makeUsingTestClass(..)
-             * 
-             * @param description
-             *            the String identifier of the test stored in SpecTests
-             *            mTests.
-             * @throws Error
-             *             on first and later uses if getTestsFor() returns
-             *             null.
-             */
-            public final void runTest(String description) {
-                if (null == mTests) {
-                    String classname = getClass().getName();
-                    mTests = getSpecTestsFor(classname);
-                }
-                mTests.runTest(description);
-            }
-        }
-    }
-
-    /** Wrap AjcTest.Spec as a TestCase. Run by delegation to suite */
-    private static class AjcTestSpecAsTest extends TestCase implements
-            HarnessJUnitUtil.IHasAjcSpec {
-        // this could implement Test, but Ant batchtest fails to pull name
-        final String name;
-
-        final AjcTest.Spec spec;
-
-        AjctestsAdapter suite;
-
-        AjcTestSpecAsTest(AjcTest.Spec spec, AjctestsAdapter suite) {
-            super(HarnessJUnitUtil.cleanTestName(spec.getDescription()));
-            this.name = HarnessJUnitUtil.cleanTestName(spec.getDescription());
-            this.suite = suite;
-            this.spec = spec;
-            spec.setSuiteDir(suite.getSuiteDir());
-        }
-
-        public int countTestCases() {
-            return 1;
-        }
-
-        public AjcTest.Spec getAjcTestSpec() {
-            return spec;
-        }
-
-        public void run(TestResult result) {
-            if (null == suite) {
-                throw new Error("need to re-init");
-            }
-            try {
-               AjState.FORCE_INCREMENTAL_DURING_TESTING = true;
-                result.startTest(this);
-                suite.runTest(this, result);
-            } finally {
-                result.endTest(this);
-                suite = null;
-                AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
-            }
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String toString() {
-            return name;
-        }
-    }
+       public static final String VERBOSE_NAME = AjctestsAdapter.class.getName()
+                       + ".VERBOSE";
+
+       private static final boolean VERBOSE = HarnessJUnitUtil
+                       .readBooleanSystemProperty(VERBOSE_NAME);
+
+       /**
+        * Factory to make and populate suite without options.
+        *
+        * @param suitePath
+        *            the String path to a harness suite file
+        * @return AjctestJUnitSuite populated with tests
+        */
+       public static AjctestsAdapter make(String suitePath) {
+               return make(suitePath, null);
+       }
+
+       /**
+        * Factory to make and populate suite
+        *
+        * @param suitePath
+        *            the String path to a harness suite file
+        * @param options
+        *            the String[] options to use when creating tests
+        * @return AjctestJUnitSuite populated with tests
+        */
+       public static AjctestsAdapter make(String suitePath, String[] options) {
+               AjctestsAdapter result = new AjctestsAdapter(suitePath, options);
+               AjcTest.Spec[] tests = AjcTest.Suite.getTests(result.getSpec());
+               if (VERBOSE) {
+                       log("loading " + tests.length + " tests in " + suitePath);
+               }
+               for (Spec ajcTest : tests) {
+                       result.addTest(new AjcTestSpecAsTest(ajcTest, result));
+               }
+               return result;
+       }
+
+       private static void log(String message) {
+               System.err.println(message);
+               System.err.flush();
+       }
+
+       private final String suitePath;
+
+       private final String[] options;
+
+       private AjcTest.Suite.Spec spec;
+
+       private Runner runner;
+
+       private Validator validator;
+
+       private IMessageHolder holder;
+
+       private Sandbox sandbox;
+
+       private File suiteDir;
+
+       private String name;
+
+       private AjctestsAdapter(String suitePath, String[] options) {
+               this.suitePath = suitePath;
+               String[] opts = new String[0];
+               if (!HarnessJUnitUtil.isEmpty(options)) {
+                       opts = new String[options.length];
+                       System.arraycopy(options, 0, opts, 0, opts.length);
+               }
+               this.options = opts;
+       }
+
+       @Override
+       public void addTest(Test test) {
+               if (!(test instanceof AjcTestSpecAsTest)) {
+                       String m = "expecting AjcTestSpecAsTest, got "
+                                       + (null == test ? "null test" : test.getClass().getName()
+                                                       + ": " + test);
+                       throw new IllegalArgumentException(m);
+               }
+               super.addTest(test);
+       }
+
+       @SuppressWarnings("rawtypes")
+       @Override
+       public void addTestSuite(Class testClass) {
+               throw new Error("unimplemented");
+       }
+
+       @Override
+       public String getName() {
+               if (null == name) {
+                       name = HarnessJUnitUtil.cleanTestName(suitePath
+                                       + Arrays.asList(options));
+               }
+               return name;
+       }
+
+       /**
+        * Callback from test to run it using suite-wide holder, etc. The caller is
+        * responsible for calling result.startTest(test) and result.endTest(test);
+        *
+        * @param test
+        *            the AjcTestSpecAsTest to run
+        * @param result
+        *            the TestResult for any result messages (may be null)
+        */
+       protected void runTest(AjcTestSpecAsTest test, TestResult result) {
+               final Runner runner = getRunner();
+               final Sandbox sandbox = getSandbox();
+               final Validator validator = getValidator();
+               int numIncomplete = 0;
+               final RunStatus status = new RunStatus(new MessageHandler(), runner);
+               status.setIdentifier(test.toString());
+               try {
+                       IMessageHolder holder = getHolder();
+                       holder.clearMessages();
+                       IRunIterator steps = test.spec.makeRunIterator(sandbox, validator);
+                       if (0 < holder.numMessages(IMessage.ERROR, true)) {
+                               MessageUtil.handleAll(status, holder, IMessage.INFO, true,
+                                               false);
+                       } else {
+                               runner.runIterator(steps, status, null);
+                       }
+                       if (steps instanceof RunSpecIterator) {
+                               numIncomplete = ((RunSpecIterator) steps).getNumIncomplete();
+                       }
+               } finally {
+                       try {
+                               // reportResult handles null TestResult
+                               HarnessJUnitUtil
+                               .reportResult(null, status, test, numIncomplete);
+                       } finally {
+                               validator.deleteTempFiles(true);
+                       }
+               }
+       }
+
+       private File getSuiteDir() {
+               if (null == suiteDir) {
+                       File file = new File(suitePath);
+                       file = file.getParentFile();
+                       if (null == file) {
+                               file = new File(".");
+                       }
+                       suiteDir = file;
+               }
+               return suiteDir;
+       }
+
+       private Validator getValidator() {
+               if (null == validator) {
+                       validator = new Validator(getHolder());
+                       // XXX lock if keepTemp?
+               }
+               return validator;
+       }
+
+       private Runner getRunner() {
+               if (null == runner) {
+                       runner = new Runner();
+               }
+               return runner;
+       }
+
+       private IMessageHolder getHolder() {
+               if (null == holder) {
+                       holder = new MessageHandler();
+               }
+               return holder;
+       }
+
+       private AjcTest.Suite.Spec getSpec() {
+               if (null == spec) {
+                       IMessageHolder holder = getHolder();
+                       spec = HarnessJUnitUtil.getSuiteSpec(suitePath, options,
+                                       getHolder());
+                       if (VERBOSE && holder.hasAnyMessage(null, true)) {
+                               MessageUtil.print(System.err, holder, "skip ",
+                                               MessageUtil.MESSAGE_MOST);
+                       }
+                       holder.clearMessages();
+               }
+               return spec;
+       }
+
+       private Sandbox getSandbox() {
+               if (null == sandbox) {
+                       sandbox = new Sandbox(spec.getSuiteDirFile(), getValidator());
+               }
+               return sandbox;
+       }
+
+       /**
+        * Wrap AjcTest.Spec for lookup by description
+        *
+        * @author wes
+        */
+       public static class SpecTests {
+               private static final HashMap<String,SpecTests> TESTS = new HashMap<>();
+
+               //        private static void putSpecTestsFor(String id, SpecTests tests) {
+               //            TESTS.put(id, tests);
+               //        }
+
+               private static SpecTests getSpecTestsFor(String id) {
+                       SpecTests result = TESTS.get(id);
+                       if (null == result) {
+                               throw new Error("no tests found for " + id);
+                       }
+                       return result;
+               }
+
+               // ------------------------------------
+               final AjctestsAdapter mAjctestsAdapter;
+
+               private final Map<String,AjcTest.Spec> mDescriptionToAjcTestSpec;
+
+               // ------------------------------------
+               private SpecTests(AjctestsAdapter ajctestsAdapter, AjcTest.Spec[] tests) {
+                       mAjctestsAdapter = ajctestsAdapter;
+                       Map<String,AjcTest.Spec> map = new HashMap<>();
+                       for (Spec test : tests) {
+                               map.put(test.getDescription(), test);
+                       }
+
+                       mDescriptionToAjcTestSpec = Collections.unmodifiableMap(map);
+               }
+
+               /**
+                * @param description
+                *            the String description of the test
+                * @throws IllegalArgumentException
+                *             if testName is not found
+                */
+               protected void runTest(String description) {
+                       AjcTest.Spec spec = getSpec(description);
+                       AjctestsAdapter.AjcTestSpecAsTest ajcTestAsSpec = new AjctestsAdapter.AjcTestSpecAsTest(
+                                       spec, mAjctestsAdapter);
+                       // runTest handles null TestResult
+                       mAjctestsAdapter.runTest(ajcTestAsSpec, null);
+               }
+
+               /**
+                * @param description
+                *            the String description of the test
+                * @throws IllegalArgumentException
+                *             if testName is not found
+                */
+               private AjcTest.Spec getSpec(String description) {
+                       AjcTest.Spec spec = mDescriptionToAjcTestSpec
+                                       .get(description);
+                       if (null == spec) {
+                               throw new IllegalArgumentException("no test for " + description);
+                       }
+                       return spec;
+               }
+
+               /**
+                * makeUsingTestClass(..) extends this to create TestCase with
+                * test_{name} for each test case.
+                */
+               public static class TestClass extends TestCase {
+                       public TestClass() {
+                       }
+                       private SpecTests mTests;
+
+                       /**
+                        * Called by code generated in makeUsingTestClass(..)
+                        *
+                        * @param description
+                        *            the String identifier of the test stored in SpecTests
+                        *            mTests.
+                        * @throws Error
+                        *             on first and later uses if getTestsFor() returns
+                        *             null.
+                        */
+                       public final void runTest(String description) {
+                               if (null == mTests) {
+                                       String classname = getClass().getName();
+                                       mTests = getSpecTestsFor(classname);
+                               }
+                               mTests.runTest(description);
+                       }
+               }
+       }
+
+       /** Wrap AjcTest.Spec as a TestCase. Run by delegation to suite */
+       private static class AjcTestSpecAsTest extends TestCase implements
+       HarnessJUnitUtil.IHasAjcSpec {
+               // this could implement Test, but Ant batchtest fails to pull name
+               final String name;
+
+               final AjcTest.Spec spec;
+
+               AjctestsAdapter suite;
+
+               AjcTestSpecAsTest(AjcTest.Spec spec, AjctestsAdapter suite) {
+                       super(HarnessJUnitUtil.cleanTestName(spec.getDescription()));
+                       this.name = HarnessJUnitUtil.cleanTestName(spec.getDescription());
+                       this.suite = suite;
+                       this.spec = spec;
+                       spec.setSuiteDir(suite.getSuiteDir());
+               }
+
+               @Override
+               public int countTestCases() {
+                       return 1;
+               }
+
+               @Override
+               public AjcTest.Spec getAjcTestSpec() {
+                       return spec;
+               }
+
+               @Override
+               public void run(TestResult result) {
+                       if (null == suite) {
+                               throw new Error("need to re-init");
+                       }
+                       try {
+                               AjState.FORCE_INCREMENTAL_DURING_TESTING = true;
+                               result.startTest(this);
+                               suite.runTest(this, result);
+                       } finally {
+                               result.endTest(this);
+                               suite = null;
+                               AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
+                       }
+               }
+
+               @Override
+               public String getName() {
+                       return name;
+               }
+
+               @Override
+               public String toString() {
+                       return name;
+               }
+       }
 }
\ No newline at end of file
index 767444ce3c7da64ef4884bececbe5da9fe9239ba..f1c8b3635ec5c748284f6586b0a1d7fbbfc79478 100644 (file)
@@ -32,6 +32,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
@@ -44,6 +45,7 @@ import org.aspectj.testing.harness.bridge.AbstractRunSpec;
 import org.aspectj.testing.harness.bridge.AjcTest;
 import org.aspectj.testing.harness.bridge.CompilerRun;
 import org.aspectj.testing.harness.bridge.FlatSuiteReader;
+import org.aspectj.testing.harness.bridge.IRunSpec;
 import org.aspectj.testing.harness.bridge.IncCompilerRun;
 import org.aspectj.testing.harness.bridge.JavaRun;
 import org.aspectj.testing.harness.bridge.RunSpecIterator;
@@ -82,236 +84,236 @@ import org.aspectj.util.LangUtil;
  * categories.
  */
 public class Harness {
-    /**
-     * Spaces up to the width that an option should take in the syntax,
-     * including the two-space leader
-     */
-    protected static final String SYNTAX_PAD = "                    ";
-    protected static final String OPTION_DELIM = ";";
-    private static final String JAVA_VERSION;
-    private static final String ASPECTJ_VERSION;
-    static {
-        String version = "UNKNOWN";
-        try {  version = System.getProperty("java.version", "UNKNOWN"); }
-        catch (Throwable t) {}
-        JAVA_VERSION = version;
-
-        version = "UNKNOWN";
-        try {
-            Class c = Class.forName("org.aspectj.bridge.Version");
-            version = (String) c.getField("text").get(null);
-        } catch (Throwable t) {
-            // ignore
-        }
-        ASPECTJ_VERSION = version;
-    }
-
-    /** factory for the subclass currently anointed as default */
-    public static Harness makeHarness() {
-        return new FeatureHarness();
-    }
-
-    /** @param args String[] like runMain(String[]) args */
-    public static void main(String[] args) throws Exception {
-        if (LangUtil.isEmpty(args)) {
-            File argFile = new File("HarnessArgs.txt");
-            if (argFile.canRead()) {
-                args = readArgs(argFile);
-            } else {
-                args = new String[] { "-help" };
-            }
-        }
-        makeHarness().runMain(args, null);
-    }
-
-    /**
-     * Get known option aliases.
-     * Subclasses may add new aliases, where the key is the alias option,
-     * and the value is a comma-delimited String of target options.
-     * @return Properties with feature aliases or null
-     */
-    protected static Properties getOptionAliases() {
-        if (null == optionAliases) {
-            optionAliases = new Properties();
-            // XXX load from **OptionAliases.properties
-        }
-        return optionAliases;
-    }
-
-    /**
-     * Read argFile contents into String[],
-     * delimiting at any whitespace
-     */
-    private static String[] readArgs(File argFile) {
-        ArrayList<String> args = new ArrayList<>();
-//        int lineNum = 0;
-
-        try {
-            BufferedReader stream =
-                new BufferedReader(new FileReader(argFile));
-            String line;
-            while (null != (line = stream.readLine())) {
-                StringTokenizer st = new StringTokenizer(line);
-                while (st.hasMoreTokens()) {
-                    args.add(st.nextToken());
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace(System.err);
-        }
-        return args.toArray(new String[0]);
-    }
-
-    /** aliases key="option" value="option{,option}" */
-    private static Properties optionAliases;
-
-    /** be extra noisy if true */
-    private boolean verboseHarness;
-
-    /** be extra quiet if true */
-    private boolean quietHarness;
-
-    /** just don't say anything! */
-    protected boolean silentHarness;
-
-    private HashMap<String,Feature> features;
+       /**
+        * Spaces up to the width that an option should take in the syntax,
+        * including the two-space leader
+        */
+       protected static final String SYNTAX_PAD = "                    ";
+       protected static final String OPTION_DELIM = ";";
+       private static final String JAVA_VERSION;
+       private static final String ASPECTJ_VERSION;
+       static {
+               String version = "UNKNOWN";
+               try {  version = System.getProperty("java.version", "UNKNOWN"); }
+               catch (Throwable t) {}
+               JAVA_VERSION = version;
+
+               version = "UNKNOWN";
+               try {
+                       Class c = Class.forName("org.aspectj.bridge.Version");
+                       version = (String) c.getField("text").get(null);
+               } catch (Throwable t) {
+                       // ignore
+               }
+               ASPECTJ_VERSION = version;
+       }
+
+       /** factory for the subclass currently anointed as default */
+       public static Harness makeHarness() {
+               return new FeatureHarness();
+       }
+
+       /** @param args String[] like runMain(String[]) args */
+       public static void main(String[] args) throws Exception {
+               if (LangUtil.isEmpty(args)) {
+                       File argFile = new File("HarnessArgs.txt");
+                       if (argFile.canRead()) {
+                               args = readArgs(argFile);
+                       } else {
+                               args = new String[] { "-help" };
+                       }
+               }
+               makeHarness().runMain(args, null);
+       }
+
+       /**
+        * Get known option aliases.
+        * Subclasses may add new aliases, where the key is the alias option,
+        * and the value is a comma-delimited String of target options.
+        * @return Properties with feature aliases or null
+        */
+       protected static Properties getOptionAliases() {
+               if (null == optionAliases) {
+                       optionAliases = new Properties();
+                       // XXX load from **OptionAliases.properties
+               }
+               return optionAliases;
+       }
+
+       /**
+        * Read argFile contents into String[],
+        * delimiting at any whitespace
+        */
+       private static String[] readArgs(File argFile) {
+               ArrayList<String> args = new ArrayList<>();
+               //        int lineNum = 0;
+
+               try {
+                       BufferedReader stream =
+                                       new BufferedReader(new FileReader(argFile));
+                       String line;
+                       while (null != (line = stream.readLine())) {
+                               StringTokenizer st = new StringTokenizer(line);
+                               while (st.hasMoreTokens()) {
+                                       args.add(st.nextToken());
+                               }
+                       }
+               } catch (IOException e) {
+                       e.printStackTrace(System.err);
+               }
+               return args.toArray(new String[0]);
+       }
+
+       /** aliases key="option" value="option{,option}" */
+       private static Properties optionAliases;
+
+       /** be extra noisy if true */
+       private boolean verboseHarness;
+
+       /** be extra quiet if true */
+       private boolean quietHarness;
+
+       /** just don't say anything! */
+       protected boolean silentHarness;
+
+       private HashMap<String,Feature> features;
 
        /** if true, do not delete temporary files. */
        private boolean keepTemp;
 
-    /** if true, delete temporary files as each test completes. */
-    private boolean killTemp;
+       /** if true, delete temporary files as each test completes. */
+       private boolean killTemp;
 
        /** if true, then log results in report(..) when done */
        private boolean logResults;
 
-    /** if true and there were failures, do System.exit({numFailures})*/
-    private boolean exitOnFailure;
-
-    protected Harness() {
-        features = new HashMap<>();
-    }
-
-
-    /**
-     * Entry point for a test.
-     * This reads in the arguments,
-     * creates the test suite(s) from the input file(s),
-     * and for each suite does setup, run, report, and cleanup.
-     * When arguments are read, any option ending with "-" causes
-     * option variants, a set of args with and another without the
-     * option. See {@link LangUtil.optionVariants(String[])} for
-     * more details.
-     * @param args the String[] for the test suite - use -help to get options,
-     *         and use "-" suffixes for variants.
-     * @param resultList List for IRunStatus results - ignored if null
-     */
-    public void runMain(String[] args, List resultList) {
-        LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(args), "empty args");
-        // read arguments
-        final ArrayList<String> globals = new ArrayList<>();
-        final ArrayList<String> files = new ArrayList<>();
-        final LinkedList<String> argList = new LinkedList<>();
-        argList.addAll(Arrays.asList(args));
-        for (int i = 0; i < argList.size(); i++) {
-            String arg = argList.get(i);
-            List<String> aliases = aliasOptions(arg);
-            if (!LangUtil.isEmpty(aliases)) {
-                argList.remove(i);
-                argList.addAll(i, aliases);
-                i--;
-                continue;
-            }
-            if ("-help".equals(arg)) {
-                logln("java " + Harness.class.getName() + " {option|suiteFile}..");
-                printSyntax(getLogStream());
-                return;
-            } else if (isSuiteFile(arg)) {
-                files.add(arg);
-            } else if (!acceptOption(arg)) {
-                globals.add(arg);
-            } // else our options absorbed
-        }
-        if (0 == files.size()) {
-            logln("## Error reading arguments: at least 1 suite file required");
-            logln("java " + Harness.class.getName() + " {option|suiteFile}..");
-            printSyntax(getLogStream());
-            return;
-        }
-        String[] globalOptions = globals.toArray(new String[0]);
-        String[][] globalOptionVariants = optionVariants(globalOptions);
-        AbstractRunSpec.RT runtime = new AbstractRunSpec.RT();
-        if (verboseHarness) {
-            runtime.setVerbose(true);
-        }
-
-        // run suites read from each file
-        AjcTest.Suite.Spec spec;
-        for (Iterator iter = files.iterator(); iter.hasNext();) {
-            File suiteFile = new File((String) iter.next());
-            if (!suiteFile.canRead()) {
-                logln("runMain(..) cannot read file: " + suiteFile);
-                continue;
-            }
-            if (null == (spec = readSuite(suiteFile))) {
-                logln("runMain(..) cannot read suite from file: " + suiteFile);
-                continue;
-            }
-
-            MessageHandler holder = new MessageHandler();
-            for (int i = 0; i < globalOptionVariants.length; i++) {
-                runtime.setOptions(globalOptionVariants[i]);
-                holder.init();
-                boolean skip = !spec.adoptParentValues(runtime, holder);
-                // awful/brittle assumption about number of skips == number of skip messages
-                final List skipList = MessageUtil.getMessages(holder, IMessage.INFO, false, "skip");
-                if ((verboseHarness || skip || (0 < skipList.size()))) {
-                    final List curArgs = Arrays.asList(globalOptionVariants[i]);
+       /** if true and there were failures, do System.exit({numFailures})*/
+       private boolean exitOnFailure;
+
+       protected Harness() {
+               features = new HashMap<>();
+       }
+
+
+       /**
+        * Entry point for a test.
+        * This reads in the arguments,
+        * creates the test suite(s) from the input file(s),
+        * and for each suite does setup, run, report, and cleanup.
+        * When arguments are read, any option ending with "-" causes
+        * option variants, a set of args with and another without the
+        * option. See {@link LangUtil.optionVariants(String[])} for
+        * more details.
+        * @param args the String[] for the test suite - use -help to get options,
+        *         and use "-" suffixes for variants.
+        * @param resultList List for IRunStatus results - ignored if null
+        */
+       public void runMain(String[] args, List resultList) {
+               LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(args), "empty args");
+               // read arguments
+               final ArrayList<String> globals = new ArrayList<>();
+               final ArrayList<String> files = new ArrayList<>();
+               final LinkedList<String> argList = new LinkedList<>();
+               argList.addAll(Arrays.asList(args));
+               for (int i = 0; i < argList.size(); i++) {
+                       String arg = argList.get(i);
+                       List<String> aliases = aliasOptions(arg);
+                       if (!LangUtil.isEmpty(aliases)) {
+                               argList.remove(i);
+                               argList.addAll(i, aliases);
+                               i--;
+                               continue;
+                       }
+                       if ("-help".equals(arg)) {
+                               logln("java " + Harness.class.getName() + " {option|suiteFile}..");
+                               printSyntax(getLogStream());
+                               return;
+                       } else if (isSuiteFile(arg)) {
+                               files.add(arg);
+                       } else if (!acceptOption(arg)) {
+                               globals.add(arg);
+                       } // else our options absorbed
+               }
+               if (0 == files.size()) {
+                       logln("## Error reading arguments: at least 1 suite file required");
+                       logln("java " + Harness.class.getName() + " {option|suiteFile}..");
+                       printSyntax(getLogStream());
+                       return;
+               }
+               String[] globalOptions = globals.toArray(new String[0]);
+               String[][] globalOptionVariants = optionVariants(globalOptions);
+               AbstractRunSpec.RT runtime = new AbstractRunSpec.RT();
+               if (verboseHarness) {
+                       runtime.setVerbose(true);
+               }
+
+               // run suites read from each file
+               AjcTest.Suite.Spec spec;
+               for (String string : files) {
+                       File suiteFile = new File(string);
+                       if (!suiteFile.canRead()) {
+                               logln("runMain(..) cannot read file: " + suiteFile);
+                               continue;
+                       }
+                       if (null == (spec = readSuite(suiteFile))) {
+                               logln("runMain(..) cannot read suite from file: " + suiteFile);
+                               continue;
+                       }
+
+                       MessageHandler holder = new MessageHandler();
+                       for (String[] globalOptionVariant : globalOptionVariants) {
+                               runtime.setOptions(globalOptionVariant);
+                               holder.init();
+                               boolean skip = !spec.adoptParentValues(runtime, holder);
+                               // awful/brittle assumption about number of skips == number of skip messages
+                               final List<IMessage> skipList = MessageUtil.getMessages(holder, IMessage.INFO, false, "skip");
+                               if ((verboseHarness || skip || (0 < skipList.size()))) {
+                                       final List<String> curArgs = Arrays.asList(globalOptionVariant);
                                        logln("runMain(" + suiteFile + ", " + curArgs + ")");
-                    if (verboseHarness) {
-                        String format = "yyyy.MM.dd G 'at' hh:mm:ss a zzz";
-                        SimpleDateFormat formatter = new SimpleDateFormat (format);
-                        String date = formatter.format(new Date());
-                        logln("test date: " + date);
-                        logln("harness features: " + listFeatureNames());
-                        logln("Java version: " + JAVA_VERSION);
-                        logln("AspectJ version: " + ASPECTJ_VERSION);
-                    }
-                    if (!(quietHarness || silentHarness) && holder.hasAnyMessage(null, true)) {
-                        MessageUtil.print(getLogStream(), holder, "skip - ");
-                        MessageUtil.printMessageCounts(getLogStream(), holder, "skip - ");
-                    }
-                }
-                if (!skip) {
-                    doStartSuite(suiteFile);
-                    long elapsed = 0;
-                    RunResult result = null;
-                    try {
-                        final long startTime = System.currentTimeMillis();
-                        result = run(spec);
-                        if (null != resultList) {
-                            resultList.add(result);
-                        }
-                        elapsed = System.currentTimeMillis() - startTime;
-                        report(result.status, skipList.size(), result.numIncomplete, elapsed);
-                    } finally {
-                        doEndSuite(suiteFile,elapsed);
-                    }
-                    if (exitOnFailure) {
-                        int numFailures = RunUtils.numFailures(result.status, true);
-                        if (0 < numFailures) {
-                            System.exit(numFailures);
-                        }
-                        Object value = result.status.getResult();
-                        if ((value instanceof Boolean)
-                                && !((Boolean) value).booleanValue()) {
-                            System.exit(-1);
-                        }
-                    }
-                }
-            }
-               }
-    }
+                                       if (verboseHarness) {
+                                               String format = "yyyy.MM.dd G 'at' hh:mm:ss a zzz";
+                                               SimpleDateFormat formatter = new SimpleDateFormat (format);
+                                               String date = formatter.format(new Date());
+                                               logln("test date: " + date);
+                                               logln("harness features: " + listFeatureNames());
+                                               logln("Java version: " + JAVA_VERSION);
+                                               logln("AspectJ version: " + ASPECTJ_VERSION);
+                                       }
+                                       if (!(quietHarness || silentHarness) && holder.hasAnyMessage(null, true)) {
+                                               MessageUtil.print(getLogStream(), holder, "skip - ");
+                                               MessageUtil.printMessageCounts(getLogStream(), holder, "skip - ");
+                                       }
+                               }
+                               if (!skip) {
+                                       doStartSuite(suiteFile);
+                                       long elapsed = 0;
+                                       RunResult result = null;
+                                       try {
+                                               final long startTime = System.currentTimeMillis();
+                                               result = run(spec);
+                                               if (null != resultList) {
+                                                       resultList.add(result);
+                                               }
+                                               elapsed = System.currentTimeMillis() - startTime;
+                                               report(result.status, skipList.size(), result.numIncomplete, elapsed);
+                                       } finally {
+                                               doEndSuite(suiteFile,elapsed);
+                                       }
+                                       if (exitOnFailure) {
+                                               int numFailures = RunUtils.numFailures(result.status, true);
+                                               if (0 < numFailures) {
+                                                       System.exit(numFailures);
+                                               }
+                                               Object value = result.status.getResult();
+                                               if ((value instanceof Boolean)
+                                                               && !((Boolean) value).booleanValue()) {
+                                                       System.exit(-1);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
 
 
        /**
@@ -328,72 +330,71 @@ public class Harness {
                        }
                }
        }
-    /**
-     * Generate variants of String[] options by creating an extra set for
-     * each option that ends with "-".  If none end with "-", then an
-     * array equal to <code>new String[][] { options }</code> is returned;
-     * if one ends with "-", then two sets are returned,
-     * three causes eight sets, etc.
-     * @return String[][] with each option set.
-     * @throws IllegalArgumentException if any option is null or empty.
-     */
-    public static String[][] optionVariants(String[] options) {
-        if ((null == options) || (0 == options.length)) {
-            return new String[][] { new String[0]};
-        }
-        // be nice, don't stomp input
-        String[] temp = new String[options.length];
-        System.arraycopy(options, 0, temp, 0, temp.length);
-        options = temp;
-        boolean[] dup = new boolean[options.length];
-        int numDups = 0;
-
-        for (int i = 0; i < options.length; i++) {
-            String option = options[i];
-            if (LangUtil.isEmpty(option)) {
-                throw new IllegalArgumentException("empty option at " + i);
-            }
-            if (option.endsWith("-")) {
-                options[i] = option.substring(0, option.length()-1);
-                dup[i] = true;
-                numDups++;
-            }
-        }
-        final String[] NONE = new String[0];
-        final int variants = exp(2, numDups);
-        final String[][] result = new String[variants][];
-        // variant is a bitmap wrt doing extra value when dup[k]=true
-        for (int variant = 0; variant < variants; variant++) {
-            ArrayList<String> next = new ArrayList<>();
-            int nextOption = 0;
-            for (int k = 0; k < options.length; k++) {
-                if (!dup[k] || (0 != (variant & (1 << (nextOption++))))) {
-                    next.add(options[k]);
-                }
-            }
-            result[variant] = next.toArray(NONE);
-        }
-        return result;
-    }
-
-    private static int exp(int base, int power) { // not in Math?
-        if (0 > power) {
-            throw new IllegalArgumentException("negative power: " + power);
-        }
-        int result = 1;
-        while (0 < power--) {
-            result *= base;
-        }
-        return result;
-    }
+       /**
+        * Generate variants of String[] options by creating an extra set for
+        * each option that ends with "-".  If none end with "-", then an
+        * array equal to <code>new String[][] { options }</code> is returned;
+        * if one ends with "-", then two sets are returned,
+        * three causes eight sets, etc.
+        * @return String[][] with each option set.
+        * @throws IllegalArgumentException if any option is null or empty.
+        */
+       public static String[][] optionVariants(String[] options) {
+               if ((null == options) || (0 == options.length)) {
+                       return new String[][] { new String[0]};
+               }
+               // be nice, don't stomp input
+               String[] temp = new String[options.length];
+               System.arraycopy(options, 0, temp, 0, temp.length);
+               options = temp;
+               boolean[] dup = new boolean[options.length];
+               int numDups = 0;
+
+               for (int i = 0; i < options.length; i++) {
+                       String option = options[i];
+                       if (LangUtil.isEmpty(option)) {
+                               throw new IllegalArgumentException("empty option at " + i);
+                       }
+                       if (option.endsWith("-")) {
+                               options[i] = option.substring(0, option.length()-1);
+                               dup[i] = true;
+                               numDups++;
+                       }
+               }
+               final String[] NONE = new String[0];
+               final int variants = exp(2, numDups);
+               final String[][] result = new String[variants][];
+               // variant is a bitmap wrt doing extra value when dup[k]=true
+               for (int variant = 0; variant < variants; variant++) {
+                       ArrayList<String> next = new ArrayList<>();
+                       int nextOption = 0;
+                       for (int k = 0; k < options.length; k++) {
+                               if (!dup[k] || (0 != (variant & (1 << (nextOption++))))) {
+                                       next.add(options[k]);
+                               }
+                       }
+                       result[variant] = next.toArray(NONE);
+               }
+               return result;
+       }
+
+       private static int exp(int base, int power) { // not in Math?
+               if (0 > power) {
+                       throw new IllegalArgumentException("negative power: " + power);
+               }
+               int result = 1;
+               while (0 < power--) {
+                       result *= base;
+               }
+               return result;
+       }
 
        /**
         * @param suiteFile
         */
        private void doStartSuite(File suiteFile) {
-               Collection c = features.values();
-               for (Iterator iter = c.iterator(); iter.hasNext();) {
-                       Feature element = (Feature) iter.next();
+               Collection<Feature> c = features.values();
+               for (Feature element : c) {
                        if (element.listener instanceof TestCompleteListener) {
                                ((TestCompleteListener)element.listener).doStartSuite(suiteFile);
                        }
@@ -401,271 +402,271 @@ public class Harness {
        }
 
        /** Run the test suite specified by the spec */
-    protected RunResult run(AjcTest.Suite.Spec spec) {
-        LangUtil.throwIaxIfNull(spec, "spec");
-        /*
-         * For each run, initialize the runner and validator,
-         * create a new set of IRun{Iterator} tests,
-         * and run them.
-         * Delete all temp files when done.
-         */
-        Runner runner = new Runner();
-        if (0 != features.size()) {
-            for (Iterator<Map.Entry<String,Feature>> iter = features.entrySet().iterator(); iter.hasNext();) {
-                Feature feature = iter.next().getValue();
-                runner.registerListener(feature.clazz, feature.listener);
-            }
-        }
-        IMessageHolder holder = new MessageHandler();
-        int numIncomplete = 0;
-        RunStatus status = new RunStatus(holder, runner);
-        status.setIdentifier(spec);
-        // validator is used for all setup in entire tree...
-        Validator validator = new Validator(status);
-        if (!killTemp) {
-            validator.lock(this);
-        }
-        Sandbox sandbox = null;
-        try {
-            sandbox = new Sandbox(spec.getSuiteDirFile(), validator);
-            IRunIterator tests = spec.makeRunIterator(sandbox, validator);
-            runner.runIterator(tests, status, null);
-            if (tests instanceof RunSpecIterator) {
-                numIncomplete = ((RunSpecIterator) tests).getNumIncomplete();
-            }
-        } finally {
-               if (!keepTemp) {
-                if (!killTemp) {
-                    validator.unlock(this);
-                }
-                   validator.deleteTempFiles(verboseHarness);
-               }
-        }
-        return new RunResult(status, numIncomplete);
-    }
-
-    /**
-     * Report the results of a test run after it is completed.
-     * Clients should be able to identify the number of:
-     * <ul>
-     * <li>tests run and passed</li>
-     * <li>tests failed, i.e., run and not passed (fail, error, etc.)</li>
-     * <li>tests incomplete, i.e., test definition read but test run setup failed</li>
-     * <li>tests skipped, i.e., test definition read and found incompatible with
-     *     the current configuration.</li>
-     * <ul>
-     *
-     * @param status returned from the run
-     * @param numSkipped int tests that were skipped because of
-     *         configuration incompatibilities
-     * @param numIncomplete int tests that failed during setup,
-     *         usually indicating a test definition or configuration error.
-     * @param msElapsed elapsed time in milliseconds
-     * */
-    protected void report(IRunStatus status, int numSkipped, int numIncomplete,
-        long msElapsed ) {
-       if (logResults) {
-            RunUtils.AJCSUITE_PRINTER.printRunStatus(getLogStream(), status);
-        } else if (!(quietHarness || silentHarness) && (0 < status.numMessages(null, true))) {
-               if (!silentHarness) {
-               MessageUtil.print(getLogStream(), status, "");
-               }
-        }
-
-               logln(BridgeUtil.childString(status, numSkipped, numIncomplete)
-            + " " + (msElapsed/1000) + " seconds");
-
-    }
-
-    // --------------- delegate methods
-    protected void logln(String s) {
-       if (!silentHarness) {
-               getLogStream().println(s);
-       }
-    }
-
-    protected PrintStream getLogStream() {
-        return System.out;
-    }
-
-    protected boolean isSuiteFile(String arg) {
-        return ((null != arg)
-                && (arg.endsWith(".txt") || arg.endsWith(".xml"))
-                && new File(arg).canRead());
-    }
-
-    /**
-     * Get the options that the input option is an alias for.
-     * Subclasses may add options directly to the getFeatureAliases result
-     * or override this.
-     * @return null if the input is not an alias for other options,
-     * or a non-empty List (String) of options that this option is an alias for
-     */
-    protected List<String> aliasOptions(String option) {
-        Properties aliases = Harness.getOptionAliases();
-        if (null != aliases) {
-            String args = aliases.getProperty(option);
-            if (!LangUtil.isEmpty(args)) {
-                return LangUtil.anySplit(args, OPTION_DELIM);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Read and implement any of our options.
-     * Options other than this and suite files will be
-     * passed down as parent options through the test spec hierarchy.
-     * Subclasses override this to implement new options.
-     */
-    protected boolean acceptOption(String option) {
-//        boolean result = false;
-        if (LangUtil.isEmpty(option)) {
-            return true; // skip bad input
-        } else if ("-verboseHarness".equals(option)) {
-            verboseHarness = true;
+       protected RunResult run(AjcTest.Suite.Spec spec) {
+               LangUtil.throwIaxIfNull(spec, "spec");
+               /*
+                * For each run, initialize the runner and validator,
+                * create a new set of IRun{Iterator} tests,
+                * and run them.
+                * Delete all temp files when done.
+                */
+               Runner runner = new Runner();
+               if (0 != features.size()) {
+                       for (Entry<String, Feature> entry : features.entrySet()) {
+                               Feature feature = entry.getValue();
+                               runner.registerListener(feature.clazz, feature.listener);
+                       }
+               }
+               IMessageHolder holder = new MessageHandler();
+               int numIncomplete = 0;
+               RunStatus status = new RunStatus(holder, runner);
+               status.setIdentifier(spec);
+               // validator is used for all setup in entire tree...
+               Validator validator = new Validator(status);
+               if (!killTemp) {
+                       validator.lock(this);
+               }
+               Sandbox sandbox = null;
+               try {
+                       sandbox = new Sandbox(spec.getSuiteDirFile(), validator);
+                       IRunIterator tests = spec.makeRunIterator(sandbox, validator);
+                       runner.runIterator(tests, status, null);
+                       if (tests instanceof RunSpecIterator) {
+                               numIncomplete = ((RunSpecIterator) tests).getNumIncomplete();
+                       }
+               } finally {
+                       if (!keepTemp) {
+                               if (!killTemp) {
+                                       validator.unlock(this);
+                               }
+                               validator.deleteTempFiles(verboseHarness);
+                       }
+               }
+               return new RunResult(status, numIncomplete);
+       }
+
+       /**
+        * Report the results of a test run after it is completed.
+        * Clients should be able to identify the number of:
+        * <ul>
+        * <li>tests run and passed</li>
+        * <li>tests failed, i.e., run and not passed (fail, error, etc.)</li>
+        * <li>tests incomplete, i.e., test definition read but test run setup failed</li>
+        * <li>tests skipped, i.e., test definition read and found incompatible with
+        *     the current configuration.</li>
+        * <ul>
+        *
+        * @param status returned from the run
+        * @param numSkipped int tests that were skipped because of
+        *         configuration incompatibilities
+        * @param numIncomplete int tests that failed during setup,
+        *         usually indicating a test definition or configuration error.
+        * @param msElapsed elapsed time in milliseconds
+        * */
+       protected void report(IRunStatus status, int numSkipped, int numIncomplete,
+                       long msElapsed ) {
+               if (logResults) {
+                       RunUtils.AJCSUITE_PRINTER.printRunStatus(getLogStream(), status);
+               } else if (!(quietHarness || silentHarness) && (0 < status.numMessages(null, true))) {
+                       if (!silentHarness) {
+                               MessageUtil.print(getLogStream(), status, "");
+                       }
+               }
+
+               logln(BridgeUtil.childString(status, numSkipped, numIncomplete)
+                               + " " + (msElapsed/1000) + " seconds");
+
+       }
+
+       // --------------- delegate methods
+       protected void logln(String s) {
+               if (!silentHarness) {
+                       getLogStream().println(s);
+               }
+       }
+
+       protected PrintStream getLogStream() {
+               return System.out;
+       }
+
+       protected boolean isSuiteFile(String arg) {
+               return ((null != arg)
+                               && (arg.endsWith(".txt") || arg.endsWith(".xml"))
+                               && new File(arg).canRead());
+       }
+
+       /**
+        * Get the options that the input option is an alias for.
+        * Subclasses may add options directly to the getFeatureAliases result
+        * or override this.
+        * @return null if the input is not an alias for other options,
+        * or a non-empty List (String) of options that this option is an alias for
+        */
+       protected List<String> aliasOptions(String option) {
+               Properties aliases = Harness.getOptionAliases();
+               if (null != aliases) {
+                       String args = aliases.getProperty(option);
+                       if (!LangUtil.isEmpty(args)) {
+                               return LangUtil.anySplit(args, OPTION_DELIM);
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Read and implement any of our options.
+        * Options other than this and suite files will be
+        * passed down as parent options through the test spec hierarchy.
+        * Subclasses override this to implement new options.
+        */
+       protected boolean acceptOption(String option) {
+               //        boolean result = false;
+               if (LangUtil.isEmpty(option)) {
+                       return true; // skip bad input
+               } else if ("-verboseHarness".equals(option)) {
+                       verboseHarness = true;
                } else if ("-quietHarness".equals(option)) {
                        quietHarness = true;
                } else if ("-silentHarness".equals(option)) {
                        silentHarness = true;
-        } else if ("-keepTemp".equals(option)) {
-            keepTemp = true;
-        } else if ("-killTemp".equals(option)) {
-            killTemp = true;
-        } else if ("-logResults".equals(option)) {
-            logResults = true;
-        } else if ("-exitOnFailure".equals(option)) {
-            exitOnFailure = true;
-        } else {
-               return false;
-        }
-        return true;
-    }
-
-    /**
-     * Read a test suite file.
-     * This implementation knows how to read .txt and .xml files
-     * and logs any errors.
-     * Subclasses override this to read new kinds of suites.
-     * @return null if unable to read (logging errors) or AjcTest.Suite.Spec otherwise
-     */
-    protected AjcTest.Suite.Spec readSuite(File suiteFile) {
-        if (null != suiteFile) {
-            String path = suiteFile.getPath();
-            try {
-                if (path.endsWith(".xml")) {
-                    return AjcSpecXmlReader.getReader().readAjcSuite(suiteFile);
-                } else if (path.endsWith(".txt")) {
-                    return FlatSuiteReader.ME.readSuite(suiteFile);
-                } else {
-                    logln("unrecognized extension? " + path);
-                }
-            } catch (IOException e) {
-                e.printStackTrace(getLogStream());
-            }
-        }
-        return null;
-    }
-
-    /** Add feature to take effect during the next runMain(..) invocation.
-     * @param feature the Feature to add, using feature.name as key.
-     */
-    protected void addFeature(Feature feature) {
-        if (null != feature) {
-            features.put(feature.name, feature);
-        }
-    }
-
-    /** remove feature by name (same as feature.name) */
-    protected void removeFeature(String name) {
-        if (!LangUtil.isEmpty(name)) {
-            features.remove(name);
-        }
-    }
-
-    /** @return unmodifiable Set of feature names */
-    protected Set listFeatureNames() {
-        return Collections.unmodifiableSet(features.keySet());
-    }
-
-    /** print detail message for syntax of main(String[]) command-line */
-    protected void printSyntax(PrintStream out) {
-        out.println("  {??}              unrecognized options are used as test spec globals");
-        out.println("  -help             print this help message");
-        out.println("  -verboseHarness   harness components log verbosely");
-        out.println("  -quietHarness     harness components suppress logging");
-        out.println("  -keepTemp         do not delete temporary files");
-        out.println("  -logResults       log results at end, verbosely if fail");
-        out.println("  -exitOnFailure    do System.exit({num-failures}) if suite fails");
-        out.println("  {suiteFile}.xml.. specify test suite XML file");
-        out.println("  {suiteFile}.txt.. specify test suite .txt file (deprecated)");
-    }
-
-    /** print known aliases at the end of the syntax message */
-    protected void printAliases(PrintStream out) {
-        LangUtil.throwIaxIfNull(out, "out");
-        Properties props = getOptionAliases();
-        if (null == props) {
-            return;
-        }
-        int pdLength = SYNTAX_PAD.length();
-        Set entries = props.entrySet();
-        for (Iterator iter = entries.iterator(); iter.hasNext();) {
-                       Map.Entry entry = (Map.Entry) iter.next();
+               } else if ("-keepTemp".equals(option)) {
+                       keepTemp = true;
+               } else if ("-killTemp".equals(option)) {
+                       killTemp = true;
+               } else if ("-logResults".equals(option)) {
+                       logResults = true;
+               } else if ("-exitOnFailure".equals(option)) {
+                       exitOnFailure = true;
+               } else {
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * Read a test suite file.
+        * This implementation knows how to read .txt and .xml files
+        * and logs any errors.
+        * Subclasses override this to read new kinds of suites.
+        * @return null if unable to read (logging errors) or AjcTest.Suite.Spec otherwise
+        */
+       protected AjcTest.Suite.Spec readSuite(File suiteFile) {
+               if (null != suiteFile) {
+                       String path = suiteFile.getPath();
+                       try {
+                               if (path.endsWith(".xml")) {
+                                       return AjcSpecXmlReader.getReader().readAjcSuite(suiteFile);
+                               } else if (path.endsWith(".txt")) {
+                                       return FlatSuiteReader.ME.readSuite(suiteFile);
+                               } else {
+                                       logln("unrecognized extension? " + path);
+                               }
+                       } catch (IOException e) {
+                               e.printStackTrace(getLogStream());
+                       }
+               }
+               return null;
+       }
+
+       /** Add feature to take effect during the next runMain(..) invocation.
+        * @param feature the Feature to add, using feature.name as key.
+        */
+       protected void addFeature(Feature feature) {
+               if (null != feature) {
+                       features.put(feature.name, feature);
+               }
+       }
+
+       /** remove feature by name (same as feature.name) */
+       protected void removeFeature(String name) {
+               if (!LangUtil.isEmpty(name)) {
+                       features.remove(name);
+               }
+       }
+
+       /** @return unmodifiable Set of feature names */
+       protected Set listFeatureNames() {
+               return Collections.unmodifiableSet(features.keySet());
+       }
+
+       /** print detail message for syntax of main(String[]) command-line */
+       protected void printSyntax(PrintStream out) {
+               out.println("  {??}              unrecognized options are used as test spec globals");
+               out.println("  -help             print this help message");
+               out.println("  -verboseHarness   harness components log verbosely");
+               out.println("  -quietHarness     harness components suppress logging");
+               out.println("  -keepTemp         do not delete temporary files");
+               out.println("  -logResults       log results at end, verbosely if fail");
+               out.println("  -exitOnFailure    do System.exit({num-failures}) if suite fails");
+               out.println("  {suiteFile}.xml.. specify test suite XML file");
+               out.println("  {suiteFile}.txt.. specify test suite .txt file (deprecated)");
+       }
+
+       /** print known aliases at the end of the syntax message */
+       protected void printAliases(PrintStream out) {
+               LangUtil.throwIaxIfNull(out, "out");
+               Properties props = getOptionAliases();
+               if (null == props) {
+                       return;
+               }
+               int pdLength = SYNTAX_PAD.length();
+               Set<Map.Entry<Object,Object>> entries = props.entrySet();
+               for (Map.Entry<Object,Object> entry : entries) {
                        String alias = "  " + (String) entry.getKey();
-            int buf = pdLength - alias.length();
-            if (0 < buf) {
-                alias += SYNTAX_PAD.substring(0, buf);
-            } else {
-                alias += " ";
-            }
-            out.println(alias + entry.getValue());
-        }
-    }
-
-    /** result struct for run(AjcTest.Spec) */
-    public static class RunResult {
-        public final IRunStatus status;
-        public final int numIncomplete;
-        public RunResult(IRunStatus status, int numIncomplete) {
-            this.status = status;
-            this.numIncomplete = numIncomplete;
-        }
-    }
-    /** feature implemented as named IRunIterator/IRun association */
-    public static class Feature {
-        /** never null, always assignable to IRun */
-        public final Class clazz;
-
-        /** never null */
-        public final IRunListener listener;
-
-        /** never null or empty */
-        public final String name;
-
-        /** @throws IllegalArgumentException if any is null/empty or clazz is
-         *           not assignable to IRun
-         */
-        public Feature(String name, Class clazz, IRunListener listener) {
-            LangUtil.throwIaxIfNull(clazz, "class");
-            if (!IRun.class.isAssignableFrom(clazz)
-                && !IRunIterator.class.isAssignableFrom(clazz)) {
-                String s = clazz.getName() + "is not assignable to IRun or IRunIterator";
-                LangUtil.throwIaxIfFalse(false, s);
-            }
-            LangUtil.throwIaxIfNull(listener, "listener");
-            LangUtil.throwIaxIfNull(name, "name");
-            LangUtil.throwIaxIfFalse(0 < name.length(), "empty name");
-            this.clazz = clazz;
-            this.listener = listener;
-            this.name = name;
-        }
-
-        /** @return feature name */
-        public String toString() {
-            return name;
-        }
-    }
+                       int buf = pdLength - alias.length();
+                       if (0 < buf) {
+                               alias += SYNTAX_PAD.substring(0, buf);
+                       } else {
+                               alias += " ";
+                       }
+                       out.println(alias + entry.getValue());
+               }
+       }
+
+       /** result struct for run(AjcTest.Spec) */
+       public static class RunResult {
+               public final IRunStatus status;
+               public final int numIncomplete;
+               public RunResult(IRunStatus status, int numIncomplete) {
+                       this.status = status;
+                       this.numIncomplete = numIncomplete;
+               }
+       }
+       /** feature implemented as named IRunIterator/IRun association */
+       public static class Feature {
+               /** never null, always assignable to IRun */
+               public final Class clazz;
+
+               /** never null */
+               public final IRunListener listener;
+
+               /** never null or empty */
+               public final String name;
+
+               /** @throws IllegalArgumentException if any is null/empty or clazz is
+                *           not assignable to IRun
+                */
+               public Feature(String name, Class clazz, IRunListener listener) {
+                       LangUtil.throwIaxIfNull(clazz, "class");
+                       if (!IRun.class.isAssignableFrom(clazz)
+                                       && !IRunIterator.class.isAssignableFrom(clazz)) {
+                               String s = clazz.getName() + "is not assignable to IRun or IRunIterator";
+                               LangUtil.throwIaxIfFalse(false, s);
+                       }
+                       LangUtil.throwIaxIfNull(listener, "listener");
+                       LangUtil.throwIaxIfNull(name, "name");
+                       LangUtil.throwIaxIfFalse(0 < name.length(), "empty name");
+                       this.clazz = clazz;
+                       this.listener = listener;
+                       this.name = name;
+               }
+
+               /** @return feature name */
+               @Override
+               public String toString() {
+                       return name;
+               }
+       }
 }
 
 
@@ -676,323 +677,333 @@ public class Harness {
  */
 class FeatureHarness extends Harness {
 
-    private static final String[] ALIASES = new String[]
-        { "-hideStreams",
-            "-hideCompilerStreams"
-            + OPTION_DELIM + "-hideRunStreams",
-          "-jim",
-            "-logMinFail"
-            + OPTION_DELIM + "-hideStreams",
-          "-loud",
-            "-verboseHarness",
-          "-baseline",
-            "-verboseHarness"
-            + OPTION_DELIM + "-traceTestsMin"
-            + OPTION_DELIM + "-hideStreams",
-          "-release",
-              "-baseline"
-              + OPTION_DELIM + "-ajctestSkipKeywords=knownLimitation,purejava",
-          "-junit",
-                 "-silentHarness" + OPTION_DELIM + "-logJUnit" + OPTION_DELIM +
-                 "-hideStreams",
-          "-cruisecontrol",
-                 "-junit" + OPTION_DELIM + "-ajctestSkipKeywords=knownLimitation,purejava"
-        };
-    static {
-        Properties optionAliases = Harness.getOptionAliases();
-        if (null != optionAliases) {
-            for (int i = 1; i < ALIASES.length; i += 2) {
-                optionAliases.put(ALIASES[i-1], ALIASES[i]);
+       private static final String[] ALIASES = new String[]
+                       { "-hideStreams",
+                                       "-hideCompilerStreams"
+                                                       + OPTION_DELIM + "-hideRunStreams",
+                                                       "-jim",
+                                                       "-logMinFail"
+                                                                       + OPTION_DELIM + "-hideStreams",
+                                                                       "-loud",
+                                                                       "-verboseHarness",
+                                                                       "-baseline",
+                                                                       "-verboseHarness"
+                                                                                       + OPTION_DELIM + "-traceTestsMin"
+                                                                                       + OPTION_DELIM + "-hideStreams",
+                                                                                       "-release",
+                                                                                       "-baseline"
+                                                                                                       + OPTION_DELIM + "-ajctestSkipKeywords=knownLimitation,purejava",
+                                                                                                       "-junit",
+                                                                                                       "-silentHarness" + OPTION_DELIM + "-logJUnit" + OPTION_DELIM +
+                                                                                                       "-hideStreams",
+                                                                                                       "-cruisecontrol",
+                                                                                                       "-junit" + OPTION_DELIM + "-ajctestSkipKeywords=knownLimitation,purejava"
+                       };
+       static {
+               Properties optionAliases = Harness.getOptionAliases();
+               if (null != optionAliases) {
+                       for (int i = 1; i < ALIASES.length; i += 2) {
+                               optionAliases.put(ALIASES[i-1], ALIASES[i]);
                        }
-        }
-    }
-
-    /** controller for suppressing and sniffing error and output streams. */
-    StreamsHandler streamsHandler;
-
-    /** facility of hiding-streams may be applied in many features */
-    IRunListener streamHider;
-
-    /** facility of capture/log may be applied in many features */
-    IRunListener captureLogger;
-
-    /** when making tests, do not run them */
-    TestMaker testMaker;
-
-    public FeatureHarness() {
-        super();
-        streamsHandler = new StreamsHandler(false, true);
-    }
-    /** override to make tests or run as usual */
-    protected RunResult run(AjcTest.Suite.Spec spec) {
-        if (null != testMaker) {
-            System.out.println("generating rather than running tests...");
-            return testMaker.run(spec);
-        } else {
-            return super.run(spec);
-        }
-    }
-
-    /**
-     * Log via StreamsHandler-designated log stream.
-     * @see org.aspectj.testing.drivers.Harness#log(String)
+               }
+       }
+
+       /** controller for suppressing and sniffing error and output streams. */
+       StreamsHandler streamsHandler;
+
+       /** facility of hiding-streams may be applied in many features */
+       IRunListener streamHider;
+
+       /** facility of capture/log may be applied in many features */
+       IRunListener captureLogger;
+
+       /** when making tests, do not run them */
+       TestMaker testMaker;
+
+       public FeatureHarness() {
+               super();
+               streamsHandler = new StreamsHandler(false, true);
+       }
+       /** override to make tests or run as usual */
+       @Override
+       protected RunResult run(AjcTest.Suite.Spec spec) {
+               if (null != testMaker) {
+                       System.out.println("generating rather than running tests...");
+                       return testMaker.run(spec);
+               } else {
+                       return super.run(spec);
+               }
+       }
+
+       /**
+        * Log via StreamsHandler-designated log stream.
+        * @see org.aspectj.testing.drivers.Harness#log(String)
         */
+       @Override
        protected void logln(String s) {
                if (!silentHarness)
-               streamsHandler.lnlog(s);
+                       streamsHandler.lnlog(s);
        }
 
-    /**
+       /**
         * @see org.aspectj.testing.drivers.Harness#getLogStream()
-     * @return StreamsHandler-designated log stream.
+        * @return StreamsHandler-designated log stream.
         */
+       @Override
        protected PrintStream getLogStream() {
                return streamsHandler.out;
        }
 
 
-    /** print detail message for syntax of main(String[]) command-line */
-    protected void printSyntax(PrintStream out) {
-        super.printSyntax(out);
-        out.println("  -progressDots     log . or ! for each AjcTest pass or fail");
-        out.println("  -logFail          log each failed AjcTest");
-        out.println("  -logPass          log each passed AjcTest");
-        out.println("  -logAll           log each AjcTest");
-        out.println("  -logMinFail       log each AjcTest failure with minimal excess data");
-        out.println("  -logMinPass       log each AjcTest success with minimal excess data");
-        out.println("  -logMinAll        log all AjcTest with minimal excess data");
-        out.println("  -logXMLFail       log XML definition for each failed AjcTest");
-        out.println("  -logXMLPass       log XML definition for each passed AjcTest");
-        out.println("  -logXMLAll        log XML definition for each AjcTest");
-        out.println("  -logJUnit         log all tests in JUnit XML report style");
-        out.println("  -hideRunStreams   hide err/out streams during java runs");
-        out.println("  -hideCompilerStreams   hide err/out streams during compiler runs");
-        out.println("  -traceTests       log pass|fail, /time/memory taken after each test");
-        out.println("  -traceTestsMin    log pass|fail after each test");
-        out.println("  -XmakeTests       create source files/dirs for initial compile run of each test");
-        out.println("  -XlogPublicType   log test XML if \"public type\" in an error message");
-        out.println("  -XlogSourceIn=Y,Z log test XML if Y or Z is in path of any sources");
-        super.printAliases(out);
-    }
-
-    /** Accept a number of logging and output options */
+       /** print detail message for syntax of main(String[]) command-line */
+       @Override
+       protected void printSyntax(PrintStream out) {
+               super.printSyntax(out);
+               out.println("  -progressDots     log . or ! for each AjcTest pass or fail");
+               out.println("  -logFail          log each failed AjcTest");
+               out.println("  -logPass          log each passed AjcTest");
+               out.println("  -logAll           log each AjcTest");
+               out.println("  -logMinFail       log each AjcTest failure with minimal excess data");
+               out.println("  -logMinPass       log each AjcTest success with minimal excess data");
+               out.println("  -logMinAll        log all AjcTest with minimal excess data");
+               out.println("  -logXMLFail       log XML definition for each failed AjcTest");
+               out.println("  -logXMLPass       log XML definition for each passed AjcTest");
+               out.println("  -logXMLAll        log XML definition for each AjcTest");
+               out.println("  -logJUnit         log all tests in JUnit XML report style");
+               out.println("  -hideRunStreams   hide err/out streams during java runs");
+               out.println("  -hideCompilerStreams   hide err/out streams during compiler runs");
+               out.println("  -traceTests       log pass|fail, /time/memory taken after each test");
+               out.println("  -traceTestsMin    log pass|fail after each test");
+               out.println("  -XmakeTests       create source files/dirs for initial compile run of each test");
+               out.println("  -XlogPublicType   log test XML if \"public type\" in an error message");
+               out.println("  -XlogSourceIn=Y,Z log test XML if Y or Z is in path of any sources");
+               super.printAliases(out);
+       }
+
+       /** Accept a number of logging and output options */
+       @Override
        protected boolean acceptOption(String option) {
-        if (null == option) {
-            return false;
-        }
-
-        final StreamsHandler streams = streamsHandler;
-        final IRunValidator validator = RunValidator.NORMAL;
-        final RunUtils.IRunStatusPrinter verbose
-            = RunUtils.VERBOSE_PRINTER;
-        final RunUtils.IRunStatusPrinter terse
-            = RunUtils.TERSE_PRINTER;
-//        final boolean LOGPASS = true;
-//        final boolean LOGFAIL = true;
-//        final boolean SKIPPASS = false;
-//        final boolean SKIPFAIL = false;
-//        final boolean LOGSTREAMS = true;
-        final boolean SKIPSTREAMS = false;
+               if (null == option) {
+                       return false;
+               }
+
+               final StreamsHandler streams = streamsHandler;
+               final IRunValidator validator = RunValidator.NORMAL;
+               final RunUtils.IRunStatusPrinter verbose
+               = RunUtils.VERBOSE_PRINTER;
+               final RunUtils.IRunStatusPrinter terse
+               = RunUtils.TERSE_PRINTER;
+               //        final boolean LOGPASS = true;
+               //        final boolean LOGFAIL = true;
+               //        final boolean SKIPPASS = false;
+               //        final boolean SKIPFAIL = false;
+               //        final boolean LOGSTREAMS = true;
+               final boolean SKIPSTREAMS = false;
 
                Feature feature = null;
-        if (super.acceptOption(option)) {
-            // ok, result returned below
-
-        } else if ("-XmakeTests".equals(option)) {
-            testMaker = TestMaker.ME;
-        } else if (option.startsWith("-traceTestsMin")) {
-            feature = new Feature(option, AjcTest.class,new TestTraceLogger(streams, false));
-        } else if (option.startsWith("-traceTests")) {
-            feature = new Feature(option, AjcTest.class,new TestTraceLogger(streams, true));
-        } else if (option.startsWith("-logMin")) {
-            feature = new Feature(option, AjcTest.class,
-                new RunLogger(option, SKIPSTREAMS, streams, validator, terse));
-        } else if (option.startsWith("-logXML")) {
-            feature = new Feature(option, AjcTest.class,
-                new XmlLogger(option, streams, validator));
-        } else if (option.startsWith("-logJUnit")) {
-               feature = new Feature(option, AjcTest.class,
-                       new JUnitXMLLogger(option,streams,validator));
-        } else if (option.startsWith("-log")) {
-            feature = new Feature(option, AjcTest.class,
-                new RunLogger(option, SKIPSTREAMS, streams, validator, verbose));
-        } else if ("-hideRunStreams".equals(option)) {
-            feature = new Feature(option, JavaRun.class, getStreamHider());
-        } else if ("-hideCompilerStreams".equals(option)) {
-            addFeature(new Feature(option, IncCompilerRun.class, getStreamHider()));   // hmmm
-            feature = new Feature(option, CompilerRun.class, getStreamHider());
-        } else if ("-progressDots".equals(option)) {
-            IRunListener listener = new RunListener() {
+               if (super.acceptOption(option)) {
+                       // ok, result returned below
+
+               } else if ("-XmakeTests".equals(option)) {
+                       testMaker = TestMaker.ME;
+               } else if (option.startsWith("-traceTestsMin")) {
+                       feature = new Feature(option, AjcTest.class,new TestTraceLogger(streams, false));
+               } else if (option.startsWith("-traceTests")) {
+                       feature = new Feature(option, AjcTest.class,new TestTraceLogger(streams, true));
+               } else if (option.startsWith("-logMin")) {
+                       feature = new Feature(option, AjcTest.class,
+                                       new RunLogger(option, SKIPSTREAMS, streams, validator, terse));
+               } else if (option.startsWith("-logXML")) {
+                       feature = new Feature(option, AjcTest.class,
+                                       new XmlLogger(option, streams, validator));
+               } else if (option.startsWith("-logJUnit")) {
+                       feature = new Feature(option, AjcTest.class,
+                                       new JUnitXMLLogger(option,streams,validator));
+               } else if (option.startsWith("-log")) {
+                       feature = new Feature(option, AjcTest.class,
+                                       new RunLogger(option, SKIPSTREAMS, streams, validator, verbose));
+               } else if ("-hideRunStreams".equals(option)) {
+                       feature = new Feature(option, JavaRun.class, getStreamHider());
+               } else if ("-hideCompilerStreams".equals(option)) {
+                       addFeature(new Feature(option, IncCompilerRun.class, getStreamHider()));   // hmmm
+                       feature = new Feature(option, CompilerRun.class, getStreamHider());
+               } else if ("-progressDots".equals(option)) {
+                       IRunListener listener = new RunListener() {
+                               @Override
                                public void runCompleted(IRunStatus run) {
-                    streamsHandler.log((validator.runPassed(run) ? "." : "!"));
+                                       streamsHandler.log((validator.runPassed(run) ? "." : "!"));
                                }
-            };
-            feature = new Feature(option, AjcTest.class, listener);
-        } else if (option.startsWith("-XlogPublicType")) {
-            String label = option + TestCompleteListener.PASS; // print when validator true
-            feature = new Feature(option, AjcTest.class,
-                new XmlLogger(label, streams, MessageRunValidator.PUBLIC_TYPE_ERROR));
-        } else if (option.startsWith("-XlogSourceIn")) {
-            String input = option.substring("-XlogSourceIn=".length());
-            LangUtil.throwIaxIfFalse(0 < input.length(), option);
-            String label = "-XlogSourceIn="  + TestCompleteListener.PASS; // print when validator true
-            StringRunner sr = new SubstringRunner(input, false);
-            feature = new Feature(option, AjcTest.class,
-                new XmlLogger(label, streams, new SourcePathValidator(sr)));
-        } else {
-            return false;
-        }
-        addFeature(feature);
-        return true;
-       }
-
-    /** lazy construction for shared hider */
-    protected IRunListener getStreamHider() {
-        if (null == streamHider) {
-            streamHider =  new RunListener() {
-                public void runStarting(IRunStatus run) {
-                    streamsHandler.hide();
-                }
-                public void runCompleted(IRunStatus run) {
-                    streamsHandler.show();
-                }
-                public String toString() { return "Harness StreamHider"; }
-            };
-        }
-        return streamHider;
-    }
+                       };
+                       feature = new Feature(option, AjcTest.class, listener);
+               } else if (option.startsWith("-XlogPublicType")) {
+                       String label = option + TestCompleteListener.PASS; // print when validator true
+                       feature = new Feature(option, AjcTest.class,
+                                       new XmlLogger(label, streams, MessageRunValidator.PUBLIC_TYPE_ERROR));
+               } else if (option.startsWith("-XlogSourceIn")) {
+                       String input = option.substring("-XlogSourceIn=".length());
+                       LangUtil.throwIaxIfFalse(0 < input.length(), option);
+                       String label = "-XlogSourceIn="  + TestCompleteListener.PASS; // print when validator true
+                       StringRunner sr = new SubstringRunner(input, false);
+                       feature = new Feature(option, AjcTest.class,
+                                       new XmlLogger(label, streams, new SourcePathValidator(sr)));
+               } else {
+                       return false;
+               }
+               addFeature(feature);
+               return true;
+       }
+
+       /** lazy construction for shared hider */
+       protected IRunListener getStreamHider() {
+               if (null == streamHider) {
+                       streamHider =  new RunListener() {
+                               @Override
+                               public void runStarting(IRunStatus run) {
+                                       streamsHandler.hide();
+                               }
+                               @Override
+                               public void runCompleted(IRunStatus run) {
+                                       streamsHandler.show();
+                               }
+                               @Override
+                               public String toString() { return "Harness StreamHider"; }
+                       };
+               }
+               return streamHider;
+       }
 }
 
 /** Generate any needed test case files for any test. */
 class TestMaker  {
 
-    static TestMaker ME = new TestMaker();
-
-    /** @throws Error if unable to make dir */
-    static void mkdirs(File dir) {
-        if (null != dir && !dir.exists()) {
-            if (!dir.mkdirs()) {
-                throw new Error("unable to make dir: " + dir);
-            }
-        }
-    }
-    static String getFileContents(File baseDir, File file, String label) {
-        String fileName = file.getName();
-        if (fileName.endsWith(".java")) {
-            fileName = fileName.substring(0, fileName.length() - 5);
-        }
-        StringBuffer sb = new StringBuffer();
-        String filePath = file.getParentFile().getAbsolutePath();
-        String dirPath = baseDir.getAbsolutePath();
-        String pack = null;
-        if (filePath.startsWith(dirPath)) {
-            pack = filePath.substring(dirPath.length()).replace('/', '.');
-        }
-        if (!LangUtil.isEmpty(pack)) {
-           sb.append("package " + pack + ";");
-        }
-        final String EOL = "\n"; // XXX find discovered EOL
-        sb.append( EOL
-            + EOL + "import org.aspectj.testing.Tester;"
-            + EOL + ""
-            + EOL + "/** @testcase " + label + " */"
-            + EOL + "public class " + fileName + " {"
-            + EOL + "\tpublic static void main(String[] args) { "
-            + EOL + "\t\tTester.check(null != args, \"null args\"); "
-            + EOL + "\t}"
-            + EOL + "}"
-            + EOL
-            );
-
-        return sb.toString();
-    }
-
-    /** create a minimal source file for a test */
-    static void createSrcFile(File baseDir, File file, String testName) {
-        if (file.exists()) {
-            return;
-        }
-        String contents = getFileContents(baseDir, file, testName);
-        String error = FileUtil.writeAsString(file, contents);
-        if (null != error) {
-            throw new Error(error);
-        }
-    }
-
-    /** create an empty arg file for a test */
-    static void createArgFile(File baseDir, File file, String testName) {
-        if (file.exists()) {
-            return;
-        }
-        String contents = "// argfile " + file;
-        String error = FileUtil.writeAsString(file, contents);
-        if (null != error) {
-            throw new Error(error);
-        }
-    }
-
-    public Harness.RunResult run(AjcTest.Suite.Spec spec) {
-        ArrayList kids = spec.getChildren();
-        for (Iterator iter = kids.iterator(); iter.hasNext();) {
-                       makeTest( (AjcTest.Spec) iter.next());
-               }
-        IRunStatus status = new RunStatus(new MessageHandler(), new Runner());
-        status.start();
-        status.finish(IRunStatus.PASS);
-        return new Harness.RunResult(status, 0);
-    }
-
-    private void makeTest(AjcTest.Spec spec) {
-        CompilerRun.Spec compileSpec = AjcTest.unwrapCompilerRunSpec(spec);
-        if (null == spec) {
-            throw new Error("null spec");
-        }
-        System.out.println("  generating test files for test: " + spec.getDescription());
-        File dir = spec.getSuiteDir();
-        if (null != dir) {
-            TestMaker.mkdirs(dir);
-        }
-        String offset = spec.getTestDirOffset();
-        if (!LangUtil.isEmpty(offset)) {
-            if (null == dir) {
-                dir = new File(offset);
-            } else {
-                dir = new File(dir.getAbsolutePath() + "/" + offset);
-            }
-        } else if (null == dir) {
-            dir = new File(".");
-        }
-        StringBuffer testName = new StringBuffer();
-        int pr = spec.getBugId();
-        if (0 < pr) {
-            testName.append("PR#" + pr + " ");
-        }
-
-        testName.append(spec.getDescription());
-        final String label = testName.toString();
-        final File[] srcFiles = FileUtil.getBaseDirFiles(dir, compileSpec.getPathsArray());
-        if (!LangUtil.isEmpty(srcFiles)) {
-            for (int i = 0; i < srcFiles.length; i++) {
-                TestMaker.createSrcFile(dir, srcFiles[i], label);
-            }
-        }
-        final File[] argFiles = FileUtil.getBaseDirFiles(dir, compileSpec.getArgfilesArray());
-        if (!LangUtil.isEmpty(argFiles)) {
-            for (int i = 0; i < argFiles.length; i++) {
-                TestMaker.createArgFile(dir, argFiles[i], label);
-            }
-        }
-
-       }
-
-    /** @return "Testmaker()" */
-    public String toString() {
-        return "TestMaker()";
-    }
+       static TestMaker ME = new TestMaker();
+
+       /** @throws Error if unable to make dir */
+       static void mkdirs(File dir) {
+               if (null != dir && !dir.exists()) {
+                       if (!dir.mkdirs()) {
+                               throw new Error("unable to make dir: " + dir);
+                       }
+               }
+       }
+       static String getFileContents(File baseDir, File file, String label) {
+               String fileName = file.getName();
+               if (fileName.endsWith(".java")) {
+                       fileName = fileName.substring(0, fileName.length() - 5);
+               }
+               StringBuffer sb = new StringBuffer();
+               String filePath = file.getParentFile().getAbsolutePath();
+               String dirPath = baseDir.getAbsolutePath();
+               String pack = null;
+               if (filePath.startsWith(dirPath)) {
+                       pack = filePath.substring(dirPath.length()).replace('/', '.');
+               }
+               if (!LangUtil.isEmpty(pack)) {
+                       sb.append("package " + pack + ";");
+               }
+               final String EOL = "\n"; // XXX find discovered EOL
+               sb.append( EOL
+                               + EOL + "import org.aspectj.testing.Tester;"
+                               + EOL + ""
+                               + EOL + "/** @testcase " + label + " */"
+                               + EOL + "public class " + fileName + " {"
+                               + EOL + "\tpublic static void main(String[] args) { "
+                               + EOL + "\t\tTester.check(null != args, \"null args\"); "
+                               + EOL + "\t}"
+                               + EOL + "}"
+                               + EOL
+                               );
+
+               return sb.toString();
+       }
+
+       /** create a minimal source file for a test */
+       static void createSrcFile(File baseDir, File file, String testName) {
+               if (file.exists()) {
+                       return;
+               }
+               String contents = getFileContents(baseDir, file, testName);
+               String error = FileUtil.writeAsString(file, contents);
+               if (null != error) {
+                       throw new Error(error);
+               }
+       }
+
+       /** create an empty arg file for a test */
+       static void createArgFile(File baseDir, File file, String testName) {
+               if (file.exists()) {
+                       return;
+               }
+               String contents = "// argfile " + file;
+               String error = FileUtil.writeAsString(file, contents);
+               if (null != error) {
+                       throw new Error(error);
+               }
+       }
+
+       public Harness.RunResult run(AjcTest.Suite.Spec spec) {
+               ArrayList<IRunSpec> kids = spec.getChildren();
+               for (IRunSpec iRunSpec : kids) {
+                       makeTest( (AjcTest.Spec) iRunSpec);
+               }
+               IRunStatus status = new RunStatus(new MessageHandler(), new Runner());
+               status.start();
+               status.finish(IRunStatus.PASS);
+               return new Harness.RunResult(status, 0);
+       }
+
+       private void makeTest(AjcTest.Spec spec) {
+               CompilerRun.Spec compileSpec = AjcTest.unwrapCompilerRunSpec(spec);
+               if (null == spec) {
+                       throw new Error("null spec");
+               }
+               System.out.println("  generating test files for test: " + spec.getDescription());
+               File dir = spec.getSuiteDir();
+               if (null != dir) {
+                       TestMaker.mkdirs(dir);
+               }
+               String offset = spec.getTestDirOffset();
+               if (!LangUtil.isEmpty(offset)) {
+                       if (null == dir) {
+                               dir = new File(offset);
+                       } else {
+                               dir = new File(dir.getAbsolutePath() + "/" + offset);
+                       }
+               } else if (null == dir) {
+                       dir = new File(".");
+               }
+               StringBuffer testName = new StringBuffer();
+               int pr = spec.getBugId();
+               if (0 < pr) {
+                       testName.append("PR#" + pr + " ");
+               }
+
+               testName.append(spec.getDescription());
+               final String label = testName.toString();
+               final File[] srcFiles = FileUtil.getBaseDirFiles(dir, compileSpec.getPathsArray());
+               if (!LangUtil.isEmpty(srcFiles)) {
+                       for (File srcFile : srcFiles) {
+                               TestMaker.createSrcFile(dir, srcFile, label);
+                       }
+               }
+               final File[] argFiles = FileUtil.getBaseDirFiles(dir, compileSpec.getArgfilesArray());
+               if (!LangUtil.isEmpty(argFiles)) {
+                       for (File argFile : argFiles) {
+                               TestMaker.createArgFile(dir, argFile, label);
+                       }
+               }
+
+       }
+
+       /** @return "Testmaker()" */
+       @Override
+       public String toString() {
+               return "TestMaker()";
+       }
 }
 
 interface StringRunner {
-    boolean accept(String s);
+       boolean accept(String s);
 }
 
 /**
@@ -1000,56 +1011,57 @@ interface StringRunner {
  * optionally case-insensitive.
  */
 class SubstringRunner implements StringRunner {
-    private static String[] extractSubstrings(
-            String substrings,
-            boolean caseSensitive) {
-        if (null == substrings) {
-            return null;
-        }
-        StringTokenizer st = new StringTokenizer(substrings, ",");
-        String[] result = new String[st.countTokens()];
-        for (int i = 0; i < result.length; i++) {
+       private static String[] extractSubstrings(
+                       String substrings,
+                       boolean caseSensitive) {
+               if (null == substrings) {
+                       return null;
+               }
+               StringTokenizer st = new StringTokenizer(substrings, ",");
+               String[] result = new String[st.countTokens()];
+               for (int i = 0; i < result.length; i++) {
                        result[i] = st.nextToken().trim();
-                   LangUtil.throwIaxIfFalse(0 < result[i].length(), "empty entry");
-            if (!caseSensitive) {
-                result[i] = result[i].toLowerCase();
-            }
-        }
-        return result;
-    }
-
-    private final String[] substrings;
-    private final boolean caseSensitive;
-
-    /**
-     * @param substrings the String containing comma-separated substrings
-     *                    to find in input - if null, any input accepted
-     * @param caseSensitive if true, do case-sensitive comparison
-     * @throws IllegalArgumentException if any substrings contains empty entry ", ,"
-     */
-    SubstringRunner(String substrings, boolean caseSensitive) {
-        this.caseSensitive = caseSensitive;
-        this.substrings = extractSubstrings(substrings, caseSensitive);
-    }
-
-    public boolean accept(String input) {
-        if (null == substrings) {
-            return true;
-        }
-        if (null == input) {
-            return false;
-        }
-
-        if (!caseSensitive) {
-            input = input.toLowerCase();
-        }
-        for (int i = 0; i < substrings.length; i++) {
-                       if (-1 != input.indexOf(substrings[i])) {
-                return true;
-            }
-               }
-        return false;
-    }
+                       LangUtil.throwIaxIfFalse(0 < result[i].length(), "empty entry");
+                       if (!caseSensitive) {
+                               result[i] = result[i].toLowerCase();
+                       }
+               }
+               return result;
+       }
+
+       private final String[] substrings;
+       private final boolean caseSensitive;
+
+       /**
+        * @param substrings the String containing comma-separated substrings
+        *                    to find in input - if null, any input accepted
+        * @param caseSensitive if true, do case-sensitive comparison
+        * @throws IllegalArgumentException if any substrings contains empty entry ", ,"
+        */
+       SubstringRunner(String substrings, boolean caseSensitive) {
+               this.caseSensitive = caseSensitive;
+               this.substrings = extractSubstrings(substrings, caseSensitive);
+       }
+
+       @Override
+       public boolean accept(String input) {
+               if (null == substrings) {
+                       return true;
+               }
+               if (null == input) {
+                       return false;
+               }
+
+               if (!caseSensitive) {
+                       input = input.toLowerCase();
+               }
+               for (String substring : substrings) {
+                       if (-1 != input.indexOf(substring)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
 }
 
 /**
@@ -1057,30 +1069,31 @@ class SubstringRunner implements StringRunner {
  * (Static evaluation - no run necessary)
  */
 class SourcePathValidator implements IRunValidator { // static - no run needed
-    private final StringRunner validator;
-    // XXX hoist common
-    SourcePathValidator(StringRunner validator) {
-        LangUtil.throwIaxIfNull(validator, "validator");
-        this.validator = validator;
-    }
-    /**
-     * @return true if any source files in compile spec are
-     *          accepted by the validator.
+       private final StringRunner validator;
+       // XXX hoist common
+       SourcePathValidator(StringRunner validator) {
+               LangUtil.throwIaxIfNull(validator, "validator");
+               this.validator = validator;
+       }
+       /**
+        * @return true if any source files in compile spec are
+        *          accepted by the validator.
         * @see org.aspectj.testing.run.IRunValidator#runPassed(IRunStatus)
         */
+       @Override
        public boolean runPassed(IRunStatus run) {
-        AjcTest.Spec testSpec = AjcTest.unwrapSpec(run);
-        if (null != testSpec) {
-            CompilerRun.Spec compileSpec = AjcTest.unwrapCompilerRunSpec(testSpec);
-            File basedir = new File(testSpec.getSuiteDir(), testSpec.getTestDirOffset());
-            String[] paths = compileSpec.getPathsArray();
-            File[] files = FileUtil.getBaseDirFiles(basedir, paths);
-            for (int i = 0; i < files.length; i++) {
-                               if (validator.accept(files[i].getAbsolutePath())) {
-                    return true;
-                }
+               AjcTest.Spec testSpec = AjcTest.unwrapSpec(run);
+               if (null != testSpec) {
+                       CompilerRun.Spec compileSpec = AjcTest.unwrapCompilerRunSpec(testSpec);
+                       File basedir = new File(testSpec.getSuiteDir(), testSpec.getTestDirOffset());
+                       String[] paths = compileSpec.getPathsArray();
+                       File[] files = FileUtil.getBaseDirFiles(basedir, paths);
+                       for (File file : files) {
+                               if (validator.accept(file.getAbsolutePath())) {
+                                       return true;
+                               }
                        }
-        }
+               }
                return false;
        }
 
@@ -1089,65 +1102,65 @@ class SourcePathValidator implements IRunValidator { // static - no run needed
 /** Signal whether run "passed" based on message kind and content */
 class MessageRunValidator implements IRunValidator {
 
-    /** signals "passed" if any error contains "public type" */
-    static final IRunValidator PUBLIC_TYPE_ERROR
-        = new MessageRunValidator("public type", IMessage.ERROR, false);
-
-    private final IMessage.Kind kind;
-    private final String sought;
-    private final boolean orGreater;
-
-    /**
-     * @param sought the String to seek anywhere in any message of the right kind
-     *         if null, accept any message of the right kind.
-     * @param kind the IMessage.Kind of messages to search - all if null
-     */
-    MessageRunValidator(String sought, IMessage.Kind kind, boolean orGreater) {
-        this.sought = sought;
-        this.kind = kind;
-        this.orGreater = orGreater;
-    }
-
-    /** @return true if this run has messages of the right kind and text */
+       /** signals "passed" if any error contains "public type" */
+       static final IRunValidator PUBLIC_TYPE_ERROR
+       = new MessageRunValidator("public type", IMessage.ERROR, false);
+
+       private final IMessage.Kind kind;
+       private final String sought;
+       private final boolean orGreater;
+
+       /**
+        * @param sought the String to seek anywhere in any message of the right kind
+        *         if null, accept any message of the right kind.
+        * @param kind the IMessage.Kind of messages to search - all if null
+        */
+       MessageRunValidator(String sought, IMessage.Kind kind, boolean orGreater) {
+               this.sought = sought;
+               this.kind = kind;
+               this.orGreater = orGreater;
+       }
+
+       /** @return true if this run has messages of the right kind and text */
+       @Override
        public boolean runPassed(IRunStatus run) {
-        return gotMessage(new IRunStatus[] {run});
-    }
-
-    /**
-     * Search these children and their children recursively
-     * for messages of the right kind and content.
-     * @return true at first match of message of the right kind and content
-     */
-    private boolean gotMessage(IRunStatus[] children) {
-        if (LangUtil.isEmpty(children)) {
-            return false;
-        }
-        for (int i = 0; i < children.length; i++) {
-                       IRunStatus run = children[i];
-            if (null == run) {
-                continue; // hmm
-            }
-            IMessage[] messages = run.getMessages(kind, orGreater);
-            if (!LangUtil.isEmpty(messages)) {
-                if (LangUtil.isEmpty(sought)) {
-                    return true;
-                } else {
-                    for (int j = 0; j < messages.length; j++) {
-                        if (null == messages[j]) {
-                            continue; // hmm
-                        }
-                               String text = messages[j].getMessage();
-                        if ((null != text) && (-1 != text.indexOf(sought))) {
-                            return true;
-                        }
-                    }
-                }
-               }
-            if (gotMessage(run.getChildren())) {
-                return true;
-            }
-        }
-       return false;
+               return gotMessage(new IRunStatus[] {run});
+       }
+
+       /**
+        * Search these children and their children recursively
+        * for messages of the right kind and content.
+        * @return true at first match of message of the right kind and content
+        */
+       private boolean gotMessage(IRunStatus[] children) {
+               if (LangUtil.isEmpty(children)) {
+                       return false;
+               }
+               for (IRunStatus run : children) {
+                       if (null == run) {
+                               continue; // hmm
+                       }
+                       IMessage[] messages = run.getMessages(kind, orGreater);
+                       if (!LangUtil.isEmpty(messages)) {
+                               if (LangUtil.isEmpty(sought)) {
+                                       return true;
+                               } else {
+                                       for (IMessage message : messages) {
+                                               if (null == message) {
+                                                       continue; // hmm
+                                               }
+                                               String text = message.getMessage();
+                                               if ((null != text) && (-1 != text.indexOf(sought))) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       }
+                       if (gotMessage(run.getChildren())) {
+                               return true;
+                       }
+               }
+               return false;
        }
 }
 
@@ -1157,105 +1170,107 @@ class MessageRunValidator implements IRunValidator {
  * Subclasses implement doRunCompleted(..).
  */
 abstract class TestCompleteListener extends RunListener {
-    /** label suffix indicating both pass and fail */
-    public static final String ALL = "All";
-
-    /** label suffix indicating fail */
-    public static final String FAIL = "Fail";
-
-    /** label suffix indicating pass */
-    public static final String PASS = "Pass";
-
-
-    /** runValidator determines if a given run passed */
-    protected final IRunValidator runValidator;
-
-    /** label for this listener */
-    final String label;
-
-    /** if trun and run passed, then run doRunCompleted(..) */
-    final boolean logOnPass;
-
-    /** if true and run did not pass, then run doRunCompleted(..) */
-    final boolean logOnNotPass;
-
-    /** may be null */
-    protected final StreamsHandler streamsHandler;
-
-    /** true if the last run evaluation was ok */
-    boolean lastRunOk;
-
-    /** last run evaluated */
-    IRunStatus lastRun; // XXX small memory leak - cache hashcode instead?
-
-    /** @param label endsWith PASS || FAIL || ALL */
-    protected TestCompleteListener(
-        String label,
-        IRunValidator runValidator,
-        StreamsHandler streamsHandler) {
-        if (null == runValidator) {
-            runValidator = RunValidator.NORMAL;
-        }
-        this.label = (null == label? "" : label);
-        this.logOnPass = label.endsWith(PASS) || label.endsWith(ALL);
-        this.logOnNotPass = label.endsWith(FAIL) || label.endsWith(ALL);
-        this.runValidator = runValidator;
-        this.streamsHandler = streamsHandler;
-    }
-
-    public void runStarted(IRunStatus run) {
-        if (null != streamsHandler) {
-            streamsHandler.startListening();
-        }
-    }
-
-    /** subclasses implement this to do some per-test initialization */
-    protected void doRunStarted(IRunStatus run) {
-    }
-
-
-    /** subclasses implement this to do some per-suite initialization */
-    protected void doStartSuite(File suite) {
-    }
-
-    /** subclasses implement this to do end-of-suite processing */
-    protected void doEndSuite(File suite, long duration) {
-    }
-
-    public final void runCompleted(IRunStatus run) {
-        boolean doit = lastRunOk(run);
-        StreamsHandler.Result result = null;
-        if (null != streamsHandler) {
-            streamsHandler.endListening(doit);
-        }
-        if (doit) {
-            doRunCompleted(run, result);
-        }
-    }
-
-    /**
-     * @return true if run is ok per constructor specifications
-     */
-    protected boolean lastRunOk(IRunStatus run) {
-        if (lastRun != run) {
-            boolean passed = runValidator.runPassed(run);
-            lastRunOk = (passed ? logOnPass : logOnNotPass);
-        }
-        return lastRunOk;
-    }
-
-    /** @return "{classname}({pass}{,fail})" indicating when this runs */
-    public String toString() { // XXX add label?
-        return LangUtil.unqualifiedClassName(this)
-            + "(" + (logOnPass ? (logOnNotPass ? "pass, fail)" : "pass)")
-                                       : (logOnNotPass ? "fail)" : ")"));
-    }
-    /**
-     * Subclasses implement this to do some completion action
-     * @param run the IRunStatus for this completed run
-     * @param result the StreamsHandler.Result (if any - may be null)
-     */
-    public abstract void doRunCompleted(IRunStatus run, StreamsHandler.Result result);
+       /** label suffix indicating both pass and fail */
+       public static final String ALL = "All";
+
+       /** label suffix indicating fail */
+       public static final String FAIL = "Fail";
+
+       /** label suffix indicating pass */
+       public static final String PASS = "Pass";
+
+
+       /** runValidator determines if a given run passed */
+       protected final IRunValidator runValidator;
+
+       /** label for this listener */
+       final String label;
+
+       /** if trun and run passed, then run doRunCompleted(..) */
+       final boolean logOnPass;
+
+       /** if true and run did not pass, then run doRunCompleted(..) */
+       final boolean logOnNotPass;
+
+       /** may be null */
+       protected final StreamsHandler streamsHandler;
+
+       /** true if the last run evaluation was ok */
+       boolean lastRunOk;
+
+       /** last run evaluated */
+       IRunStatus lastRun; // XXX small memory leak - cache hashcode instead?
+
+       /** @param label endsWith PASS || FAIL || ALL */
+       protected TestCompleteListener(
+                       String label,
+                       IRunValidator runValidator,
+                       StreamsHandler streamsHandler) {
+               if (null == runValidator) {
+                       runValidator = RunValidator.NORMAL;
+               }
+               this.label = (null == label? "" : label);
+               this.logOnPass = label.endsWith(PASS) || label.endsWith(ALL);
+               this.logOnNotPass = label.endsWith(FAIL) || label.endsWith(ALL);
+               this.runValidator = runValidator;
+               this.streamsHandler = streamsHandler;
+       }
+
+       public void runStarted(IRunStatus run) {
+               if (null != streamsHandler) {
+                       streamsHandler.startListening();
+               }
+       }
+
+       /** subclasses implement this to do some per-test initialization */
+       protected void doRunStarted(IRunStatus run) {
+       }
+
+
+       /** subclasses implement this to do some per-suite initialization */
+       protected void doStartSuite(File suite) {
+       }
+
+       /** subclasses implement this to do end-of-suite processing */
+       protected void doEndSuite(File suite, long duration) {
+       }
+
+       @Override
+       public final void runCompleted(IRunStatus run) {
+               boolean doit = lastRunOk(run);
+               StreamsHandler.Result result = null;
+               if (null != streamsHandler) {
+                       streamsHandler.endListening(doit);
+               }
+               if (doit) {
+                       doRunCompleted(run, result);
+               }
+       }
+
+       /**
+        * @return true if run is ok per constructor specifications
+        */
+       protected boolean lastRunOk(IRunStatus run) {
+               if (lastRun != run) {
+                       boolean passed = runValidator.runPassed(run);
+                       lastRunOk = (passed ? logOnPass : logOnNotPass);
+               }
+               return lastRunOk;
+       }
+
+       /** @return "{classname}({pass}{,fail})" indicating when this runs */
+       @Override
+       public String toString() { // XXX add label?
+               return LangUtil.unqualifiedClassName(this)
+                               + "(" + (logOnPass ? (logOnNotPass ? "pass, fail)" : "pass)")
+                                               : (logOnNotPass ? "fail)" : ")"));
+       }
+       /**
+        * Subclasses implement this to do some completion action
+        * @param run the IRunStatus for this completed run
+        * @param result the StreamsHandler.Result (if any - may be null)
+        */
+       public abstract void doRunCompleted(IRunStatus run, StreamsHandler.Result result);
 }
 
 /**
@@ -1264,36 +1279,37 @@ abstract class TestCompleteListener extends RunListener {
  * most sensibly AjcTest.class.
  */
 class XmlLogger extends TestCompleteListener {
-    /**
-     * @param printer the component that prints any status - not null
-     * @param runValidator if null, use RunValidator.NORMAL
-     */
-    public XmlLogger(
-        String label,
-        StreamsHandler streamsHandler,
-        IRunValidator runValidator) {
-        super(label, runValidator, streamsHandler);
-    }
-
-    public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
-        PrintStream out = streamsHandler.getLogStream();
-        out.println("");
-        XMLWriter writer = new XMLWriter(new PrintWriter(out, true));
-        Object id = run.getIdentifier();
-        if (!(id instanceof Runner.IteratorWrapper)) {
-            out.println(this + " not IteratorWrapper: "
-                + id.getClass().getName() + ": " + id);
-            return;
-        }
-        IRunIterator iter = ((Runner.IteratorWrapper) id).iterator;
-        if (!(iter instanceof RunSpecIterator)) {
-            out.println(this + " not RunSpecIterator: " + iter.getClass().getName()
-                + ": " + iter);
-            return;
-        }
-        ((RunSpecIterator) iter).spec.writeXml(writer);
-        out.flush();
-    }
+       /**
+        * @param printer the component that prints any status - not null
+        * @param runValidator if null, use RunValidator.NORMAL
+        */
+       public XmlLogger(
+                       String label,
+                       StreamsHandler streamsHandler,
+                       IRunValidator runValidator) {
+               super(label, runValidator, streamsHandler);
+       }
+
+       @Override
+       public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
+               PrintStream out = streamsHandler.getLogStream();
+               out.println("");
+               XMLWriter writer = new XMLWriter(new PrintWriter(out, true));
+               Object id = run.getIdentifier();
+               if (!(id instanceof Runner.IteratorWrapper)) {
+                       out.println(this + " not IteratorWrapper: "
+                                       + id.getClass().getName() + ": " + id);
+                       return;
+               }
+               IRunIterator iter = ((Runner.IteratorWrapper) id).iterator;
+               if (!(iter instanceof RunSpecIterator)) {
+                       out.println(this + " not RunSpecIterator: " + iter.getClass().getName()
+                                       + ": " + iter);
+                       return;
+               }
+               ((RunSpecIterator) iter).spec.writeXml(writer);
+               out.flush();
+       }
 
 }
 
@@ -1312,24 +1328,25 @@ class XmlLogger extends TestCompleteListener {
  */
 class JUnitXMLLogger extends TestCompleteListener {
 
-//  private File suite;
-  private StringBuffer junitOutput;
-  private long startTimeMillis;
-  private int numTests = 0;
-  private int numFails = 0;
-  private DecimalFormat timeFormatter = new DecimalFormat("#.##");
-
-  public JUnitXMLLogger(
-       String label,
-       StreamsHandler streamsHandler,
-       IRunValidator runValidator) {
-               super(label + ALL, runValidator, streamsHandler);
-               junitOutput = new StringBuffer();
-  }
+       //  private File suite;
+       private StringBuffer junitOutput;
+       private long startTimeMillis;
+       private int numTests = 0;
+       private int numFails = 0;
+       private DecimalFormat timeFormatter = new DecimalFormat("#.##");
+
+       public JUnitXMLLogger(
+                       String label,
+                       StreamsHandler streamsHandler,
+                       IRunValidator runValidator) {
+               super(label + ALL, runValidator, streamsHandler);
+               junitOutput = new StringBuffer();
+       }
 
        /* (non-Javadoc)
         * @see org.aspectj.testing.drivers.TestCompleteListener#doRunCompleted(org.aspectj.testing.run.IRunStatus, org.aspectj.testing.util.StreamsHandler.Result)
         */
+       @Override
        public void doRunCompleted(IRunStatus run, Result result) {
                long duration = System.currentTimeMillis()  - startTimeMillis;
                numTests++;
@@ -1340,8 +1357,8 @@ class JUnitXMLLogger extends TestCompleteListener {
                        numFails++;
                        junitOutput.append("\n");
                        junitOutput.append("<failure message=\"test failed\" type=\"unknown\">\n");
-//                     junitOutput.println(result.junitOutput);
-//                     junitOutput.println(result.err);
+                       //                      junitOutput.println(result.junitOutput);
+                       //                      junitOutput.println(result.err);
                        junitOutput.append("</failure>\n");
                }
                junitOutput.append("</testcase>\n");
@@ -1350,14 +1367,16 @@ class JUnitXMLLogger extends TestCompleteListener {
        /* (non-Javadoc)
         * @see org.aspectj.testing.drivers.TestCompleteListener#runStarted(org.aspectj.testing.run.IRunStatus)
         */
+       @Override
        public void runStarting(IRunStatus run) {
-                super.runStarting(run);
-                startTimeMillis = System.currentTimeMillis();
+               super.runStarting(run);
+               startTimeMillis = System.currentTimeMillis();
        }
 
        /* (non-Javadoc)
         * @see org.aspectj.testing.drivers.TestCompleteListener#doEndSuite(java.io.File, long)
         */
+       @Override
        protected void doEndSuite(File suite, long duration) {
                super.doEndSuite(suite, duration);
                String suiteName = suite.getName();
@@ -1376,9 +1395,10 @@ class JUnitXMLLogger extends TestCompleteListener {
        /* (non-Javadoc)
         * @see org.aspectj.testing.drivers.TestCompleteListener#doStartSuite(java.io.File)
         */
+       @Override
        protected void doStartSuite(File suite) {
                super.doStartSuite(suite);
-//             this.suite = suite;
+               //              this.suite = suite;
                numTests = 0;
                numFails = 0;
                junitOutput = new StringBuffer();
@@ -1388,98 +1408,101 @@ class JUnitXMLLogger extends TestCompleteListener {
 
 /** log pass and/or failed runs */
 class RunLogger extends TestCompleteListener {
-    final boolean logStreams;
-    final RunUtils.IRunStatusPrinter printer;
-
-    /**
-     * @param printer the component that prints any status - not null
-     * @param runValidator if null, use RunValidator.NORMAL
-     */
-    public RunLogger(
-        String label,
-        boolean logStreams,
-        StreamsHandler streamsHandler,
-        IRunValidator runValidator,
-        RunUtils.IRunStatusPrinter printer) {
-        super(label, runValidator, streamsHandler);
-        LangUtil.throwIaxIfNull(streamsHandler, "streamsHandler");
-        LangUtil.throwIaxIfNull(printer, "printer");
-        this.logStreams = logStreams;
-        this.printer = printer;
-    }
-
-    public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
-        PrintStream out = streamsHandler.getLogStream();
-        printer.printRunStatus(out, run);
-        if (logStreams) {
-            if (!LangUtil.isEmpty(result.err)) {
-                out.println("--- error");
-                out.println(result.err);
-            }
-            if (!LangUtil.isEmpty(result.out)) {
-                out.println("--- ouput");
-                out.println(result.out);
-            }
-        }
-        out.println("");
-    }
+       final boolean logStreams;
+       final RunUtils.IRunStatusPrinter printer;
+
+       /**
+        * @param printer the component that prints any status - not null
+        * @param runValidator if null, use RunValidator.NORMAL
+        */
+       public RunLogger(
+                       String label,
+                       boolean logStreams,
+                       StreamsHandler streamsHandler,
+                       IRunValidator runValidator,
+                       RunUtils.IRunStatusPrinter printer) {
+               super(label, runValidator, streamsHandler);
+               LangUtil.throwIaxIfNull(streamsHandler, "streamsHandler");
+               LangUtil.throwIaxIfNull(printer, "printer");
+               this.logStreams = logStreams;
+               this.printer = printer;
+       }
+
+       @Override
+       public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
+               PrintStream out = streamsHandler.getLogStream();
+               printer.printRunStatus(out, run);
+               if (logStreams) {
+                       if (!LangUtil.isEmpty(result.err)) {
+                               out.println("--- error");
+                               out.println(result.err);
+                       }
+                       if (!LangUtil.isEmpty(result.out)) {
+                               out.println("--- ouput");
+                               out.println(result.out);
+                       }
+               }
+               out.println("");
+       }
 }
 
 /** trace time and memory between runStaring and runCompleted */
 class TestTraceLogger extends TestCompleteListener {
-    private static final Runtime runtime = Runtime.getRuntime();
-    private long startTime;
-    private long startMemoryFree;
-    private final boolean verbose;
-
-    public TestTraceLogger(StreamsHandler handler) {
-        this(handler, true);
-    }
-    public TestTraceLogger(StreamsHandler handler, boolean verbose) {
-        super("-traceTestsAll", null, handler);
-        this.verbose = verbose;
-    }
-    public void runStarting(IRunStatus run) {
-        super.runStarting(run);
-        startTime = System.currentTimeMillis();
-        startMemoryFree = runtime.freeMemory();
-    }
-
-    public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
-        long elapsed = System.currentTimeMillis() - startTime;
-        long free = runtime.freeMemory();
-        long used = startMemoryFree - free;
-        String label = run.runResult() ? "PASS " : "FAIL ";
-        PrintStream out = streamsHandler.getLogStream();
-        if (verbose) {
-            label = label
-                    + "elapsed: " + LangUtil.toSizedString(elapsed, 7)
-                    + " free: " + LangUtil.toSizedString(free, 10)
-                    + " used: " + LangUtil.toSizedString(used, 10)
-                    + " id: ";
-        }
-        out.println(label + renderId(run));
-    }
-
-    /** @return true - always trace tests */
-    protected boolean isFailLabel(String label) {
-        return true;
-    }
-
-    /** @return true - always trace tests */
-    protected boolean isPassLabel(String label) {
-        return true;
-    }
-
-    /**
-     * This implementation returns run identifier toString().
-     * Subclasses override this to render id as message suffix.
-     */
-    protected String renderId(IRunStatus run) {
-        return "" + run.getIdentifier();
-    }
+       private static final Runtime runtime = Runtime.getRuntime();
+       private long startTime;
+       private long startMemoryFree;
+       private final boolean verbose;
+
+       public TestTraceLogger(StreamsHandler handler) {
+               this(handler, true);
+       }
+       public TestTraceLogger(StreamsHandler handler, boolean verbose) {
+               super("-traceTestsAll", null, handler);
+               this.verbose = verbose;
+       }
+       @Override
+       public void runStarting(IRunStatus run) {
+               super.runStarting(run);
+               startTime = System.currentTimeMillis();
+               startMemoryFree = runtime.freeMemory();
+       }
+
+       @Override
+       public void doRunCompleted(IRunStatus run, StreamsHandler.Result result) {
+               long elapsed = System.currentTimeMillis() - startTime;
+               long free = runtime.freeMemory();
+               long used = startMemoryFree - free;
+               String label = run.runResult() ? "PASS " : "FAIL ";
+               PrintStream out = streamsHandler.getLogStream();
+               if (verbose) {
+                       label = label
+                                       + "elapsed: " + LangUtil.toSizedString(elapsed, 7)
+                                       + " free: " + LangUtil.toSizedString(free, 10)
+                                       + " used: " + LangUtil.toSizedString(used, 10)
+                                       + " id: ";
+               }
+               out.println(label + renderId(run));
+       }
+
+       /** @return true - always trace tests */
+       protected boolean isFailLabel(String label) {
+               return true;
+       }
+
+       /** @return true - always trace tests */
+       protected boolean isPassLabel(String label) {
+               return true;
+       }
+
+       /**
+        * This implementation returns run identifier toString().
+        * Subclasses override this to render id as message suffix.
+        */
+       protected String renderId(IRunStatus run) {
+               return "" + run.getIdentifier();
+       }
 }
-        // printing files
+// printing files
 //        AjcTest.Spec testSpec = AjcTest.unwrapSpec(run);
 //        if (null != testSpec) {
 //            CompilerRun.Spec compileSpec = AjcTest.unwrapCompilerRunSpec(testSpec);
index 4e61a512cbc41a7347ccdf723c9704f40a93f6b3..9e302f41f3dc2afe7c5dca2185ab8d0b8e7e0969 100644 (file)
@@ -1,14 +1,14 @@
 /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
+ * Copyright (c) 1999-2001 Xerox Corporation,
  *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xerox/PARC     initial implementation
  *     Wes Isberg     2004 updates
  * ******************************************************************/
 
@@ -62,7 +62,7 @@ import org.aspectj.util.LangUtil;
  * <u>Coordination with writers</u>: because this reads the contents of values written by IXmlWritable, they should ensure their
  * values are readable. When flattening and unflattening lists, the convention is to use the {un}flattenList(..) methods in
  * XMLWriter.
- * 
+ *
  * @see XMLWriter@unflattenList(String)
  * @see XMLWriter@flattenList(List)
  */
@@ -114,7 +114,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                // XXXXXunused sourceLocations = new ArrayList();
                keywords = new ArrayList<String>();
                children = new ArrayList<IRunSpec>();
-               dirChanges = new ArrayList();
+               dirChanges = new ArrayList<>();
                xmlNames = XMLNames.DEFAULT;
                runtime = new RT();
                this.skipIfAnyChildSkipped = skipIfAnyChildSkipped;
@@ -191,8 +191,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        public void addKeywords(String[] ra) {
                if (null != ra) {
-                       for (int i = 0; i < ra.length; i++) {
-                               addKeyword(ra[i]);
+                       for (String element : ra) {
+                               addKeyword(element);
                        }
                }
        }
@@ -210,7 +210,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        /** @return String[] of options */
        public String[] getOptionsArray() {
-               return (String[]) options.toArray(new String[0]);
+               return options.toArray(new String[0]);
        }
 
        public void setOption(String option) {
@@ -231,7 +231,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        /**
         * Set options, removing any existing options.
-        * 
+        *
         * @param options String[] options to use - may be null or empty
         */
        public void setOptionsArray(String[] options) {
@@ -249,8 +249,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        public void addOptions(String[] ra) {
                if (null != ra) {
-                       for (int i = 0; i < ra.length; i++) {
-                               addOption(ra[i]);
+                       for (String element : ra) {
+                               addOption(element);
                        }
                }
        }
@@ -263,7 +263,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        /** @return String[] of paths */
        public String[] getPathsArray() {
-               return (String[]) paths.toArray(new String[0]);
+               return paths.toArray(new String[0]);
        }
 
        public void setPath(String path) {
@@ -288,8 +288,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        public void addPaths(String[] ra) {
                if (null != ra) {
-                       for (int i = 0; i < ra.length; i++) {
-                               addPath(ra[i]);
+                       for (String element : ra) {
+                               addPath(element);
                        }
                }
        }
@@ -327,8 +327,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
        public void addMessages(String items) {
                if (null != items) {
                        String[] ra = XMLWriter.unflattenList(items);
-                       for (int i = 0; i < ra.length; i++) {
-                               addMessage(ra[i]);
+                       for (String element : ra) {
+                               addMessage(element);
                        }
                }
        }
@@ -395,7 +395,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
         * or the child's adoptParentValues(..) should add one info message with the reason this is being skipped. The only reason to
         * override this would be to NOT invoke the same for children, or to do something similar for children which are not
         * AbstractRunSpec.
-        * 
+        *
         * @param parentRuntime the RT values to adopt - ignored if null
         * @param handler the IMessageHandler for info messages when skipping
         * @return false if this wants to be skipped, true otherwise
@@ -437,7 +437,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
         * adds any non-null options we don't already have. setting verbose and adding to parent options. Implementors override this to
         * affect how parent values are adopted. Implementors should not recurse into children. This method may be called multiple
         * times, so implementors should not destroy any spec information. Always add an info message when returning false to skip
-        * 
+        *
         * @param parentRuntime the RT values to adopt - never null
         * @return false if this wants to be skipped, true otherwise
         */
@@ -456,7 +456,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        /**
         * Implementations call this when signalling skips to ensure consistency in message formatting
-        * 
+        *
         * @param handler the IMessageHandler sink - not null
         * @param reason the String reason to skip - not null
         */
@@ -473,7 +473,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
        /**
         * Control XML output by renaming or suppressing output for attributes and subelements. Subelements are skipped by setting the
         * XMLNames booleans to false. Attributes are skipped by setting their name to null.
-        * 
+        *
         * @param names XMLNames with new names and/or suppress flags.
         */
        protected void setXMLNames(XMLNames names) {
@@ -504,7 +504,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                return ((!LangUtil.isEmpty(xmlNames.descriptionName) && !LangUtil.isEmpty(description))
                                || (!LangUtil.isEmpty(xmlNames.keywordsName) && !LangUtil.isEmpty(keywords))
                                || (!LangUtil.isEmpty(xmlNames.optionsName) && !LangUtil.isEmpty(options)) || (!LangUtil
-                               .isEmpty(xmlNames.pathsName) && !LangUtil.isEmpty(paths)));
+                                               .isEmpty(xmlNames.pathsName) && !LangUtil.isEmpty(paths)));
        }
 
        /**
@@ -539,11 +539,12 @@ abstract public class AbstractRunSpec implements IRunSpec {
         * The default implementation writes everything as attributes, then subelements for dirChanges, messages, then subelements for
         * children. Subclasses that override may delegate back for any of these. Subclasses may also set XMLNames to name or suppress
         * any attribute or subelement.
-        * 
+        *
         * @see writeMessages(XMLWriter)
         * @see writeChildren(XMLWriter)
         * @see IXmlWritable#writeXml(XMLWriter)
         */
+       @Override
        public void writeXml(XMLWriter out) {
                out.startElement(xmlElementName, false);
                writeAttributes(out);
@@ -572,8 +573,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
         */
        protected void writeChildren(XMLWriter out) {
                if (0 < children.size()) {
-                       for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) {
-                               IXmlWritable self = (IXmlWritable) iter.next();
+                       for (IRunSpec iRunSpec : children) {
+                               IXmlWritable self = iRunSpec;
                                self.writeXml(out);
                        }
                }
@@ -583,8 +584,8 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
        public void printAll(PrintStream out, String prefix) {
                out.println(prefix + toString());
-               for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) {
-                       AbstractRunSpec child = (AbstractRunSpec) iter.next(); // IRunSpec
+               for (IRunSpec iRunSpec : children) {
+                       AbstractRunSpec child = (AbstractRunSpec) iRunSpec; // IRunSpec
                        child.printAll(out, prefix + "    ");
                }
        }
@@ -592,7 +593,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
        /**
         * default implementation returns the description if not empty or the unqualified class name otherwise. Subclasses should not
         * call toString from here unless they reimplement it.
-        * 
+        *
         * @return name of this thing or type
         */
        protected String getPrintName() {
@@ -604,6 +605,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
        }
 
        /** @return summary count of spec elements */
+       @Override
        public String toString() {
                return getPrintName() + "(" + containedSummary() + ")";
        }
@@ -646,9 +648,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                 */
                spec.badInput = badInput;
                spec.children.clear();
-               for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) {
-                       // clone these...
-                       IRunSpec child = iter.next();
+               for (IRunSpec child : children) {
                        // require all child classes to support clone?
                        if (child instanceof AbstractRunSpec) {
                                spec.addChild((AbstractRunSpec) ((AbstractRunSpec) child).clone());
@@ -728,6 +728,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                final boolean skipMessages;
                final boolean skipChildren;
 
+               @Override
                protected Object clone() {
                        return new XMLNames(null, descriptionName, sourceLocationName, keywordsName, optionsName, pathsName, commentName,
                                        stagingName, badInputName, skipDirChanges, skipMessages, skipChildren);
@@ -767,6 +768,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
        }
 
        /** subclasses implement this to create and set up a run */
+       @Override
        abstract public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator);
 
        /** segregate runtime-only state in spec */
@@ -788,15 +790,15 @@ abstract public class AbstractRunSpec implements IRunSpec {
                /**
                 * Set parent options - old options destroyed. Will result in duplicates if duplicates added. Null or empty entries are
                 * ignored
-                * 
+                *
                 * @param options ignored if null or empty
                 */
                public void setOptions(String[] options) {
                        parentOptions.clear();
                        if (!LangUtil.isEmpty(options)) {
-                               for (int i = 0; i < options.length; i++) {
-                                       if (!LangUtil.isEmpty(options[i])) {
-                                               parentOptions.add(options[i]);
+                               for (String option : options) {
+                                       if (!LangUtil.isEmpty(option)) {
+                                               parentOptions.add(option);
                                        }
                                }
                        }
@@ -804,7 +806,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
                /**
                 * Copy values from another RT
-                * 
+                *
                 * @param toCopy the RT to copy from
                 * @throws IllegalArgumentException if toCopy is null
                 */
@@ -817,11 +819,11 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
                /**
                 * Return any parent option accepted by validOptions, optionally removing the parent option.
-                * 
+                *
                 * @param validOptions String[] of options to extract
                 * @param remove if true, then remove any parent option matched
                 * @return String[] containing any validOptions[i] in parentOptions
-                * 
+                *
                 */
                public Values extractOptions(Options validOptions, boolean remove, StringBuffer errors) {
                        Values result = Values.EMPTY;
@@ -836,7 +838,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                                return result;
                        }
                        // boolean haveOption = false;
-                       String[] parents = (String[]) parentOptions.toArray(new String[0]);
+                       String[] parents = parentOptions.toArray(new String[0]);
                        try {
                                result = validOptions.acceptInput(parents);
                        } catch (InvalidInputException e) {
@@ -869,7 +871,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
                /**
                 * Return any parent option which has one of validOptions as a prefix, optionally absorbing (removing) the parent option.
-                * 
+                *
                 * @param validOptions String[] of options to extract
                 * @param absorb if true, then remove any parent option matched
                 * @return String[] containing any validOptions[i] in parentOptions (at most once)
@@ -880,8 +882,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                        }
                        ArrayList<String> result = new ArrayList<String>();
                        // boolean haveOption = false;
-                       for (int i = 0; i < validOptions.length; i++) {
-                               String option = validOptions[i];
+                       for (String option : validOptions) {
                                if (LangUtil.isEmpty(option)) {
                                        continue;
                                }
@@ -895,7 +896,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
                                        }
                                }
                        }
-                       return (String[]) result.toArray(new String[0]);
+                       return result.toArray(new String[0]);
                }
 
                /** Get ListIterator that permits removals */
@@ -905,7 +906,7 @@ abstract public class AbstractRunSpec implements IRunSpec {
 
                /**
                 * Enable verbose logging
-                * 
+                *
                 * @param verbose if true, do verbose logging
                 */
                public void setVerbose(boolean verbose) {
index 36ade5f2a84305859f1b012d79bb27f59ca84cd3..4d1a47cebaccc41e968ff90afed9bd4e9d0ea071 100644 (file)
@@ -1,14 +1,14 @@
 /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
+ * Copyright (c) 1999-2001 Xerox Corporation,
  *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xerox/PARC     initial implementation
  * ******************************************************************/
 
 package org.aspectj.testing.harness.bridge;
@@ -32,310 +32,310 @@ import junit.framework.TestCase;
  * Primarily used by others to test AjcTest
  */
 public class AjcSpecTest extends TestCase {
-    public static final String NOTSAME = " != ";
-    public static void sameAjcSuiteSpec(
-        AjcTest.Suite.Spec lhsSpec,
-        AjcTest.Suite.Spec rhsSpec,
-        Assert a) {
-        assertNotNull(lhsSpec);
-        assertNotNull(rhsSpec);
-        Iterator lhs = lhsSpec.getChildren().iterator();
-        Iterator rhs = rhsSpec.getChildren().iterator();
-        while (lhs.hasNext() && rhs.hasNext()) {
-            AjcTest.Spec lhsTest = (AjcTest.Spec) lhs.next();
-            AjcTest.Spec rhsTest = (AjcTest.Spec) rhs.next();
-            AjcSpecTest.sameAjcTestSpec(lhsTest, rhsTest, a);
-        }
-        assertTrue(!lhs.hasNext());        
-        assertTrue(!rhs.hasNext());        
-    }
+       public static final String NOTSAME = " != ";
+       public static void sameAjcSuiteSpec(
+                       AjcTest.Suite.Spec lhsSpec,
+                       AjcTest.Suite.Spec rhsSpec,
+                       Assert a) {
+               assertNotNull(lhsSpec);
+               assertNotNull(rhsSpec);
+               Iterator lhs = lhsSpec.getChildren().iterator();
+               Iterator rhs = rhsSpec.getChildren().iterator();
+               while (lhs.hasNext() && rhs.hasNext()) {
+                       AjcTest.Spec lhsTest = (AjcTest.Spec) lhs.next();
+                       AjcTest.Spec rhsTest = (AjcTest.Spec) rhs.next();
+                       AjcSpecTest.sameAjcTestSpec(lhsTest, rhsTest, a);
+               }
+               assertTrue(!lhs.hasNext());
+               assertTrue(!rhs.hasNext());
+       }
 
        public static void sameAjcTestSpec(
-               AjcTest.Spec lhsTest,
-               AjcTest.Spec rhsTest,
-               Assert a) {
-        assertNotNull(lhsTest);
-        assertNotNull(rhsTest);
-        assertEquals(lhsTest.getBugId(), rhsTest.getBugId());
-        assertEquals(lhsTest.getTestDirOffset(), rhsTest.getTestDirOffset());
-        // XXX suiteDir varies by run..
-        // description, options, paths, comments, keywords
-        sameAbstractRunSpec(lhsTest, rhsTest, a);
+                       AjcTest.Spec lhsTest,
+                       AjcTest.Spec rhsTest,
+                       Assert a) {
+               assertNotNull(lhsTest);
+               assertNotNull(rhsTest);
+               assertEquals(lhsTest.getBugId(), rhsTest.getBugId());
+               assertEquals(lhsTest.getTestDirOffset(), rhsTest.getTestDirOffset());
+               // XXX suiteDir varies by run..
+               // description, options, paths, comments, keywords
+               sameAbstractRunSpec(lhsTest, rhsTest, a);
        }
 
        public static void sameAbstractRunSpec(
-               AbstractRunSpec lhs,
-               AbstractRunSpec rhs,
-        Assert a) {
-        assertEquals(lhs.description, rhs.description);
-        // XXX keywords added in .txt reading - 
-        //sameList(lhs.getKeywordsList(), rhs.getKeywordsList(), a);
-        // XXX sameList(lhs.globalOptions, rhs.globalOptions, a);
-        sameList(lhs.getOptionsList(), rhs.getOptionsList(), a);
-        sameList(lhs.getPathsList(), rhs.getPathsList(), a);
-        assertEquals(lhs.isStaging(), rhs.isStaging());
-        sameList(lhs.keywords, rhs.keywords, a);
-        assertEquals(lhs.comment, rhs.comment); 
-        assertEquals(lhs.badInput, rhs.badInput);
-        // xml adds sourceloc?
-        //sameSourceLocation(lhs.getSourceLocation(), rhs.getSourceLocation(), a);
-        // XXX also sourceLocations?
-        sameMessages(lhs.getMessages(), rhs.getMessages(), a);
+                       AbstractRunSpec lhs,
+                       AbstractRunSpec rhs,
+                       Assert a) {
+               assertEquals(lhs.description, rhs.description);
+               // XXX keywords added in .txt reading -
+               //sameList(lhs.getKeywordsList(), rhs.getKeywordsList(), a);
+               // XXX sameList(lhs.globalOptions, rhs.globalOptions, a);
+               sameList(lhs.getOptionsList(), rhs.getOptionsList(), a);
+               sameList(lhs.getPathsList(), rhs.getPathsList(), a);
+               assertEquals(lhs.isStaging(), rhs.isStaging());
+               sameList(lhs.keywords, rhs.keywords, a);
+               assertEquals(lhs.comment, rhs.comment);
+               assertEquals(lhs.badInput, rhs.badInput);
+               // xml adds sourceloc?
+               //sameSourceLocation(lhs.getSourceLocation(), rhs.getSourceLocation(), a);
+               // XXX also sourceLocations?
+               sameMessages(lhs.getMessages(), rhs.getMessages(), a);
+       }
+
+       /** @return normal form - null is "", "" is "", and others are {fully.qualified.class}.toString().trim() */
+       static String normal(Object input) {
+               if ((null == input) || ("".equals(input))) {
+                       return "";
+               } else {
+                       return input.getClass().getName() + "." + input.toString().trim();
+               }
        }
 
-    /** @return normal form - null is "", "" is "", and others are {fully.qualified.class}.toString().trim() */
-    static String normal(Object input) {
-        if ((null == input) || ("".equals(input))) {
-            return "";
-        } else {
-            return input.getClass().getName() + "." + input.toString().trim();
-        }
-    }
+       /** @return true if these match after normalizing */
+       public static void same(Object lhs, Object rhs, Assert a) {
+               lhs = normal(lhs);
+               rhs = normal(rhs);
+               assertTrue(lhs + NOTSAME + rhs, lhs.equals(rhs));
+       }
 
-    /** @return true if these match after normalizing */
-    public static void same(Object lhs, Object rhs, Assert a) {
-        lhs = normal(lhs);
-        rhs = normal(rhs);
-        assertTrue(lhs + NOTSAME + rhs, lhs.equals(rhs));
-    }
-    
-    /** @return true if both are empty (null or no entries) or if all match */
-    public static void sameRA(String[] lhs, String[] rhs, Assert a) {        
-        if (null == lhs) {
-            assertTrue((null == rhs) || (0 == rhs.length));
-        } else if (null == rhs) {
-            assertTrue(0 == lhs.length);
-        } else {
-            String l = normal(lhs);
-            String r = normal(rhs);
-            assertTrue(l + NOTSAME + r, l.equals(r));
-        }
-    }
-        
-    /** @return normal form for String[] items*/
-    static String normal(String[] items) {
-        return (null == items ? "[]" : normal(Arrays.asList(items)));
-    }
-    
-    /** @return normal form for list items */
-    static String normal(List list) {
-        StringBuffer sb = new StringBuffer();
-        sb.append("[");
-        boolean first = true;
-        for (Iterator iter = list.iterator(); iter.hasNext();) {
-            Object o = iter.next();            
-            if (!first) {
-                sb.append(", ");
-            } else {
-                first = false;
-            }
-            sb.append(normal(o));
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-        
-    /** @return true if both are empty (null or no entries) or if all match after trimming */
-    public static void sameListSize(List lhs, List rhs) {
-        if (null == lhs) {
-            assertTrue((null == rhs) || (0 == rhs.size()));
-        } else if (null == rhs) {
-            assertTrue(0 == lhs.size());
-        } else {
-            assertTrue(rhs.size() == lhs.size());
-        }        
-    }
+       /** @return true if both are empty (null or no entries) or if all match */
+       public static void sameRA(String[] lhs, String[] rhs, Assert a) {
+               if (null == lhs) {
+                       assertTrue((null == rhs) || (0 == rhs.length));
+               } else if (null == rhs) {
+                       assertTrue(0 == lhs.length);
+               } else {
+                       String l = normal(lhs);
+                       String r = normal(rhs);
+                       assertTrue(l + NOTSAME + r, l.equals(r));
+               }
+       }
 
-    /** @return true if both are empty (null or no entries) or if all match after trimming */
-    public static void sameList(List lhs, List rhs, Assert a) {
-        sameListSize(lhs, rhs);
-        String l = normal(lhs);
-        String r = normal(rhs);
-        String label = l + NOTSAME + r;
-        assertTrue(label, l.equals(r));
-    }
-    
-//    /**
-//     * Normalize and compare:
-//     * <li>bug id's are not compared since extracted during xml writing</li>
-//     * <li>keyword compare is disabled since keywords are generated during xml reading.</li> 
-//     * <li>description compare is normalized by stripping bug ids</li>
-//     * <li>String and arrays are equal when empty (null or 0-length)</li>
-//     * @see Ajctest#stripBugId(String)
-//     */
-//    public static void sameAjcTest(AjcTest lhs, AjcTest rhs, Assert reporter) {
-//        Assert a = reporter;
-//        String label = lhs + NOTSAME + rhs;
-//        assertTrue(label, null != lhs);
-//        assertTrue(label, null != rhs);
-//        //assertTrue(label, lhs.ignoreWarnings == rhs.ignoreWarnings);
-//        // XXX disabled - not in .txt 
-//        // sameStringList(lhs.keywords, rhs.keywords, a);
-//        // sameString(lhs.bugId, rhs.bugId, a);
-//        // argh - bugid stripped from description
-//        //same(AjcTest.stripBugId(lhs.description), AjcTest.stripBugId(lhs.description), a);
-//        //sameRA(lhs.globals, rhs.globals, a);
-//        //lhs.reset();
-//        //rhs.reset();
-//        boolean gotOne = false;
-//        IMessageHolder holder = new MessageHandler();
-//        assertTrue(label, !holder.hasAnyMessage(IMessage.FAIL, IMessageHolder.ORGREATER));
-//        while (lhs.hasNextRun() && rhs.hasNextRun()) {
-//            sameIAjcRun((IAjcRun) lhs.nextRun(holder), (IAjcRun) rhs.nextRun(holder), reporter);
-//            assertTrue(label, !holder.hasAnyMessage(IMessage.FAIL, IMessageHolder.ORGREATER));
-//            if (!gotOne) {
-//                gotOne = true;
-//            }
-//        }
-//        assertTrue(label, gotOne);
-//        assertTrue(label, !lhs.hasNextRun());
-//        assertTrue(label, !rhs.hasNextRun());
-//    }
+       /** @return normal form for String[] items*/
+       static String normal(String[] items) {
+               return (null == items ? "[]" : normal(Arrays.asList(items)));
+       }
+
+       /** @return normal form for list items */
+       static String normal(List list) {
+               StringBuffer sb = new StringBuffer();
+               sb.append("[");
+               boolean first = true;
+               for (Iterator iter = list.iterator(); iter.hasNext();) {
+                       Object o = iter.next();
+                       if (!first) {
+                               sb.append(", ");
+                       } else {
+                               first = false;
+                       }
+                       sb.append(normal(o));
+               }
+               sb.append("]");
+               return sb.toString();
+       }
+
+       /** @return true if both are empty (null or no entries) or if all match after trimming */
+       public static void sameListSize(List lhs, List rhs) {
+               if (null == lhs) {
+                       assertTrue((null == rhs) || (0 == rhs.size()));
+               } else if (null == rhs) {
+                       assertTrue(0 == lhs.size());
+               } else {
+                       assertTrue(rhs.size() == lhs.size());
+               }
+       }
+
+       /** @return true if both are empty (null or no entries) or if all match after trimming */
+       public static void sameList(List lhs, List rhs, Assert a) {
+               sameListSize(lhs, rhs);
+               String l = normal(lhs);
+               String r = normal(rhs);
+               String label = l + NOTSAME + r;
+               assertTrue(label, l.equals(r));
+       }
+
+       //    /**
+       //     * Normalize and compare:
+       //     * <li>bug id's are not compared since extracted during xml writing</li>
+       //     * <li>keyword compare is disabled since keywords are generated during xml reading.</li>
+       //     * <li>description compare is normalized by stripping bug ids</li>
+       //     * <li>String and arrays are equal when empty (null or 0-length)</li>
+       //     * @see Ajctest#stripBugId(String)
+       //     */
+       //    public static void sameAjcTest(AjcTest lhs, AjcTest rhs, Assert reporter) {
+       //        Assert a = reporter;
+       //        String label = lhs + NOTSAME + rhs;
+       //        assertTrue(label, null != lhs);
+       //        assertTrue(label, null != rhs);
+       //        //assertTrue(label, lhs.ignoreWarnings == rhs.ignoreWarnings);
+       //        // XXX disabled - not in .txt
+       //        // sameStringList(lhs.keywords, rhs.keywords, a);
+       //        // sameString(lhs.bugId, rhs.bugId, a);
+       //        // argh - bugid stripped from description
+       //        //same(AjcTest.stripBugId(lhs.description), AjcTest.stripBugId(lhs.description), a);
+       //        //sameRA(lhs.globals, rhs.globals, a);
+       //        //lhs.reset();
+       //        //rhs.reset();
+       //        boolean gotOne = false;
+       //        IMessageHolder holder = new MessageHandler();
+       //        assertTrue(label, !holder.hasAnyMessage(IMessage.FAIL, IMessageHolder.ORGREATER));
+       //        while (lhs.hasNextRun() && rhs.hasNextRun()) {
+       //            sameIAjcRun((IAjcRun) lhs.nextRun(holder), (IAjcRun) rhs.nextRun(holder), reporter);
+       //            assertTrue(label, !holder.hasAnyMessage(IMessage.FAIL, IMessageHolder.ORGREATER));
+       //            if (!gotOne) {
+       //                gotOne = true;
+       //            }
+       //        }
+       //        assertTrue(label, gotOne);
+       //        assertTrue(label, !lhs.hasNextRun());
+       //        assertTrue(label, !rhs.hasNextRun());
+       //    }
 
        public static void sameIAjcRun(IAjcRun lhs, IAjcRun rhs, Assert reporter) {
-//        Assert a = reporter;
-        assertTrue(lhs != null);
-        assertTrue(rhs != null);
-        Class c = lhs.getClass();
-        assertTrue(c == rhs.getClass());
-        AbstractRunSpec lhsSpec;
-        AbstractRunSpec rhsSpec;
-        
-        if (c == CompilerRun.class) {
-            CompilerRun.Spec l = ((CompilerRun) lhs).spec;
-            CompilerRun.Spec r = ((CompilerRun) rhs).spec;
-            lhsSpec = l;
-            rhsSpec = r;
-            assertEquals(l.argfiles, r.argfiles);
-            assertEquals(l.aspectpath, r.aspectpath);
-            assertEquals(l.testSrcDirOffset, r.testSrcDirOffset);
-            assertEquals(l.compiler, r.compiler);
-            assertEquals(l.includeClassesDir, r.includeClassesDir);
-            assertEquals(l.reuseCompiler, r.reuseCompiler);
-            assertEquals(l.sourceroots, r.sourceroots);
-            assertEquals(l.extdirs, r.extdirs);
-        } else if (c == JavaRun.class) {
-            JavaRun.Spec l = ((JavaRun) lhs).spec;
-            JavaRun.Spec r = ((JavaRun) rhs).spec;
-            lhsSpec = l;
-            rhsSpec = r;
-            assertTrue(l.skipTester ==  r.skipTester);
-            assertEquals(l.className, r.className);
-            assertEquals(l.javaVersion, r.javaVersion);
-            assertEquals(l.skipTester, r.skipTester);
-            assertEquals(l.outStreamIsError, r.outStreamIsError);
-            assertEquals(l.errStreamIsError, r.errStreamIsError);
-        } else if (c == IncCompilerRun.class) {
-            IncCompilerRun.Spec l = ((IncCompilerRun) lhs).spec;
-            IncCompilerRun.Spec r = ((IncCompilerRun) rhs).spec;
-            lhsSpec = l;
-            rhsSpec = r;
-            assertEquals(l.tag, r.tag);
-            assertEquals(l.fresh, r.fresh);
-        } else {
-            assertTrue(lhs.equals(rhs));
-            return;
-        }
-        sameSpec(lhsSpec, rhsSpec, reporter);
+               //        Assert a = reporter;
+               assertTrue(lhs != null);
+               assertTrue(rhs != null);
+               Class c = lhs.getClass();
+               assertTrue(c == rhs.getClass());
+               AbstractRunSpec lhsSpec;
+               AbstractRunSpec rhsSpec;
+
+               if (c == CompilerRun.class) {
+                       CompilerRun.Spec l = ((CompilerRun) lhs).spec;
+                       CompilerRun.Spec r = ((CompilerRun) rhs).spec;
+                       lhsSpec = l;
+                       rhsSpec = r;
+                       assertEquals(l.argfiles, r.argfiles);
+                       assertEquals(l.aspectpath, r.aspectpath);
+                       assertEquals(l.testSrcDirOffset, r.testSrcDirOffset);
+                       assertEquals(l.compiler, r.compiler);
+                       assertEquals(l.includeClassesDir, r.includeClassesDir);
+                       assertEquals(l.reuseCompiler, r.reuseCompiler);
+                       assertEquals(l.sourceroots, r.sourceroots);
+                       assertEquals(l.extdirs, r.extdirs);
+               } else if (c == JavaRun.class) {
+                       JavaRun.Spec l = ((JavaRun) lhs).spec;
+                       JavaRun.Spec r = ((JavaRun) rhs).spec;
+                       lhsSpec = l;
+                       rhsSpec = r;
+                       assertTrue(l.skipTester ==  r.skipTester);
+                       assertEquals(l.className, r.className);
+                       assertEquals(l.javaVersion, r.javaVersion);
+                       assertEquals(l.skipTester, r.skipTester);
+                       assertEquals(l.outStreamIsError, r.outStreamIsError);
+                       assertEquals(l.errStreamIsError, r.errStreamIsError);
+               } else if (c == IncCompilerRun.class) {
+                       IncCompilerRun.Spec l = ((IncCompilerRun) lhs).spec;
+                       IncCompilerRun.Spec r = ((IncCompilerRun) rhs).spec;
+                       lhsSpec = l;
+                       rhsSpec = r;
+                       assertEquals(l.tag, r.tag);
+                       assertEquals(l.fresh, r.fresh);
+               } else {
+                       assertTrue(lhs.equals(rhs));
+                       return;
+               }
+               sameSpec(lhsSpec, rhsSpec, reporter);
        }
 
        public static void sameSpec(AbstractRunSpec lhs, AbstractRunSpec rhs, Assert a) {
-        if ((null == lhs) && (null == rhs)) {
-            return;
-        }
-        assertTrue(lhs != null);
-        assertTrue(rhs != null);
-        assertEquals(""+lhs.getOptionsList(), ""+rhs.getOptionsList());
-        sameList(lhs.getPathsList(), rhs.getPathsList(), a);
-        sameMessages(lhs.getMessages(), rhs.getMessages(), a);
-        sameDirChangesList(lhs.dirChanges, rhs.dirChanges, a);
+               if ((null == lhs) && (null == rhs)) {
+                       return;
+               }
+               assertTrue(lhs != null);
+               assertTrue(rhs != null);
+               assertEquals(""+lhs.getOptionsList(), ""+rhs.getOptionsList());
+               sameList(lhs.getPathsList(), rhs.getPathsList(), a);
+               sameMessages(lhs.getMessages(), rhs.getMessages(), a);
+               sameDirChangesList(lhs.dirChanges, rhs.dirChanges, a);
+       }
+
+       public static void sameDirChangesList(ArrayList<DirChanges.Spec> lhs, ArrayList<DirChanges.Spec> rhs, Assert a) {
+               if ((null == lhs) && (null == rhs)) {
+                       return;
+               }
+               assertTrue(rhs != null);
+               assertTrue(lhs != null);
+               sameListSize(lhs, rhs);
+               Iterator<DirChanges.Spec> lhsIter = lhs.iterator();
+               Iterator<DirChanges.Spec> rhsIter = rhs.iterator();
+               while (lhsIter.hasNext() && rhsIter.hasNext()) {
+                       sameDirChangesSpec(lhsIter.next(), rhsIter.next(), a);
+               }
        }
 
-       public static void sameDirChangesList(ArrayList lhs, ArrayList rhs, Assert a) {
-        if ((null == lhs) && (null == rhs)) {
-            return;
-        }
-        assertTrue(rhs != null);
-        assertTrue(lhs != null);
-        sameListSize(lhs, rhs);
-        Iterator lhsIter = lhs.iterator();
-        Iterator rhsIter = rhs.iterator();
-        while (lhsIter.hasNext() && rhsIter.hasNext()) {
-            sameDirChangesSpec((DirChanges.Spec) lhsIter.next(), (DirChanges.Spec) rhsIter.next(), a);
-        }
+       public static void sameDirChangesSpec(DirChanges.Spec lhs, DirChanges.Spec rhs, Assert a) {
+               if ((null == lhs) && (null == rhs)) {
+                       return;
+               }
+               assertTrue(rhs != null);
+               assertTrue(lhs != null);
+               assertEquals(lhs.defaultSuffix, rhs.defaultSuffix);
+               assertEquals(lhs.dirToken, rhs.dirToken);
+               assertEquals(lhs.fastFail, rhs.fastFail);
+               assertEquals(lhs.expDir, rhs.expDir); // XXX normalize?
+               sameList(lhs.updated, rhs.updated, a);
+               sameList(lhs.removed, rhs.removed, a);
+               sameList(lhs.added, rhs.added, a);
        }
 
-    public static void sameDirChangesSpec(DirChanges.Spec lhs, DirChanges.Spec rhs, Assert a) {
-        if ((null == lhs) && (null == rhs)) {
-            return;
-        }
-        assertTrue(rhs != null);
-        assertTrue(lhs != null);
-        assertEquals(lhs.defaultSuffix, rhs.defaultSuffix);        
-        assertEquals(lhs.dirToken, rhs.dirToken);
-        assertEquals(lhs.fastFail, rhs.fastFail);
-        assertEquals(lhs.expDir, rhs.expDir); // XXX normalize?
-        sameList(lhs.updated, rhs.updated, a);
-        sameList(lhs.removed, rhs.removed, a);
-        sameList(lhs.added, rhs.added, a);
-    }
+       public static void sameMessages(IMessageHolder one, IMessageHolder two, Assert a) {
+               if ((null == one) && (null == two)) {
+                       return;
+               }
+               // order matters here
+               ListIterator lhs = one.getUnmodifiableListView().listIterator();
+               ListIterator rhs = two.getUnmodifiableListView().listIterator();
+               while (lhs.hasNext() && rhs.hasNext()) {
+                       sameMessage((IMessage) lhs.next(), (IMessage) rhs.next(), a);
+               }
+               assertTrue(!lhs.hasNext());
+               assertTrue(!rhs.hasNext());
+       }
 
-    public static void sameMessages(IMessageHolder one, IMessageHolder two, Assert a) {
-        if ((null == one) && (null == two)) {
-            return;
-        }
-        // order matters here
-        ListIterator lhs = one.getUnmodifiableListView().listIterator();
-        ListIterator rhs = two.getUnmodifiableListView().listIterator();
-        while (lhs.hasNext() && rhs.hasNext()) {
-            sameMessage((IMessage) lhs.next(), (IMessage) rhs.next(), a);
-        }
-        assertTrue(!lhs.hasNext());        
-        assertTrue(!rhs.hasNext());        
-    }
+       public static void sameMessage(IMessage lhs, IMessage rhs, Assert a) {
+               if ((null == lhs) && (null == rhs)) {
+                       return;
+               }
+               assertTrue(lhs != null);
+               assertTrue(rhs != null);
+               assertTrue(lhs.getKind() == rhs.getKind());
+               same(lhs.getMessage(), rhs.getMessage(), a);
+               same(lhs.getDetails(), rhs.getDetails(), a);
+               assertEquals(lhs.getThrown(), rhs.getThrown());
+               sameSourceLocation(lhs.getSourceLocation(), rhs.getSourceLocation());
+               sameSourceLocations(lhs.getExtraSourceLocations(), rhs.getExtraSourceLocations());
+       }
+       public static void sameSourceLocations(List lhs, List rhs) {
+               sameListSize(lhs, rhs);
+               if ((null == lhs) || (0 == lhs.size())) {
+                       return;
+               }
+               // ok, do order-dependent check..
+               ListIterator iterLeft = lhs.listIterator();
+               ListIterator iterRight = rhs.listIterator();
+               while (iterLeft.hasNext() && iterRight.hasNext()) {
+                       ISourceLocation left = (ISourceLocation) iterLeft.next();
+                       ISourceLocation right = (ISourceLocation) iterRight.next();
+                       sameSourceLocation(left, right);
+               }
+               assertTrue(!iterLeft.hasNext());
+               assertTrue(!iterRight.hasNext());
 
-    public static void sameMessage(IMessage lhs, IMessage rhs, Assert a) {
-        if ((null == lhs) && (null == rhs)) {
-            return;
-        }
-        assertTrue(lhs != null);
-        assertTrue(rhs != null);
-        assertTrue(lhs.getKind() == rhs.getKind());
-        same(lhs.getMessage(), rhs.getMessage(), a);
-        same(lhs.getDetails(), rhs.getDetails(), a);
-        assertEquals(lhs.getThrown(), rhs.getThrown());
-        sameSourceLocation(lhs.getSourceLocation(), rhs.getSourceLocation());
-        sameSourceLocations(lhs.getExtraSourceLocations(), rhs.getExtraSourceLocations());        
        }
-    public static void sameSourceLocations(List lhs, List rhs) {
-        sameListSize(lhs, rhs);
-        if ((null == lhs) || (0 == lhs.size())) {
-            return;
-        }
-        // ok, do order-dependent check..
-        ListIterator iterLeft = lhs.listIterator(); 
-        ListIterator iterRight = rhs.listIterator(); 
-        while (iterLeft.hasNext() && iterRight.hasNext()) {
-            ISourceLocation left = (ISourceLocation) iterLeft.next();
-            ISourceLocation right = (ISourceLocation) iterRight.next();
-            sameSourceLocation(left, right);
-        }
-        assertTrue(!iterLeft.hasNext());
-        assertTrue(!iterRight.hasNext());
-        
-    }
 
        public static void sameSourceLocation(ISourceLocation lhs, ISourceLocation rhs) {
-        if ((null == lhs) && (null == rhs)) {
-            return;
-        }
-        assertTrue(lhs != null);
-        assertTrue(rhs != null);
-        assertTrue(lhs.getLine() == rhs.getLine());
-        assertTrue(lhs.getColumn() == rhs.getColumn());
-        assertTrue(lhs.getOffset() == rhs.getOffset());
-        assertTrue(lhs.getEndLine() == rhs.getEndLine());
-        // XXX need to compare files, permitting null == NONE        
+               if ((null == lhs) && (null == rhs)) {
+                       return;
+               }
+               assertTrue(lhs != null);
+               assertTrue(rhs != null);
+               assertTrue(lhs.getLine() == rhs.getLine());
+               assertTrue(lhs.getColumn() == rhs.getColumn());
+               assertTrue(lhs.getOffset() == rhs.getOffset());
+               assertTrue(lhs.getEndLine() == rhs.getEndLine());
+               // XXX need to compare files, permitting null == NONE
        }
 
        /**
@@ -345,34 +345,34 @@ public class AjcSpecTest extends TestCase {
        public AjcSpecTest(String name) {
                super(name);
        }
-    
-    public void testMinimal() {
-        AjcTest.Spec one = new AjcTest.Spec();
-        AjcTest.Spec two = new AjcTest.Spec();
-        // empty/identity tests
-        sameAjcTestSpec(one, two, this);
-        
-        one.addOption("-one");
-        one.addKeyword("keyword");
-        one.addPath("path");
-        IMessage m = MessageUtil.info("info message");
-        one.addMessage(m);
-        DirChanges.Spec dcspec = new DirChanges.Spec();
-        dcspec.setDirToken("dirToken");
-        dcspec.setDefaultSuffix(".suffix");
-        one.addDirChanges(dcspec);
 
-        // full/identity tests
-        sameAjcTestSpec(one, one, this);
-        // XXX need to clone...
+       public void testMinimal() {
+               AjcTest.Spec one = new AjcTest.Spec();
+               AjcTest.Spec two = new AjcTest.Spec();
+               // empty/identity tests
+               sameAjcTestSpec(one, two, this);
+
+               one.addOption("-one");
+               one.addKeyword("keyword");
+               one.addPath("path");
+               IMessage m = MessageUtil.info("info message");
+               one.addMessage(m);
+               DirChanges.Spec dcspec = new DirChanges.Spec();
+               dcspec.setDirToken("dirToken");
+               dcspec.setDefaultSuffix(".suffix");
+               one.addDirChanges(dcspec);
 
-        // XXX need to test that more differences are detected
-        boolean passed = false;
-        try {
-            sameAjcTestSpec(one, two, this);        
-        } catch (AssertionFailedError e) {
-            passed = true;
-        }
-        assertTrue("did not get expected exception", passed);
-    }
+               // full/identity tests
+               sameAjcTestSpec(one, one, this);
+               // XXX need to clone...
+
+               // XXX need to test that more differences are detected
+               boolean passed = false;
+               try {
+                       sameAjcTestSpec(one, two, this);
+               } catch (AssertionFailedError e) {
+                       passed = true;
+               }
+               assertTrue("did not get expected exception", passed);
+       }
 }
index c7e282040436f083f3d85900ff8386b7343cd362..7aa817f05a314c1c7fa05a6831d6b30d44b781f8 100644 (file)
@@ -1,13 +1,13 @@
 /* *******************************************************************
  * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xerox/PARC     initial implementation
  * ******************************************************************/
 
 package org.aspectj.testing.harness.bridge;
@@ -50,856 +50,897 @@ import org.aspectj.weaver.loadtime.WeavingURLClassLoader;
  */
 public class JavaRun implements IAjcRun {
 
-    private static void appendClasspath(StringBuffer cp, Object[] entries) {
-        if (!LangUtil.isEmpty(entries)) {
-            for (int i = 0; i < entries.length; i++) {
-                Object entry = entries[i];
-                if (entry instanceof String) {
-                    cp.append((String) entry);
-                    cp.append(File.pathSeparator);
-                } else if (entry instanceof File) {
-                    String s = FileUtil.getBestPath((File) entry);
-                    if (null != s) {
-                        cp.append(s);
-                        cp.append(File.pathSeparator);
-                    }
-                }
-            }
-        }
-    }
-    
-    Spec spec;
-       private Sandbox sandbox;   
-
-    /** programmatic initialization per spec */
-    public JavaRun(Spec spec) {
-        this.spec = spec;
-    }
-    // XXX init(Spec)
-    
-    /**
-     * This checks the spec for a class name
-     * and checks the sandbox for a readable test source directory,
-     * a writable run dir, and (non-null, possibly-empty) lists
-     * of readable classpath dirs and jars,
-     * and, if fork is enabled, that java can be read.
+       private static void appendClasspath(StringBuffer cp, Object[] entries) {
+               if (!LangUtil.isEmpty(entries)) {
+                       for (Object entry : entries) {
+                               if (entry instanceof String) {
+                                       cp.append((String) entry);
+                                       cp.append(File.pathSeparator);
+                               } else if (entry instanceof File) {
+                                       String s = FileUtil.getBestPath((File) entry);
+                                       if (null != s) {
+                                               cp.append(s);
+                                               cp.append(File.pathSeparator);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       Spec spec;
+       private Sandbox sandbox;
+
+       /** programmatic initialization per spec */
+       public JavaRun(Spec spec) {
+               this.spec = spec;
+       }
+       // XXX init(Spec)
+
+       /**
+        * This checks the spec for a class name
+        * and checks the sandbox for a readable test source directory,
+        * a writable run dir, and (non-null, possibly-empty) lists
+        * of readable classpath dirs and jars,
+        * and, if fork is enabled, that java can be read.
         * @return true if all checks pass
-     * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File)
+        * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File)
         */
+       @Override
        public boolean setupAjcRun(Sandbox sandbox, Validator validator) {
                this.sandbox = sandbox;
-        sandbox.javaRunInit(this);
+               sandbox.javaRunInit(this);
                return (validator.nullcheck(spec.className, "class name")
-            && validator.nullcheck(sandbox, "sandbox")
-            && validator.canReadDir(sandbox.getTestBaseSrcDir(this), "testBaseSrc dir")
-            && validator.canWriteDir(sandbox.runDir, "run dir")
-            && validator.canReadFiles(sandbox.getClasspathJars(true, this), "classpath jars")
-            && validator.canReadDirs(sandbox.getClasspathDirectories(true, this, true), "classpath dirs")
-            && (!spec.forkSpec.fork
-                    || validator.canRead(spec.forkSpec.java, "java"))
-            );            
-        
+                               && validator.nullcheck(sandbox, "sandbox")
+                               && validator.canReadDir(sandbox.getTestBaseSrcDir(this), "testBaseSrc dir")
+                               && validator.canWriteDir(sandbox.runDir, "run dir")
+                               && validator.canReadFiles(sandbox.getClasspathJars(true, this), "classpath jars")
+                               && validator.canReadDirs(sandbox.getClasspathDirectories(true, this, true), "classpath dirs")
+                               && (!spec.forkSpec.fork
+                                               || validator.canRead(spec.forkSpec.java, "java"))
+                               );
+
+       }
+
+       /** caller must record any exceptions */
+       @Override
+       public boolean run(IRunStatus status)
+                       throws IllegalAccessException,
+                       InvocationTargetException,
+                       ClassNotFoundException,
+                       NoSuchMethodException {
+               boolean completedNormally = false;
+               boolean passed = false;
+               if (!LangUtil.isEmpty(spec.dirChanges)) {
+                       MessageUtil.info(status, "XXX dirChanges not implemented in JavaRun");
+               }
+               try {
+                       final boolean readable = true;
+                       File[] libs = sandbox.getClasspathJars(readable, this);
+                       boolean includeClassesDir = true;
+                       File[] dirs = sandbox.getClasspathDirectories(readable, this, includeClassesDir);
+                       completedNormally = (spec.forkSpec.fork)
+                                       ? runInOtherVM(status, libs, dirs)
+                                                       : runInSameVM(status, libs, dirs);
+                                       passed = completedNormally;
+               } finally {
+                       if (!passed  || !status.runResult()) {
+                               MessageUtil.info(status, spec.toLongString());
+                               MessageUtil.info(status, "sandbox: " + sandbox);
+                       }
+               }
+               return passed;
+       }
+       protected boolean runInSameVM(IRunStatus status, File[] libs, File[] dirs) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+               ClassLoader loader = null;
+               boolean completedNormally = false;
+               boolean passed = false;
+               ByteArrayOutputStream outSnoop = null;
+               PrintStream oldOut = null;
+               ByteArrayOutputStream errSnoop = null;
+               PrintStream oldErr = null;
+               if (spec.outStreamIsError) {
+                       outSnoop = new ByteArrayOutputStream();
+                       oldOut = System.out;
+                       System.setOut(new PrintStream(outSnoop, true));
+               }
+               if (spec.errStreamIsError) {
+                       errSnoop = new ByteArrayOutputStream();
+                       oldErr = System.err;
+                       System.setErr(new PrintStream(errSnoop, true));
+               }
+               Class targetClass = null;
+               try {
+                       final URL[] clAndLibs;
+                       {
+                               File[] files = sandbox.findFiles(spec.classpath);
+                               URL[] clURLs = FileUtil.getFileURLs(files);
+                               URL[] libURLs = FileUtil.getFileURLs(libs);
+                               clAndLibs = new URL[clURLs.length + libURLs.length];
+                               System.arraycopy(clURLs, 0, clAndLibs , 0, clURLs.length);
+                               System.arraycopy(libURLs, 0, clAndLibs, clURLs.length, libURLs.length);
+                       }
+                       if (!spec.isLTW()) {
+                               loader = new TestClassLoader(clAndLibs, dirs);
+                       } else {
+                               final URL[] aspectURLs;
+                               {
+                                       File[] files = sandbox.findFiles(spec.aspectpath);
+                                       aspectURLs = FileUtil.getFileURLs(files);
+                               }
+                               ArrayList classpath = new ArrayList();
+                               classpath.addAll(Arrays.asList(aspectURLs));
+                               final URL[] classURLs;
+                               {
+                                       classpath.addAll(Arrays.asList(clAndLibs));
+                                       URL[] urls = FileUtil.getFileURLs(dirs);
+                                       classpath.addAll(Arrays.asList(urls));
+                                       classpath.add(FileUtil.getFileURL(Globals.F_aspectjrt_jar));
+                                       classpath.add(FileUtil.getFileURL(Globals.F_testingclient_jar));
+                                       classURLs = (URL[]) classpath.toArray(new URL[0]);
+                               }
+
+                               ClassLoader parent = JavaRun.class.getClassLoader();
+                               loader = new WeavingURLClassLoader(classURLs, aspectURLs, parent);
+                       }
+                       // make the following load test optional
+                       // Class testAspect = loader.loadClass("org.aspectj.lang.JoinPoint");
+                       targetClass = loader.loadClass(spec.className);
+                       Method main = targetClass.getMethod("main", Globals.MAIN_PARM_TYPES);
+                       setupTester(sandbox.getTestBaseSrcDir(this), loader, status);
+                       RunSecurityManager.ME.setJavaRunThread(this);
+                       main.invoke(null, new Object[] { spec.getOptionsArray() });
+                       completedNormally = true;
+                       boolean snoopFailure =
+                                       ((null != errSnoop) && 0 < errSnoop.size())
+                                       || ((null != outSnoop) && 0 < outSnoop.size());
+                       passed = !snoopFailure && (null == spec.expectedException);
+               } catch (AbortException e) {
+                       if (expectedException(e)) {
+                               passed = true;
+                       } else {
+                               throw e;
+                       }
+               } catch (InvocationTargetException e) {
+                       // this and following clauses catch ExitCalledException
+                       Throwable thrown = LangUtil.unwrapException(e);
+                       if (null == thrown) {
+                               throw e;
+                       }
+                       if (thrown instanceof RunSecurityManager.ExitCalledException) {
+                               int i = ((RunSecurityManager.ExitCalledException) thrown).exitCode;
+                               status.finish(new Integer(i));
+                       } else if (thrown instanceof RunSecurityManager.AwtUsedException) {
+                               MessageUtil.fail(status, "test code should not use the AWT event queue");
+                               throw (RunSecurityManager.AwtUsedException) thrown;
+                               // same as: status.thrown(thrown);
+                       } else if (expectedException(thrown)) {
+                               passed = true;
+                       } else if (thrown instanceof RuntimeException) {
+                               throw (RuntimeException) thrown;
+                       } else if (thrown instanceof Error) {
+                               throw (Error) thrown;
+                       } else {
+                               throw e;
+                       }
+               } catch (RunSecurityManager.ExitCalledException e) {
+                       // XXX need to update run validator (a) to accept null result or (b) to require zero result, and set 0 if completed normally
+                       status.finish(new Integer(e.exitCode));
+               } catch (ClassNotFoundException e) {
+                       String[] classes = FileUtil.listFiles(sandbox.classesDir);
+                       MessageUtil.info(status, "sandbox.classes: " + Arrays.asList(classes));
+                       MessageUtil.fail(status, null, e);
+               } finally {
+                       if (null != oldOut) {
+                               System.setOut(oldOut);
+                       }
+                       if (null != oldErr) {
+                               System.setErr(oldErr);
+                       }
+                       RunSecurityManager.ME.releaseJavaRunThread(this);
+                       if (!completedNormally) {
+                               MessageUtil.info(status, "targetClass: " + targetClass);
+                               MessageUtil.info(status, "loader: " + loader);
+                       }
+               }
+               return passed;
+       }
+
+       /**
+        * Run in another VM by grabbing Java, bootclasspath, classpath, etc.
+        * This assumes any exception or output to System.err is a failure,
+        * and any normal completion is a pass.
+        * @param status
+        * @param libs
+        * @param dirs
+        * @return
+        */
+       protected boolean runInOtherVM(IRunStatus status, File[] libs, File[] dirs) {
+               // assert spec.fork || !LangUtil.isEmpty(spec.aspectpath);
+               ArrayList<String> cmd = new ArrayList<>();
+               cmd.add(FileUtil.getBestPath(spec.forkSpec.java));
+               if (!LangUtil.isEmpty(spec.forkSpec.vmargs)) {
+                       cmd.addAll(Arrays.asList(spec.forkSpec.vmargs));
+               }
+               final String classpath;
+               {
+                       StringBuffer cp = new StringBuffer();
+                       appendClasspath(cp, spec.forkSpec.bootclasspath);
+                       appendClasspath(cp, dirs);
+                       appendClasspath(cp, libs);
+                       File[] classpathFiles = sandbox.findFiles(spec.classpath);
+                       int cpLength = (null == classpathFiles ? 0 : classpathFiles.length);
+                       int spLength = (null == spec.classpath ? 0 : spec.classpath.length);
+                       if (cpLength != spLength) {
+                               throw new Error("unable to find " + Arrays.asList(spec.classpath)
+                               + " got " + Arrays.asList(classpathFiles));
+                       }
+                       appendClasspath(cp, classpathFiles);
+                       File[] stdlibs = {Globals.F_aspectjrt_jar, Globals.F_testingclient_jar};
+                       appendClasspath(cp, stdlibs);
+                       classpath = cp.toString();
+               }
+               if (!spec.isLTW()) {
+                       cmd.add("-classpath");
+                       cmd.add(classpath);
+               } else {
+                       // verify 1.4 or above, assuming same vm as running this
+                       if (!Globals.supportsJava("1.4")) {
+                               throw new Error("load-time weaving test requires Java 1.4+");
+                       }
+                       cmd.add("-Djava.system.class.loader=org.aspectj.weaver.WeavingURLClassLoader");
+                       // assume harness VM classpath has WeavingURLClassLoader (but not others)
+                       cmd.add("-classpath");
+                       cmd.add(System.getProperty("java.class.path"));
+
+                       File[] aspectJars = sandbox.findFiles(spec.aspectpath);
+                       if (aspectJars.length != spec.aspectpath.length) {
+                               throw new Error("unable to find " + Arrays.asList(spec.aspectpath));
+                       }
+                       StringBuffer cp = new StringBuffer();
+                       appendClasspath(cp, aspectJars);
+                       cmd.add("-Daj.aspect.path=" + cp.toString());
+                       cp.append(classpath); // appendClasspath writes trailing delimiter
+                       cmd.add("-Daj.class.path=" + cp.toString());
+               }
+               cmd.add(spec.className);
+               cmd.addAll(spec.options);
+               String[] command = cmd.toArray(new String[0]);
+
+               final IMessageHandler handler = status;
+               // setup to run asynchronously, pipe streams through, and report errors
+               class DoneFlag {
+                       boolean done;
+                       boolean failed;
+                       int code;
+               }
+               final StringBuffer commandLabel = new StringBuffer();
+               final DoneFlag doneFlag = new DoneFlag();
+               LangUtil.ProcessController controller
+               = new LangUtil.ProcessController() {
+                       @Override
+                       protected void doCompleting(Thrown ex, int result) {
+                               if (!ex.thrown && (0 == result)) {
+                                       doneFlag.done = true;
+                                       return; // no errors
+                               }
+                               // handle errors
+                               String context = spec.className
+                                               + " command \""
+                                               + commandLabel
+                                               + "\"";
+                               if (null != ex.fromProcess) {
+                                       if (!expectedException(ex.fromProcess)) {
+                                               String m = "Exception running " + context;
+                                               MessageUtil.abort(handler, m, ex.fromProcess);
+                                               doneFlag.failed = true;
+                                       }
+                               } else if (0 != result) {
+                                       doneFlag.code = result;
+                               }
+                               if (null != ex.fromInPipe) {
+                                       String m = "Error processing input pipe for " + context;
+                                       MessageUtil.abort(handler, m, ex.fromInPipe);
+                                       doneFlag.failed = true;
+                               }
+                               if (null != ex.fromOutPipe) {
+                                       String m = "Error processing output pipe for " + context;
+                                       MessageUtil.abort(handler, m, ex.fromOutPipe);
+                                       doneFlag.failed = true;
+                               }
+                               if (null != ex.fromErrPipe) {
+                                       String m = "Error processing error pipe for " + context;
+                                       MessageUtil.abort(handler, m, ex.fromErrPipe);
+                                       doneFlag.failed = true;
+                               }
+                               doneFlag.done = true;
+                       }
+               };
+               controller.init(command, spec.className);
+               if (null != spec.forkSpec.javaHome) {
+                       controller.setEnvp(new String[] {"JAVA_HOME=" + spec.forkSpec.javaHome});
+               }
+               commandLabel.append(Arrays.asList(controller.getCommand()).toString());
+               final ByteArrayOutputStream errSnoop
+               = new ByteArrayOutputStream();
+               final ByteArrayOutputStream outSnoop
+               = new ByteArrayOutputStream();
+               controller.setErrSnoop(errSnoop);
+               controller.setOutSnoop(outSnoop);
+               controller.start();
+               // give it 3 minutes...
+               long maxTime = System.currentTimeMillis() + 3 * 60 * 1000;
+               boolean waitingForStop = false;
+               while (!doneFlag.done) {
+                       if (maxTime < System.currentTimeMillis()) {
+                               if (waitingForStop) { // hit second timeout - bail
+                                       break;
+                               }
+                               MessageUtil.fail(status, "timeout waiting for process");
+                               doneFlag.failed = true;
+                               controller.stop();
+                               // wait 1 minute to evaluate results of stopping
+                               waitingForStop = true;
+                               maxTime = System.currentTimeMillis() + 1 * 60 * 1000;
+                       }
+                       try {
+                               Thread.sleep(300);
+                       } catch (InterruptedException e) {
+                               // ignore
+                       }
+               }
+
+               boolean foundException = false;
+               if (0 < errSnoop.size()) {
+                       if (expectedException(errSnoop)) {
+                               foundException = true;
+                       } else if (spec.errStreamIsError) {
+                               MessageUtil.error(handler, errSnoop.toString());
+                               if (!doneFlag.failed) {
+                                       doneFlag.failed = true;
+                               }
+                       } else {
+                               MessageUtil.info(handler, "Error stream: " + errSnoop.toString());
+                       }
+               }
+               if (0 < outSnoop.size()) {
+                       if (expectedException(outSnoop)) {
+                               foundException = true;
+                       } else if (spec.outStreamIsError) {
+                               MessageUtil.error(handler, outSnoop.toString());
+                               if (!doneFlag.failed) {
+                                       doneFlag.failed = true;
+                               }
+                       } else {
+                               MessageUtil.info(handler, "Output stream: " + outSnoop.toString());
+                       }
+               }
+               if (!foundException) {
+                       if (null != spec.expectedException) {
+                               String m = " expected exception " + spec.expectedException;
+                               MessageUtil.fail(handler, m);
+                               doneFlag.failed = true;
+                       } else if (0 != doneFlag.code) {
+                               String m = doneFlag.code + " result from " + commandLabel;
+                               MessageUtil.fail(handler, m);
+                               doneFlag.failed = true;
+                       }
+               }
+               if (doneFlag.failed) {
+                       MessageUtil.info(handler, "other-vm command-line: " + commandLabel);
+               }
+               return !doneFlag.failed;
+       }
+
+       protected boolean expectedException(Throwable thrown) {
+               if (null != spec.expectedException) {
+                       String cname = thrown.getClass().getName();
+                       if (-1 != cname.indexOf(spec.expectedException)) {
+                               return true; // caller sets value for returns normally
+                       }
+               }
+               return false;
+       }
+
+       protected boolean expectedException(ByteArrayOutputStream bout) {
+               return ((null != spec.expectedException)
+                               && (-1 != bout.toString().indexOf(spec.expectedException)));
+       }
+
+       /**
+        * Clear (static) testing state and setup base directory,
+        * unless spec.skipTesting.
+        * @return null if successful, error message otherwise
+        */
+       protected void setupTester(File baseDir, ClassLoader loader, IMessageHandler handler) {
+               if (null == loader) {
+                       setupTester(baseDir, handler);
+                       return;
+               }
+               File baseDirSet = null;
+               try {
+                       if (!spec.skipTester) {
+                               Class tc = loader.loadClass("org.aspectj.testing.Tester");
+                               // Tester.clear();
+                               Method m = tc.getMethod("clear", new Class[0]);
+                               m.invoke(null, new Object[0]);
+                               // Tester.setMessageHandler(handler);
+                               m = tc.getMethod("setMessageHandler", new Class[] {IMessageHandler.class});
+                               m.invoke(null, new Object[] { handler});
+
+                               //Tester.setBASEDIR(baseDir);
+                               m = tc.getMethod("setBASEDIR", new Class[] {File.class});
+                               m.invoke(null, new Object[] { baseDir});
+
+                               //baseDirSet = Tester.getBASEDIR();
+                               m = tc.getMethod("getBASEDIR", new Class[0]);
+                               baseDirSet = (File) m.invoke(null, new Object[0]);
+
+                               if (!baseDirSet.equals(baseDir)) {
+                                       String l = "AjcScript.setupTester() setting "
+                                                       + baseDir + " returned " + baseDirSet;
+                                       MessageUtil.debug(handler, l);
+                               }
+                       }
+               } catch (Throwable t) {
+                       MessageUtil.abort(handler, "baseDir=" + baseDir, t);
+               }
        }
-    
-    /** caller must record any exceptions */
-    public boolean run(IRunStatus status)
-        throws IllegalAccessException,
-                InvocationTargetException,
-                ClassNotFoundException,
-                NoSuchMethodException {
-        boolean completedNormally = false;
-        boolean passed = false;
-        if (!LangUtil.isEmpty(spec.dirChanges)) {
-            MessageUtil.info(status, "XXX dirChanges not implemented in JavaRun");
-        }
-        try {
-            final boolean readable = true;
-            File[] libs = sandbox.getClasspathJars(readable, this);
-            boolean includeClassesDir = true;
-            File[] dirs = sandbox.getClasspathDirectories(readable, this, includeClassesDir);
-            completedNormally = (spec.forkSpec.fork)
-                ? runInOtherVM(status, libs, dirs)
-                : runInSameVM(status, libs, dirs);
-            passed = completedNormally;
-        } finally {
-            if (!passed  || !status.runResult()) {
-                MessageUtil.info(status, spec.toLongString());
-                MessageUtil.info(status, "sandbox: " + sandbox);
-            }
-        }
-        return passed;
-    }
-    protected boolean runInSameVM(IRunStatus status, File[] libs, File[] dirs) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-        ClassLoader loader = null;
-        boolean completedNormally = false;
-        boolean passed = false;
-        ByteArrayOutputStream outSnoop = null;
-        PrintStream oldOut = null;
-        ByteArrayOutputStream errSnoop = null;
-        PrintStream oldErr = null;
-        if (spec.outStreamIsError) {
-            outSnoop = new ByteArrayOutputStream();
-            oldOut = System.out;
-            System.setOut(new PrintStream(outSnoop, true));
-        }
-        if (spec.errStreamIsError) {
-            errSnoop = new ByteArrayOutputStream();
-            oldErr = System.err;
-            System.setErr(new PrintStream(errSnoop, true));
-        }
-        Class targetClass = null;
-        try {
-            final URL[] clAndLibs;
-            {
-                File[] files = sandbox.findFiles(spec.classpath);
-                URL[] clURLs = FileUtil.getFileURLs(files);
-                URL[] libURLs = FileUtil.getFileURLs(libs);
-                clAndLibs = new URL[clURLs.length + libURLs.length];
-                System.arraycopy(clURLs, 0, clAndLibs , 0, clURLs.length);
-                System.arraycopy(libURLs, 0, clAndLibs, clURLs.length, libURLs.length);
-            }
-            if (!spec.isLTW()) {
-                loader = new TestClassLoader(clAndLibs, dirs);                
-            } else {
-                final URL[] aspectURLs;
-                {
-                    File[] files = sandbox.findFiles(spec.aspectpath);
-                    aspectURLs = FileUtil.getFileURLs(files);
-                }
-                ArrayList classpath = new ArrayList();
-                classpath.addAll(Arrays.asList(aspectURLs));
-                final URL[] classURLs;
-                {
-                    classpath.addAll(Arrays.asList(clAndLibs));
-                    URL[] urls = FileUtil.getFileURLs(dirs);
-                    classpath.addAll(Arrays.asList(urls));
-                    classpath.add(FileUtil.getFileURL(Globals.F_aspectjrt_jar));
-                    classpath.add(FileUtil.getFileURL(Globals.F_testingclient_jar));
-                    classURLs = (URL[]) classpath.toArray(new URL[0]);
-                }
-                
-                ClassLoader parent = JavaRun.class.getClassLoader();
-                loader = new WeavingURLClassLoader(classURLs, aspectURLs, parent);
-            }
-            // make the following load test optional
-            // Class testAspect = loader.loadClass("org.aspectj.lang.JoinPoint");
-            targetClass = loader.loadClass(spec.className);
-            Method main = targetClass.getMethod("main", Globals.MAIN_PARM_TYPES);
-            setupTester(sandbox.getTestBaseSrcDir(this), loader, status);
-            RunSecurityManager.ME.setJavaRunThread(this);
-            main.invoke(null, new Object[] { spec.getOptionsArray() });
-            completedNormally = true;
-            boolean snoopFailure =
-                ((null != errSnoop) && 0 < errSnoop.size())
-                || ((null != outSnoop) && 0 < outSnoop.size());
-            passed = !snoopFailure && (null == spec.expectedException);
-        } catch (AbortException e) {
-            if (expectedException(e)) {
-                passed = true;
-            } else {
-                throw e;
-            }
-        } catch (InvocationTargetException e) {
-            // this and following clauses catch ExitCalledException
-            Throwable thrown = LangUtil.unwrapException(e);
-            if (null == thrown) {
-                throw e;
-            }
-            if (thrown instanceof RunSecurityManager.ExitCalledException) {
-                int i = ((RunSecurityManager.ExitCalledException) thrown).exitCode;
-                status.finish(new Integer(i));
-            } else if (thrown instanceof RunSecurityManager.AwtUsedException) {
-                MessageUtil.fail(status, "test code should not use the AWT event queue");
-                throw (RunSecurityManager.AwtUsedException) thrown;
-                // same as: status.thrown(thrown);
-            } else if (expectedException(thrown)) {
-                passed = true;
-            } else if (thrown instanceof RuntimeException) {
-                throw (RuntimeException) thrown;
-            } else if (thrown instanceof Error) {
-                throw (Error) thrown;
-            } else {
-                throw e; 
-            }
-        } catch (RunSecurityManager.ExitCalledException e) {
-            // XXX need to update run validator (a) to accept null result or (b) to require zero result, and set 0 if completed normally
-            status.finish(new Integer(e.exitCode));
-        } catch (ClassNotFoundException e) {
-            String[] classes = FileUtil.listFiles(sandbox.classesDir);
-            MessageUtil.info(status, "sandbox.classes: " + Arrays.asList(classes));
-            MessageUtil.fail(status, null, e);
-        } finally {
-            if (null != oldOut) {
-                System.setOut(oldOut);
-            }
-            if (null != oldErr) {
-                System.setErr(oldErr);
-            }
-            RunSecurityManager.ME.releaseJavaRunThread(this);
-            if (!completedNormally) {
-                MessageUtil.info(status, "targetClass: " + targetClass);
-                MessageUtil.info(status, "loader: " + loader);
-            }
-        }
-        return passed;
-    }
-    
-    /**
-     * Run in another VM by grabbing Java, bootclasspath, classpath, etc.
-     * This assumes any exception or output to System.err is a failure,
-     * and any normal completion is a pass.
-     * @param status
-     * @param libs
-     * @param dirs
-     * @return
-     */
-    protected boolean runInOtherVM(IRunStatus status, File[] libs, File[] dirs) {
-        // assert spec.fork || !LangUtil.isEmpty(spec.aspectpath);
-        ArrayList cmd = new ArrayList();
-        cmd.add(FileUtil.getBestPath(spec.forkSpec.java));
-        if (!LangUtil.isEmpty(spec.forkSpec.vmargs)) {
-            cmd.addAll(Arrays.asList(spec.forkSpec.vmargs));
-        }
-        final String classpath;
-        {
-            StringBuffer cp = new StringBuffer();
-            appendClasspath(cp, spec.forkSpec.bootclasspath);
-            appendClasspath(cp, dirs);        
-            appendClasspath(cp, libs);
-            File[] classpathFiles = sandbox.findFiles(spec.classpath);
-            int cpLength = (null == classpathFiles ? 0 : classpathFiles.length);
-            int spLength = (null == spec.classpath ? 0 : spec.classpath.length);
-            if (cpLength != spLength) {
-                throw new Error("unable to find " + Arrays.asList(spec.classpath)
-                        + " got " + Arrays.asList(classpathFiles));
-            }
-            appendClasspath(cp, classpathFiles);
-            File[] stdlibs = {Globals.F_aspectjrt_jar, Globals.F_testingclient_jar};
-            appendClasspath(cp, stdlibs);
-            classpath = cp.toString();
-        }
-        if (!spec.isLTW()) {
-            cmd.add("-classpath");
-            cmd.add(classpath);
-        } else {
-            // verify 1.4 or above, assuming same vm as running this
-            if (!Globals.supportsJava("1.4")) {
-                throw new Error("load-time weaving test requires Java 1.4+");
-            }
-            cmd.add("-Djava.system.class.loader=org.aspectj.weaver.WeavingURLClassLoader");
-            // assume harness VM classpath has WeavingURLClassLoader (but not others)
-            cmd.add("-classpath");
-            cmd.add(System.getProperty("java.class.path"));
-
-            File[] aspectJars = sandbox.findFiles(spec.aspectpath);
-            if (aspectJars.length != spec.aspectpath.length) {
-                throw new Error("unable to find " + Arrays.asList(spec.aspectpath));
-            }
-            StringBuffer cp = new StringBuffer();
-            appendClasspath(cp, aspectJars);
-            cmd.add("-Daj.aspect.path=" + cp.toString());
-            cp.append(classpath); // appendClasspath writes trailing delimiter
-            cmd.add("-Daj.class.path=" + cp.toString());
-        }
-        cmd.add(spec.className);
-        cmd.addAll(spec.options);
-        String[] command = (String[]) cmd.toArray(new String[0]);
-
-        final IMessageHandler handler = status;
-        // setup to run asynchronously, pipe streams through, and report errors
-        class DoneFlag {
-            boolean done;
-            boolean failed;
-            int code;
-        }
-        final StringBuffer commandLabel = new StringBuffer();
-        final DoneFlag doneFlag = new DoneFlag();
-        LangUtil.ProcessController controller
-            = new LangUtil.ProcessController() {
-                protected void doCompleting(Thrown ex, int result) {
-                    if (!ex.thrown && (0 == result)) {
-                        doneFlag.done = true;
-                        return; // no errors
-                    }
-                    // handle errors
-                    String context = spec.className 
-                        + " command \"" 
-                        + commandLabel 
-                        + "\"";
-                    if (null != ex.fromProcess) {
-                        if (!expectedException(ex.fromProcess)) {
-                            String m = "Exception running " + context;
-                            MessageUtil.abort(handler, m, ex.fromProcess);
-                            doneFlag.failed = true;
-                        }
-                    } else if (0 != result) {
-                        doneFlag.code = result;
-                    }
-                    if (null != ex.fromInPipe) {
-                        String m = "Error processing input pipe for " + context;
-                        MessageUtil.abort(handler, m, ex.fromInPipe);
-                        doneFlag.failed = true;
-                    }
-                    if (null != ex.fromOutPipe) {
-                        String m = "Error processing output pipe for " + context;
-                        MessageUtil.abort(handler, m, ex.fromOutPipe);
-                        doneFlag.failed = true;
-                    }
-                    if (null != ex.fromErrPipe) {
-                        String m = "Error processing error pipe for " + context;
-                        MessageUtil.abort(handler, m, ex.fromErrPipe);
-                        doneFlag.failed = true;
-                    }
-                    doneFlag.done = true;
-                }
-            };
-        controller.init(command, spec.className);
-        if (null != spec.forkSpec.javaHome) {
-            controller.setEnvp(new String[] {"JAVA_HOME=" + spec.forkSpec.javaHome});
-        }
-        commandLabel.append(Arrays.asList(controller.getCommand()).toString());
-        final ByteArrayOutputStream errSnoop 
-            = new ByteArrayOutputStream();
-        final ByteArrayOutputStream outSnoop 
-            = new ByteArrayOutputStream();
-        controller.setErrSnoop(errSnoop);
-        controller.setOutSnoop(outSnoop);
-        controller.start();
-        // give it 3 minutes...
-        long maxTime = System.currentTimeMillis() + 3 * 60 * 1000;
-        boolean waitingForStop = false;
-        while (!doneFlag.done) {
-            if (maxTime < System.currentTimeMillis()) {
-                if (waitingForStop) { // hit second timeout - bail
-                    break;
-                }
-                MessageUtil.fail(status, "timeout waiting for process"); 
-                doneFlag.failed = true;
-                controller.stop(); 
-                // wait 1 minute to evaluate results of stopping
-                waitingForStop = true;
-                maxTime = System.currentTimeMillis() + 1 * 60 * 1000;
-            }
-            try {
-                Thread.sleep(300);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-        }
-
-        boolean foundException = false;
-        if (0 < errSnoop.size()) {
-            if (expectedException(errSnoop)) {
-                foundException = true;
-            } else if (spec.errStreamIsError) {
-                MessageUtil.error(handler, errSnoop.toString());
-                if (!doneFlag.failed) {
-                    doneFlag.failed = true;
-                } 
-            } else {
-                MessageUtil.info(handler, "Error stream: " + errSnoop.toString());
-            }
-        }
-        if (0 < outSnoop.size()) {
-            if (expectedException(outSnoop)) {
-                foundException = true;
-            } else if (spec.outStreamIsError) {
-                MessageUtil.error(handler, outSnoop.toString());
-                if (!doneFlag.failed) {
-                    doneFlag.failed = true;
-                } 
-            } else {
-                MessageUtil.info(handler, "Output stream: " + outSnoop.toString());
-            }
-        }
-        if (!foundException) {
-            if (null != spec.expectedException) {
-                String m = " expected exception " + spec.expectedException;
-                MessageUtil.fail(handler, m);                
-                doneFlag.failed = true;
-            } else if (0 != doneFlag.code) {
-                String m = doneFlag.code + " result from " + commandLabel;
-                MessageUtil.fail(handler, m);
-                doneFlag.failed = true;
-            }
-        }
-        if (doneFlag.failed) {
-            MessageUtil.info(handler, "other-vm command-line: " + commandLabel);
-        }
-        return !doneFlag.failed;
-    }
-
-    protected boolean expectedException(Throwable thrown) {
-        if (null != spec.expectedException) {
-            String cname = thrown.getClass().getName();
-            if (-1 != cname.indexOf(spec.expectedException)) {
-                return true; // caller sets value for returns normally
-            }
-        }
-        return false;
-    }
-    
-    protected boolean expectedException(ByteArrayOutputStream bout) {
-        return ((null != spec.expectedException)
-                && (-1 != bout.toString().indexOf(spec.expectedException)));
-    }
-    
-    /**
-     * Clear (static) testing state and setup base directory,
-     * unless spec.skipTesting.
-     * @return null if successful, error message otherwise
-     */
-    protected void setupTester(File baseDir, ClassLoader loader, IMessageHandler handler) {
-        if (null == loader) {
-            setupTester(baseDir, handler);
-            return;
-        }
-        File baseDirSet = null;
-        try {
-            if (!spec.skipTester) { 
-                Class tc = loader.loadClass("org.aspectj.testing.Tester");
-                // Tester.clear();
-                Method m = tc.getMethod("clear", new Class[0]);
-                m.invoke(null, new Object[0]);             
-                // Tester.setMessageHandler(handler);
-                m = tc.getMethod("setMessageHandler", new Class[] {IMessageHandler.class});
-                m.invoke(null, new Object[] { handler});             
-                
-                //Tester.setBASEDIR(baseDir);
-                m = tc.getMethod("setBASEDIR", new Class[] {File.class});
-                m.invoke(null, new Object[] { baseDir});             
-
-                //baseDirSet = Tester.getBASEDIR();
-                m = tc.getMethod("getBASEDIR", new Class[0]);
-                baseDirSet = (File) m.invoke(null, new Object[0]);             
-                
-                if (!baseDirSet.equals(baseDir)) {
-                    String l = "AjcScript.setupTester() setting "
-                             + baseDir + " returned " + baseDirSet;
-                    MessageUtil.debug(handler, l);
-                }
-            }
-        } catch (Throwable t) {
-            MessageUtil.abort(handler, "baseDir=" + baseDir, t);
-        }
-    }
-
-    /**
-     * Clear (static) testing state and setup base directory,
-     * unless spec.skipTesting.
-     * This implementation assumes that Tester is defined for the
-     * same class loader as this class.
-     * @return null if successful, error message otherwise
-     */
-    protected void setupTester(File baseDir, IMessageHandler handler) {
-        File baseDirSet = null;
-        try {
-            if (!spec.skipTester) {                
-                Tester.clear();
-                Tester.setMessageHandler(handler);
-                Tester.setBASEDIR(baseDir);
-                baseDirSet = Tester.getBASEDIR();
-                if (!baseDirSet.equals(baseDir)) {
-                    String l = "AjcScript.setupTester() setting "
-                             + baseDir + " returned " + baseDirSet;
-                    MessageUtil.debug(handler, l);
-                }
-            }
-        } catch (Throwable t) {
-            MessageUtil.abort(handler, "baseDir=" + baseDir, t);
-        }
-    }
+
+       /**
+        * Clear (static) testing state and setup base directory,
+        * unless spec.skipTesting.
+        * This implementation assumes that Tester is defined for the
+        * same class loader as this class.
+        * @return null if successful, error message otherwise
+        */
+       protected void setupTester(File baseDir, IMessageHandler handler) {
+               File baseDirSet = null;
+               try {
+                       if (!spec.skipTester) {
+                               Tester.clear();
+                               Tester.setMessageHandler(handler);
+                               Tester.setBASEDIR(baseDir);
+                               baseDirSet = Tester.getBASEDIR();
+                               if (!baseDirSet.equals(baseDir)) {
+                                       String l = "AjcScript.setupTester() setting "
+                                                       + baseDir + " returned " + baseDirSet;
+                                       MessageUtil.debug(handler, l);
+                               }
+                       }
+               } catch (Throwable t) {
+                       MessageUtil.abort(handler, "baseDir=" + baseDir, t);
+               }
+       }
+       @Override
        public String toString() {
-        return "JavaRun(" + spec + ")";
+               return "JavaRun(" + spec + ")";
+       }
+
+       /**
+        * Struct class for fork attributes and initialization.
+        * This supports defaults for forking using system properties
+        * which will be overridden by any specification.
+        * (It differs from CompilerRun, which supports option
+        * overriding by passing values as harness arguments.)
+        */
+       public static class ForkSpec {
+               /**
+                * key for system property for default value for forking
+                * (true if set to true)
+                */
+               public static String FORK_KEY = "javarun.fork";
+               public static String JAVA_KEY = "javarun.java";
+               public static String VM_ARGS_KEY = "javarun.vmargs";
+               public static String JAVA_HOME_KEY = "javarun.java.home";
+               public static String BOOTCLASSPATH_KEY = "javarun.bootclasspath";
+               static final ForkSpec FORK;
+               static {
+                       ForkSpec fork  = new ForkSpec();
+                       fork.fork = Boolean.getBoolean(FORK_KEY);
+                       fork.java = getFile(JAVA_KEY);
+                       if (null == fork.java) {
+                               fork.java = LangUtil.getJavaExecutable();
+                       }
+                       fork.javaHome = getFile(JAVA_HOME_KEY);
+                       fork.bootclasspath = XMLWriter.unflattenList(getProperty(BOOTCLASSPATH_KEY));
+                       fork.vmargs = XMLWriter.unflattenList(getProperty(VM_ARGS_KEY));
+                       FORK = fork;
+               }
+               private static File getFile(String key) {
+                       String path = getProperty(key);
+                       if (null != path) {
+                               File result = new File(path);
+                               if (result.exists()) {
+                                       return result;
+                               }
+                       }
+                       return null;
+               }
+               private static String getProperty(String key) {
+                       try {
+                               return System.getProperty(key);
+                       } catch (Throwable t) {
+                               return null;
+                       }
+               }
+               private boolean fork;
+               private String[] bootclasspath;
+               private File java;
+               private File javaHome;
+               private String[] vmargs;
+
+               private ForkSpec() {
+                       copy(FORK);
+               }
+
+               private void copy(ForkSpec forkSpec) {
+                       if (null != forkSpec) {
+                               fork = forkSpec.fork;
+                               bootclasspath = forkSpec.bootclasspath;
+                               java = forkSpec.java;
+                               javaHome = forkSpec.javaHome;
+                               vmargs = forkSpec.vmargs;
+                       }
+               }
+
+               /**
+                * @return "" or bootclasspath with File.pathSeparator internal delimiters
+                */
+               String getBootclasspath() {
+                       if (LangUtil.isEmpty(bootclasspath)) {
+                               return "";
+                       }
+                       return FileUtil.flatten(bootclasspath, null);
+               }
+       }
+
+       /**
+        * Initializer/factory for JavaRun.
+        * The classpath is not here but precalculated in the Sandbox.
+        */
+       public static class Spec extends AbstractRunSpec {
+               static {
+                       try {
+                               System.setSecurityManager(RunSecurityManager.ME);
+                       } catch (Throwable t) {
+                               System.err.println("JavaRun: Security manager set - no System.exit() protection");
+                       }
+               }
+               public static final String XMLNAME = "run";
+               /**
+                * skip description, skip sourceLocation,
+                * do keywords, do options, skip paths, do comment,
+                * skip staging,   skip badInput,
+                * do dirChanges, do messages but skip children.
+                */
+               private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT,
+                               "", "", null, null, "", null, "", "", false, false, true);
+
+               /** fully-qualified name of the class to run */
+               protected String className;
+
+               /** Alternative to classname for specifying what to run modulename/type */
+               protected String module;
+
+               /** minimum required version of Java, if any */
+               protected String javaVersion;
+
+               /** if true, skip Tester setup (e.g., if Tester n/a) */
+               protected boolean skipTester;
+
+               /** if true, report text to output stream as error */
+               protected boolean outStreamIsError;
+
+               /** if true, report text to error stream as error */
+               protected boolean errStreamIsError = true;
+
+               protected final ForkSpec forkSpec;
+               protected String[] aspectpath;
+               protected boolean useLTW;
+               protected String[] classpath;
+               protected String expectedException;
+
+               public Spec() {
+                       super(XMLNAME);
+                       setXMLNames(NAMES);
+                       forkSpec = new ForkSpec();
+               }
+
+               protected void initClone(Spec spec)
+                               throws CloneNotSupportedException {
+                       super.initClone(spec);
+                       spec.className = className;
+                       spec.errStreamIsError = errStreamIsError;
+                       spec.javaVersion = javaVersion;
+                       spec.outStreamIsError = outStreamIsError;
+                       spec.skipTester = skipTester;
+                       spec.forkSpec.copy(forkSpec);
+               }
+
+               @Override
+               public Object clone() throws CloneNotSupportedException {
+                       Spec result = new Spec();
+                       initClone(result);
+                       return result;
+               }
+
+               public boolean isLTW() {
+                       return useLTW || (null != aspectpath);
+               }
+
+               /**
+                * @param version "1.1", "1.2", "1.3", "1.4"
+                * @throws IllegalArgumentException if version is not recognized
+                */
+               public void setJavaVersion(String version) {
+                       Globals.supportsJava(version);
+                       this.javaVersion = version;
+               }
+
+               /** @className fully-qualified name of the class to run */
+               public void setClassName(String className) {
+                       this.className = className;
+               }
+
+               public void setModule(String module) {
+                       this.module = module;
+               }
+
+               public void setLTW(String ltw) {
+                       useLTW = TestUtil.parseBoolean(ltw);
+               }
+
+               public void setAspectpath(String path) {
+                       this.aspectpath = XMLWriter.unflattenList(path);
+               }
+               public void setException(String exception) {
+                       this.expectedException = exception;
+               }
+
+               public void setClasspath(String path) {
+                       this.classpath = XMLWriter.unflattenList(path);
+               }
+               public void setErrStreamIsError(String errStreamIsError) {
+                       this.errStreamIsError = TestUtil.parseBoolean(errStreamIsError);
+               }
+
+               public void setOutStreamIsError(String outStreamIsError) {
+                       this.outStreamIsError = TestUtil.parseBoolean(outStreamIsError);
+               }
+
+               /** @param skip if true, then do not set up Tester */
+               public void setSkipTester(boolean skip) {
+                       skipTester = skip;
+               }
+
+               public void setFork(boolean fork) {
+                       forkSpec.fork = fork;
+               }
+
+               /**
+                * @param vmargs comma-delimited list of arguments for java,
+                * typically -Dname=value,-DanotherName="another value"
+                */
+               public void setVmArgs(String vmargs) {
+                       forkSpec.vmargs = XMLWriter.unflattenList(vmargs);
+               }
+
+               /** override to set dirToken to Sandbox.RUN_DIR */
+               @Override
+               public void addDirChanges(DirChanges.Spec spec) {
+                       if (null == spec) {
+                               return;
+                       }
+                       spec.setDirToken(Sandbox.RUN_DIR);
+                       super.addDirChanges(spec);
+               }
+
+               /** @return a JavaRun with this as spec if setup completes successfully. */
+               @Override
+               public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator) {
+                       JavaRun run = new JavaRun(this);
+                       if (run.setupAjcRun(sandbox, validator)) {
+                               // XXX need name for JavaRun
+                               return new WrappedRunIterator(this, run);
+                       }
+                       return null;
+               }
+
+               /**
+                * Write this out as a run element as defined in
+                * AjcSpecXmlReader.DOCTYPE.
+                * @see AjcSpecXmlReader#DOCTYPE
+                * @see IXmlWritable#writeXml(XMLWriter)
+                */
+               @Override
+               public void writeXml(XMLWriter out) {
+                       String attr = XMLWriter.makeAttribute("class", className);
+                       out.startElement(xmlElementName, attr, false);
+                       if (skipTester) {
+                               out.printAttribute("skipTester", "true");
+                       }
+                       if (null != javaVersion) {
+                               out.printAttribute("vm", javaVersion);
+                       }
+                       if (outStreamIsError) {
+                               out.printAttribute("outStreamIsError", "true");
+                       }
+                       if (!errStreamIsError) { // defaults to true
+                               out.printAttribute("errStreamIsError", "false");
+                       }
+                       super.writeAttributes(out);
+                       out.endAttributes();
+                       if (!LangUtil.isEmpty(dirChanges)) {
+                               DirChanges.Spec.writeXml(out, dirChanges);
+                       }
+                       SoftMessage.writeXml(out, getMessages());
+                       out.endElement(xmlElementName);
+               }
+               @Override
+               public String toLongString() {
+                       return toString() + "[" + super.toLongString() + "]";
+               }
+
+               @Override
+               public String toString() {
+                       if (skipTester) {
+                               return "JavaRun(" + className + ", skipTester)";
+                       } else {
+                               return "JavaRun(" + className + ")";
+                       }
+               }
+
+               /**
+                * This implementation skips if:
+                * <ul>
+                * <li>current VM is not at least any specified javaVersion </li>
+                * </ul>
+                * @return false if this wants to be skipped, true otherwise
+                */
+               @Override
+               protected boolean doAdoptParentValues(RT parentRuntime, IMessageHandler handler) {
+                       if (!super.doAdoptParentValues(parentRuntime, handler)) {
+                               return false;
+                       }
+                       if ((null != javaVersion) && (!Globals.supportsJava(javaVersion))) {
+                               skipMessage(handler, "requires Java version " + javaVersion);
+                               return false;
+                       }
+                       return true;
+               }
+       }
+       /**
+        * This permits everything but System.exit() in the context of a
+        * thread set by JavaRun.
+        * XXX need to update for thread spawned by that thread
+        * XXX need to update for awt thread use after AJDE wrapper doesn't
+        */
+       public static class RunSecurityManager extends SecurityManager {
+               public static RunSecurityManager ME = new RunSecurityManager();
+               private Thread runThread;
+               private RunSecurityManager(){}
+               private synchronized void setJavaRunThread(JavaRun run) {
+                       LangUtil.throwIaxIfNull(run, "run");
+                       runThread = Thread.currentThread();
+               }
+               private synchronized void releaseJavaRunThread(JavaRun run) {
+                       LangUtil.throwIaxIfNull(run, "run");
+                       runThread = null;
+               }
+               /** @throws ExitCalledException if called from the JavaRun-set thread */
+               @Override
+               public void checkExit(int exitCode) throws ExitCalledException {
+                       if ((null != runThread) && runThread.equals(Thread.currentThread())) {
+                               throw new ExitCalledException(exitCode);
+                       }
+               }
+               @Override
+               public void checkAwtEventQueueAccess() {
+                       if ((null != runThread) && runThread.equals(Thread.currentThread())) {
+                               throw new AwtUsedException();
+                       }
+               }
+               @Override
+               public void checkSystemClipboardAccess() {
+                       // permit
+               }
+               // used by constrained calls
+               public static class ExitCalledException extends SecurityException {
+                       public final int exitCode;
+                       public ExitCalledException(int exitCode) {
+                               this.exitCode = exitCode;
+                       }
+               }
+               public static class AwtUsedException extends SecurityException {
+                       public AwtUsedException() { }
+               }
+               // permit everything else
+               @Override
+               public void checkAccept(String arg0, int arg1) {
+               }
+               @Override
+               public void checkAccess(Thread arg0) {
+               }
+               @Override
+               public void checkAccess(ThreadGroup arg0) {
+               }
+               @Override
+               public void checkConnect(String arg0, int arg1) {
+               }
+               @Override
+               public void checkConnect(String arg0, int arg1, Object arg2) {
+               }
+               @Override
+               public void checkCreateClassLoader() {
+               }
+               @Override
+               public void checkDelete(String arg0) {
+               }
+               @Override
+               public void checkExec(String arg0) {
+               }
+               @Override
+               public void checkLink(String arg0) {
+               }
+               @Override
+               public void checkListen(int arg0) {
+               }
+               @Override
+               public void checkMemberAccess(Class arg0, int arg1) {
+               }
+               @Override
+               public void checkMulticast(InetAddress arg0) {
+               }
+               @Override
+               public void checkMulticast(InetAddress arg0, byte arg1) {
+               }
+               @Override
+               public void checkPackageAccess(String arg0) {
+               }
+               @Override
+               public void checkPackageDefinition(String arg0) {
+               }
+               @Override
+               public void checkPermission(Permission arg0) {
+               }
+               @Override
+               public void checkPermission(Permission arg0, Object arg1) {
+               }
+               @Override
+               public void checkPrintJobAccess() {
+               }
+               @Override
+               public void checkPropertiesAccess() {
+               }
+               @Override
+               public void checkPropertyAccess(String arg0) {
+               }
+               @Override
+               public void checkRead(FileDescriptor arg0) {
+               }
+               @Override
+               public void checkRead(String arg0) {
+               }
+               @Override
+               public void checkRead(String arg0, Object arg1) {
+               }
+               @Override
+               public void checkSecurityAccess(String arg0) {
+               }
+               @Override
+               public void checkSetFactory() {
+               }
+               @Override
+               public boolean checkTopLevelWindow(Object arg0) {
+                       return true;
+               }
+               @Override
+               public void checkWrite(FileDescriptor arg0) {
+               }
+               @Override
+               public void checkWrite(String arg0) {
+               }
+
        }
-        
-    /**
-     * Struct class for fork attributes and initialization.
-     * This supports defaults for forking using system properties
-     * which will be overridden by any specification.
-     * (It differs from CompilerRun, which supports option 
-     * overriding by passing values as harness arguments.)
-     */
-    public static class ForkSpec {
-        /**
-         * key for system property for default value for forking
-         * (true if set to true)
-         */
-        public static String FORK_KEY = "javarun.fork";
-        public static String JAVA_KEY = "javarun.java";
-        public static String VM_ARGS_KEY = "javarun.vmargs";
-        public static String JAVA_HOME_KEY = "javarun.java.home";
-        public static String BOOTCLASSPATH_KEY = "javarun.bootclasspath";
-        static final ForkSpec FORK;
-        static {
-            ForkSpec fork  = new ForkSpec();
-            fork.fork = Boolean.getBoolean(FORK_KEY);
-            fork.java = getFile(JAVA_KEY);
-            if (null == fork.java) {
-                fork.java = LangUtil.getJavaExecutable();
-            }
-            fork.javaHome = getFile(JAVA_HOME_KEY);
-            fork.bootclasspath = XMLWriter.unflattenList(getProperty(BOOTCLASSPATH_KEY));
-            fork.vmargs = XMLWriter.unflattenList(getProperty(VM_ARGS_KEY));
-            FORK = fork;
-        }
-        private static File getFile(String key) {
-            String path = getProperty(key);
-            if (null != path) {
-                File result = new File(path);
-                if (result.exists()) {
-                    return result;
-                }
-            }
-            return null;
-        }
-        private static String getProperty(String key) {
-            try {
-                return System.getProperty(key);
-            } catch (Throwable t) {
-                return null;
-            }
-        }
-        private boolean fork;
-        private String[] bootclasspath;
-        private File java;
-        private File javaHome;
-        private String[] vmargs;
-
-        private ForkSpec() {
-            copy(FORK);
-        }
-        
-        private void copy(ForkSpec forkSpec) {
-            if (null != forkSpec) {
-                fork = forkSpec.fork;
-                bootclasspath = forkSpec.bootclasspath;
-                java = forkSpec.java;
-                javaHome = forkSpec.javaHome;
-                vmargs = forkSpec.vmargs;
-            }
-        }
-
-        /**
-         * @return "" or bootclasspath with File.pathSeparator internal delimiters
-         */
-        String getBootclasspath() {
-            if (LangUtil.isEmpty(bootclasspath)) {
-                return "";
-            }
-            return FileUtil.flatten(bootclasspath, null);
-        }
-    }
-    
-    /** 
-     * Initializer/factory for JavaRun.
-     * The classpath is not here but precalculated in the Sandbox.
-     */
-    public static class Spec extends AbstractRunSpec {
-        static {
-            try {
-                System.setSecurityManager(RunSecurityManager.ME);
-            } catch (Throwable t) {
-                System.err.println("JavaRun: Security manager set - no System.exit() protection");
-            }
-        }
-        public static final String XMLNAME = "run";
-        /**
-         * skip description, skip sourceLocation, 
-         * do keywords, do options, skip paths, do comment,
-         * skip staging,   skip badInput,
-         * do dirChanges, do messages but skip children. 
-         */
-        private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT,
-                "", "", null, null, "", null, "", "", false, false, true);
-                
-        /** fully-qualified name of the class to run */
-        protected String className;
-        
-        /** Alternative to classname for specifying what to run modulename/type */
-        protected String module;
-        
-        /** minimum required version of Java, if any */
-        protected String javaVersion;
-        
-        /** if true, skip Tester setup (e.g., if Tester n/a) */
-        protected boolean skipTester;
-        
-        /** if true, report text to output stream as error */
-        protected boolean outStreamIsError;
-
-        /** if true, report text to error stream as error */
-        protected boolean errStreamIsError = true;
-        
-        protected final ForkSpec forkSpec;
-        protected String[] aspectpath;
-        protected boolean useLTW;
-        protected String[] classpath;
-        protected String expectedException;
-        
-        public Spec() {
-            super(XMLNAME);
-            setXMLNames(NAMES);
-            forkSpec = new ForkSpec();
-        }
-        
-        protected void initClone(Spec spec) 
-                throws CloneNotSupportedException {
-            super.initClone(spec);
-            spec.className = className;            
-            spec.errStreamIsError = errStreamIsError;
-            spec.javaVersion = javaVersion;
-            spec.outStreamIsError = outStreamIsError;
-            spec.skipTester = skipTester;
-            spec.forkSpec.copy(forkSpec);
-        }
-        
-        public Object clone() throws CloneNotSupportedException {
-            Spec result = new Spec();
-            initClone(result);
-            return result;    
-        }
-
-        public boolean isLTW() {
-            return useLTW || (null != aspectpath);
-        }
-        
-        /**
-         * @param version "1.1", "1.2", "1.3", "1.4"
-         * @throws IllegalArgumentException if version is not recognized
-         */
-        public void setJavaVersion(String version) {
-               Globals.supportsJava(version);
-            this.javaVersion = version;
-        }
-        
-        /** @className fully-qualified name of the class to run */
-        public void setClassName(String className) {
-            this.className = className;
-        }
-        
-        public void setModule(String module) {
-            this.module = module;
-        }
-
-        public void setLTW(String ltw) {
-            useLTW = TestUtil.parseBoolean(ltw);
-        }
-        
-        public void setAspectpath(String path) {
-            this.aspectpath = XMLWriter.unflattenList(path);
-        }
-        public void setException(String exception) {
-            this.expectedException = exception;
-        }
-        
-        public void setClasspath(String path) {
-            this.classpath = XMLWriter.unflattenList(path);
-        }
-        public void setErrStreamIsError(String errStreamIsError) {
-            this.errStreamIsError = TestUtil.parseBoolean(errStreamIsError);
-        }
-
-        public void setOutStreamIsError(String outStreamIsError) {
-            this.outStreamIsError = TestUtil.parseBoolean(outStreamIsError);
-        }
-
-        /** @param skip if true, then do not set up Tester */
-        public void setSkipTester(boolean skip) {
-            skipTester = skip;
-        }
-        
-        public void setFork(boolean fork) {
-            forkSpec.fork = fork;
-        }
-        
-        /**
-         * @param vmargs comma-delimited list of arguments for java,
-         * typically -Dname=value,-DanotherName="another value"
-         */
-        public void setVmArgs(String vmargs) {
-            forkSpec.vmargs = XMLWriter.unflattenList(vmargs);
-        }
-        
-        /** override to set dirToken to Sandbox.RUN_DIR */
-        public void addDirChanges(DirChanges.Spec spec) {
-            if (null == spec) {
-                return;
-            }
-            spec.setDirToken(Sandbox.RUN_DIR);
-            super.addDirChanges(spec);
-        }
-
-        /** @return a JavaRun with this as spec if setup completes successfully. */
-        public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator) {
-            JavaRun run = new JavaRun(this);
-            if (run.setupAjcRun(sandbox, validator)) {
-                // XXX need name for JavaRun
-                return new WrappedRunIterator(this, run);
-            }
-            return null;
-        }
-
-        /** 
-         * Write this out as a run element as defined in
-         * AjcSpecXmlReader.DOCTYPE.
-         * @see AjcSpecXmlReader#DOCTYPE 
-         * @see IXmlWritable#writeXml(XMLWriter) 
-         */
-        public void writeXml(XMLWriter out) {
-            String attr = XMLWriter.makeAttribute("class", className);
-            out.startElement(xmlElementName, attr, false);
-            if (skipTester) {
-                out.printAttribute("skipTester", "true");
-            }
-            if (null != javaVersion) {
-                out.printAttribute("vm", javaVersion);
-            }
-            if (outStreamIsError) {
-                out.printAttribute("outStreamIsError", "true");
-            }
-            if (!errStreamIsError) { // defaults to true
-                out.printAttribute("errStreamIsError", "false");
-            }
-            super.writeAttributes(out);
-            out.endAttributes();
-            if (!LangUtil.isEmpty(dirChanges)) {
-                DirChanges.Spec.writeXml(out, dirChanges);
-            }
-            SoftMessage.writeXml(out, getMessages());
-            out.endElement(xmlElementName);
-        }
-        public String toLongString() {
-            return toString() + "[" + super.toLongString() + "]";        
-        }
-        
-        public String toString() {
-            if (skipTester) {
-                return "JavaRun(" + className + ", skipTester)";
-            } else {
-                return "JavaRun(" + className + ")";
-            }
-        }
-        
-        /**
-         * This implementation skips if:
-         * <ul>
-         * <li>current VM is not at least any specified javaVersion </li>
-         * </ul>
-         * @return false if this wants to be skipped, true otherwise
-         */
-        protected boolean doAdoptParentValues(RT parentRuntime, IMessageHandler handler) {
-            if (!super.doAdoptParentValues(parentRuntime, handler)) {
-                return false;
-            }
-            if ((null != javaVersion) && (!Globals.supportsJava(javaVersion))) {
-                skipMessage(handler, "requires Java version " + javaVersion);
-                return false;
-            }
-            return true;
-        }  
-     }
-    /**
-     * This permits everything but System.exit() in the context of a 
-     * thread set by JavaRun.
-     * XXX need to update for thread spawned by that thread
-     * XXX need to update for awt thread use after AJDE wrapper doesn't
-     */
-    public static class RunSecurityManager extends SecurityManager {
-        public static RunSecurityManager ME = new RunSecurityManager();
-        private Thread runThread;
-        private RunSecurityManager(){}
-        private synchronized void setJavaRunThread(JavaRun run) {
-            LangUtil.throwIaxIfNull(run, "run");
-            runThread = Thread.currentThread();
-        }
-        private synchronized void releaseJavaRunThread(JavaRun run) {
-            LangUtil.throwIaxIfNull(run, "run");
-            runThread = null;
-        }
-        /** @throws ExitCalledException if called from the JavaRun-set thread */
-        public void checkExit(int exitCode) throws ExitCalledException {
-            if ((null != runThread) && runThread.equals(Thread.currentThread())) {
-                throw new ExitCalledException(exitCode);
-            }
-        }
-        public void checkAwtEventQueueAccess() {
-            if ((null != runThread) && runThread.equals(Thread.currentThread())) {
-                throw new AwtUsedException();
-            }
-        }
-        public void checkSystemClipboardAccess() {
-            // permit
-        }
-        // used by constrained calls
-        public static class ExitCalledException extends SecurityException {
-            public final int exitCode;
-            public ExitCalledException(int exitCode) {
-                this.exitCode = exitCode;
-            }
-        }
-        public static class AwtUsedException extends SecurityException {
-            public AwtUsedException() { }
-        }
-        // permit everything else
-        public void checkAccept(String arg0, int arg1) {
-        }
-        public void checkAccess(Thread arg0) {
-        }
-        public void checkAccess(ThreadGroup arg0) {
-        }
-        public void checkConnect(String arg0, int arg1) {
-        }
-        public void checkConnect(String arg0, int arg1, Object arg2) {
-        }
-        public void checkCreateClassLoader() {
-        }
-        public void checkDelete(String arg0) {
-        }
-        public void checkExec(String arg0) {
-        }
-        public void checkLink(String arg0) {
-        }
-        public void checkListen(int arg0) {
-        }
-        public void checkMemberAccess(Class arg0, int arg1) {
-        }
-        public void checkMulticast(InetAddress arg0) {
-        }
-        public void checkMulticast(InetAddress arg0, byte arg1) {
-        }
-        public void checkPackageAccess(String arg0) {
-        }
-        public void checkPackageDefinition(String arg0) {
-        }
-        public void checkPermission(Permission arg0) {
-        }
-        public void checkPermission(Permission arg0, Object arg1) {
-        }
-        public void checkPrintJobAccess() {
-        }
-        public void checkPropertiesAccess() {
-        }
-        public void checkPropertyAccess(String arg0) {
-        }
-        public void checkRead(FileDescriptor arg0) {
-        }
-        public void checkRead(String arg0) {
-        }
-        public void checkRead(String arg0, Object arg1) {
-        }
-        public void checkSecurityAccess(String arg0) {
-        }
-        public void checkSetFactory() {
-        }
-        public boolean checkTopLevelWindow(Object arg0) {
-            return true;
-        }
-        public void checkWrite(FileDescriptor arg0) {
-        }
-        public void checkWrite(String arg0) {
-        }
-        
-    }
 
 }
index 37ddd005eee6e3ac80a9d5d3f68118d177e4db22..5bb1a15b24381b14410591af153601539ab0e1cc 100644 (file)
@@ -1,13 +1,13 @@
 /* *******************************************************************
  * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xerox/PARC     initial implementation
  * ******************************************************************/
 
 package org.aspectj.testing.harness.bridge;
@@ -27,7 +27,7 @@ import org.aspectj.bridge.MessageUtil;
 import org.aspectj.util.FileUtil;
 import org.aspectj.util.LangUtil;
 
-/** 
+/**
  * Check input and implement defaults.
  * This handles failure messaging and collecting temp directories
  * for later cleanup.
@@ -42,518 +42,518 @@ import org.aspectj.util.LangUtil;
  * not change the reporting scheme established by the caller,
  * so the caller may lock and unlock the error handling policy.
  * When the policy is locked, this silently ignores attempts
- * to toggle exceptions, or delete temporary files. 
+ * to toggle exceptions, or delete temporary files.
  * XXX callers cannot prevent others from pushing other error handlers.
  */
 public class Validator {
-    
-    /** stack of handlers */
-    private final Stack handlers;
-    
-    /** list of File registered for deletion on demand */
-    private final ArrayList tempFiles; // deleteTempFiles requires ListIterator.remove()
-    
-    /** list of Sandboxes registered for cleanup on demand  */
-    private final ArrayList sandboxes;
-    
-    /** if true, throw AbortException on failure */
-    boolean abortOnFailure;
-    
-    /** this object prevents any changes to error-handling policy */
-    private Object locker;
-    
-    public Validator(IMessageHandler handler) {
-        tempFiles = new ArrayList();
-        sandboxes = new ArrayList();
-        handlers = new Stack();
-        pushHandler(handler);
-    } 
-    
-    /** 
-     * Push IMessageHandler onto stack,
-     * so it will be used until the next push or pop
-     * @param handler not null
-     * 
-     */
-    public void pushHandler(IMessageHandler handler) {
-       LangUtil.throwIaxIfNull(handler, "handler");
+
+       /** stack of handlers */
+       private final Stack<IMessageHandler> handlers;
+
+       /** list of File registered for deletion on demand */
+       private final ArrayList<File> tempFiles; // deleteTempFiles requires ListIterator.remove()
+
+       /** list of Sandboxes registered for cleanup on demand  */
+       private final ArrayList<Sandbox> sandboxes;
+
+       /** if true, throw AbortException on failure */
+       boolean abortOnFailure;
+
+       /** this object prevents any changes to error-handling policy */
+       private Object locker;
+
+       public Validator(IMessageHandler handler) {
+               tempFiles = new ArrayList<>();
+               sandboxes = new ArrayList<>();
+               handlers = new Stack<>();
+               pushHandler(handler);
+       }
+
+       /**
+        * Push IMessageHandler onto stack,
+        * so it will be used until the next push or pop
+        * @param handler not null
+        *
+        */
+       public void pushHandler(IMessageHandler handler) {
+               LangUtil.throwIaxIfNull(handler, "handler");
                handlers.push(handler);
-    }
-    
-    /** @throws IllegalStateException if handler is not on top */
-    public void popHandler(IMessageHandler handler) {
-       LangUtil.throwIaxIfNull(handler, "handler");
+       }
+
+       /** @throws IllegalStateException if handler is not on top */
+       public void popHandler(IMessageHandler handler) {
+               LangUtil.throwIaxIfNull(handler, "handler");
                if (handler != handlers.peek()) {
                        throw new IllegalStateException("not current handler");
                }
                handlers.pop();
-    }
-    
-    /** @return true if this requestor now has locked the error handling policy */
-    public boolean lock(Object requestor) {
-        if (null == locker) {
-            locker = requestor;
-        }
-        return (locker == requestor);
-    }
-
-    /** @return true if the error handling policy is now unlocked  */
-    public boolean unlock(Object requestor) {
-        if (requestor == locker) {
-            locker = null;
-        }
-        return (locker == null);
-    }
-    
-    public void setAbortOnFailure(boolean abortOnFailure) {
-        if (null == locker) {
-            if (this.abortOnFailure != abortOnFailure) {
-                this.abortOnFailure = abortOnFailure;
-            }
-        }
-    }
-        
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} array<li>
-     * <li>{null check} {message}[#}<li>
-     */
-    public boolean nullcheck(Object[] ra, String message) {
-        return ((nullcheck((Object) ra, message + " array"))
-                && nullcheck(Arrays.asList(ra), message));
-    }
-    
-    /**
-     * Like nullcheck(Collection, message), except adding lower and upper bound
-     * @param atLeast fail if list size is smaller than this
-     * @param atMost  fail if list size is greater than this
-     */
-    public boolean nullcheck(Collection list, int atLeast, int atMost, String message) {
-        if (nullcheck(list, message)) {
-            int size = list.size();
-            if (size < atLeast) {
-                fail(message + ": " + size + "<" + atLeast);
-            } else if (size > atMost) {
-                fail(message + ": " + size + ">" + atMost);
-            } else {
-                return true;
-            }
-        }
-        return false;
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} list<li>
-     * <li>{null check} {message}[#}<li>
-     */
-    public boolean nullcheck(Collection list, String message) {
-        if (nullcheck((Object) list, message + " list")) {
-            int i = 0;
-            for (Iterator iter = list.iterator(); iter.hasNext();) {
+       }
+
+       /** @return true if this requestor now has locked the error handling policy */
+       public boolean lock(Object requestor) {
+               if (null == locker) {
+                       locker = requestor;
+               }
+               return (locker == requestor);
+       }
+
+       /** @return true if the error handling policy is now unlocked  */
+       public boolean unlock(Object requestor) {
+               if (requestor == locker) {
+                       locker = null;
+               }
+               return (locker == null);
+       }
+
+       public void setAbortOnFailure(boolean abortOnFailure) {
+               if (null == locker) {
+                       if (this.abortOnFailure != abortOnFailure) {
+                               this.abortOnFailure = abortOnFailure;
+                       }
+               }
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} array<li>
+        * <li>{null check} {message}[#}<li>
+        */
+       public boolean nullcheck(Object[] ra, String message) {
+               return ((nullcheck((Object) ra, message + " array"))
+                               && nullcheck(Arrays.asList(ra), message));
+       }
+
+       /**
+        * Like nullcheck(Collection, message), except adding lower and upper bound
+        * @param atLeast fail if list size is smaller than this
+        * @param atMost  fail if list size is greater than this
+        */
+       public boolean nullcheck(Collection list, int atLeast, int atMost, String message) {
+               if (nullcheck(list, message)) {
+                       int size = list.size();
+                       if (size < atLeast) {
+                               fail(message + ": " + size + "<" + atLeast);
+                       } else if (size > atMost) {
+                               fail(message + ": " + size + ">" + atMost);
+                       } else {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} list<li>
+        * <li>{null check} {message}[#}<li>
+        */
+       public boolean nullcheck(Collection list, String message) {
+               if (nullcheck((Object) list, message + " list")) {
+                       int i = 0;
+                       for (Iterator iter = list.iterator(); iter.hasNext();) {
                                if (!nullcheck(iter.next(), message + "[" + i++ + "]")) {
-                            return false;
-                }              
+                                       return false;
+                               }
                        }
-            return true;
-        }
-        return false;
-    }
-    
-    /** 
-     * May fail with the message "null {message}" 
-     * if o and the def{ault} are null
-     * @return o if not null or default otherwise
-     */
-    public Object nulldefault(Object o, String message, Object def) {
-        if (null == o) {
-            o = def;
-        }
-        nullcheck(o, message);
-        return o;
-    }
-
-    /** may fail with the message "null {message}" */
-    public boolean nullcheck(Object o, String message) {
-        if (null == o) {
-            if (null == message) message = "object";
-            fail("null " + message);
-            return false;
-        }
-        return true;
-    }
-    
-    /**
-     * Verify that all paths are readable relative to baseDir. 
-     * may fail with the message "cannot read {file}" 
-     */
-    public boolean canRead(File baseDir, String[] paths, String message) {
-        if (!canRead(baseDir, "baseDir - " + message)
-            || !nullcheck(paths, "paths - " + message)) {
-            return false;
-        }
-        final String dirPath = baseDir.getPath();
-        File[] files = FileUtil.getBaseDirFiles(baseDir, paths);
-        for (int j = 0; j < files.length; j++) {
-            if (!canRead(files[j], "{" + dirPath + "} " + files[j])) {
-                return false;
-            }           
-        }
-        return true;
-    }
-    
-    /**
-     * Verify that all paths are readable relative to baseDir. 
-     * may fail with the message "cannot read {file}" 
-     */
-    public boolean canRead(File[] files, String message) {
-        if (!nullcheck(files, message)) {
-            return false;
-        }
-        for (int j = 0; j < files.length; j++) {
-            if (!canRead(files[j], files[j].getPath())) {
-                return false;
-            }           
-        }
-        return true;
-    }
-
-    /** may fail with the message "cannot read {file}" */
-    public boolean canRead(File file, String message) {
-        if (nullcheck(file, message)) {
-            if (file.canRead()) {
-                return true;
-            } else {
-                fail("cannot read " + file);
-            }
-        }
-        return false;
-    }
-    
-    /** may fail with the message "cannot write {file}" */
-    public boolean canWrite(File file, String message) {
-        if (nullcheck(file, message)) {
-            if (file.canRead()) {
-                return true;
-            } else {
-                fail("cannot write " + file);
-            }
-        }
-        return false;
-    }
-    
-    /** may fail with the message "not a directory {file}" */
-    public boolean canReadDir(File file, String message) {
-        if (canRead(file, message)) {
-            if (file.isDirectory()) {
-                return true;
-            } else {
-                fail("not a directory " + file);
-            }
-        }
-        return false;
-    }
-    
-    /** may fail with the message "not a directory {file}" */
-    public boolean canWriteDir(File file, String message) {
-        if (canWrite(file, message)) {
-            if (file.isDirectory()) {
-                return true;
-            } else {
-                fail("not a directory " + file);
-            }
-        }
-        return false;
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dir array<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canRead} {message}[#}<li>
-     */
-    public boolean canReadFiles(Object[] dirs, String message) {
-        return ((nullcheck((Object) dirs, message + " dir array"))
-                && canReadFiles(Arrays.asList(dirs), message));
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} files<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canRead} {message}[#}<li>
-     */
-    public boolean canReadFiles(Collection dirs, String message) {
-        if (nullcheck((Object) dirs, message + " files")) {
-            int i = 0;
-            for (Iterator iter = dirs.iterator(); iter.hasNext();) {
-                Object o = iter.next();
-                if (! (o instanceof File)) {
-                    fail(i + ": not a file " + o);
-                }                
-                if (!canRead((File) o, message + "[" + i++ + "]")) {
-                     return false;
-                }       
-            }
-            return true;
-        }
-        return false;
-    }
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dir array<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canReadDir} {message}[#}<li>
-     */
-    public boolean canReadDirs(Object[] dirs, String message) {
-        return ((nullcheck((Object) dirs, message + " dir array"))
-                && canReadDirs(Arrays.asList(dirs), message));
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dirs<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canReadDir} {message}[#}<li>
-     */
-    public boolean canReadDirs(Collection dirs, String message) {
-        if (nullcheck((Object) dirs, message + " dirs")) {
-            int i = 0;
-            for (Iterator iter = dirs.iterator(); iter.hasNext();) {
-                Object o = iter.next();
-                if (! (o instanceof File)) {
-                    fail(i + ": not a file " + o);
-                }                
-                if (!canReadDir((File) o, message + "[" + i++ + "]")) {
-                     return false;
-                }       
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dir array<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canWrite} {message}[#}<li>
-     */
-    public boolean canWriteFiles(Object[] dirs, String message) {
-        return ((nullcheck((Object) dirs, message + " dir array"))
-                && canWriteFiles(Arrays.asList(dirs), message));
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} files<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canWrite} {message}[#}<li>
-     */
-    public boolean canWriteFiles(Collection dirs, String message) {
-        if (nullcheck((Object) dirs, message + " files")) {
-            int i = 0;
-            for (Iterator iter = dirs.iterator(); iter.hasNext();) {
-                Object o = iter.next();
-                if (! (o instanceof File)) {
-                    fail(i + ": not a file " + o);
-                }                
-                if (!canWrite((File) o, message + "[" + i++ + "]")) {
-                     return false;
-                }       
-            }
-            return true;
-        }
-        return false;
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dir array<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canWriteDir} {message}[#}<li>
-     */
-    public boolean canWriteDirs(Object[] dirs, String message) {
-        return ((nullcheck((Object) dirs, message + " dir array"))
-                && canWriteDirs(Arrays.asList(dirs), message));
-    }
-    
-    /** 
-     * May fail with any of the messages
-     * <li>{null check} dirs<li>
-     * <li>"#: not a File {file}"<li>
-     * <li>{canWriteDir} {message}[#}<li>
-     */
-    public boolean canWriteDirs(Collection dirs, String message) {
-        if (nullcheck((Object) dirs, message + " dirs")) {
-            int i = 0;
-            for (Iterator iter = dirs.iterator(); iter.hasNext();) {
-                Object o = iter.next();
-                if (! (o instanceof File)) {
-                    fail(i + ": not a file " + o);
-                }                
-                if (!canWriteDir((File) o, message + "[" + i++ + "]")) {
-                     return false;
-                }       
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** 
-     * Send an info message to any underlying handler 
-     * @param message ignored if null
-     */
-    public void info(String message) {
-        if (null != message) {
-               IMessageHandler handler = getHandler();
-            MessageUtil.info(handler, message);
-        }
-    }
-    
-    /** Fail via message or AbortException */
-    public void fail(String message) {
-        fail(message, (Throwable) null);
-    }
-    
-    /** 
-     * Fail via message or AbortException.
-    * All failure messages go through here,
-    * so subclasses may override to control
-    * failure-handling.
-    */
-    public void fail(String message, Throwable thrown) {
-        if ((null == message) && (null == thrown)) {
-            message = "<Validator:no message>";
-        }
-        IMessage m = MessageUtil.fail(message, thrown);
-        if (abortOnFailure) {
-            throw new AbortException(m);
-        } else {
-               IMessageHandler handler = getHandler();
-            handler.handleMessage(m);
-        }
-    }
-    
-    /** 
-     * Register a file temporary, i.e., to be
-     * deleted on completion.  The file need not
-     * exist (yet or ever) and may be a duplicate
-     * of existing files registered.
-     */
-    public void registerTempFile(File file) {
-        if (null != file) {
-            tempFiles.add(file);
-        }
-    }
-    
-    /** 
-     * Get a writable {possibly-empty} directory.
-     * If the input dir is null, then try to create a temporary
-     * directory using name.  
-     * If the input dir is not null, this tries to 
-     * create it if it does not exist.  
-     * Then if name is not null,
-     * it tries to get a temporary directory
-     * under this using name.
-     * If name is null, "Validator" is used.
-     * If deleteContents is true, this will try to delete
-     * any existing contents.  If this is unable to delete
-     * the contents of the input directory, this may return
-     * a new, empty temporary directory.
-     * If register is true, then any directory returned is
-     * saved for later deletion using <code>deleteTempDirs()</code>,
-     * including the input directory.
-     * When this is unable to create a result, if failMessage
-     * is not null then this will fail; otherwise it returns false;
-     */
-    public File getWritableDir(File dir, String name, 
-        boolean deleteContents, boolean register, String failMessage) {
-        // check dir
-        if (null == dir) {
-            if (null == name) {
-                name = "Validator";
-            }
-            dir = FileUtil.getTempDir(name);            
-        } else { 
-            if (!dir.exists()) { 
-                dir.mkdirs();
-            }
-        }
-        // fail if necessary
-        if ((null == dir) || (!dir.exists())) {
-            if (null != failMessage) {
-                fail(failMessage + ": unable to get parent " + dir);
-            }
-        } else {
-            FileUtil.makeNewChildDir(dir, name);
-            if (deleteContents) {
-                FileUtil.deleteContents(dir);
-            }
-            if (register) {
-                tempFiles.add(dir);
-            }
-        }
-        return dir;
-    }
-
-    /** 
-     * Delete any temp sandboxes, files or directories saved,
-     * optionally reporting failures in the normal way.
-     * This will be ignored unless the failure policy
-     * is unlocked.
-     */
-    public void deleteTempFiles(boolean reportFailures) {
-        if (null == locker) {
-            for (ListIterator iter = tempFiles.listIterator(); iter.hasNext();) {
-                if (deleteFile((File) iter.next(), reportFailures)) {
-                    iter.remove();
-                }
-            }
-            for (ListIterator iter = sandboxes.listIterator(); iter.hasNext();) {
-                Sandbox sandbox = (Sandbox) iter.next();                
-                // XXX assumes all dirs are in sandboxDir
-                if (deleteFile(sandbox.sandboxDir, reportFailures)) {
-                    iter.remove();
-                }
-            }
-        }
-    }                
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * May fail with the message "null {message}"
+        * if o and the def{ault} are null
+        * @return o if not null or default otherwise
+        */
+       public Object nulldefault(Object o, String message, Object def) {
+               if (null == o) {
+                       o = def;
+               }
+               nullcheck(o, message);
+               return o;
+       }
+
+       /** may fail with the message "null {message}" */
+       public boolean nullcheck(Object o, String message) {
+               if (null == o) {
+                       if (null == message) message = "object";
+                       fail("null " + message);
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * Verify that all paths are readable relative to baseDir.
+        * may fail with the message "cannot read {file}"
+        */
+       public boolean canRead(File baseDir, String[] paths, String message) {
+               if (!canRead(baseDir, "baseDir - " + message)
+                               || !nullcheck(paths, "paths - " + message)) {
+                       return false;
+               }
+               final String dirPath = baseDir.getPath();
+               File[] files = FileUtil.getBaseDirFiles(baseDir, paths);
+               for (File file : files) {
+                       if (!canRead(file, "{" + dirPath + "} " + file)) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Verify that all paths are readable relative to baseDir.
+        * may fail with the message "cannot read {file}"
+        */
+       public boolean canRead(File[] files, String message) {
+               if (!nullcheck(files, message)) {
+                       return false;
+               }
+               for (File file : files) {
+                       if (!canRead(file, file.getPath())) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /** may fail with the message "cannot read {file}" */
+       public boolean canRead(File file, String message) {
+               if (nullcheck(file, message)) {
+                       if (file.canRead()) {
+                               return true;
+                       } else {
+                               fail("cannot read " + file);
+                       }
+               }
+               return false;
+       }
+
+       /** may fail with the message "cannot write {file}" */
+       public boolean canWrite(File file, String message) {
+               if (nullcheck(file, message)) {
+                       if (file.canRead()) {
+                               return true;
+                       } else {
+                               fail("cannot write " + file);
+                       }
+               }
+               return false;
+       }
+
+       /** may fail with the message "not a directory {file}" */
+       public boolean canReadDir(File file, String message) {
+               if (canRead(file, message)) {
+                       if (file.isDirectory()) {
+                               return true;
+                       } else {
+                               fail("not a directory " + file);
+                       }
+               }
+               return false;
+       }
+
+       /** may fail with the message "not a directory {file}" */
+       public boolean canWriteDir(File file, String message) {
+               if (canWrite(file, message)) {
+                       if (file.isDirectory()) {
+                               return true;
+                       } else {
+                               fail("not a directory " + file);
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dir array<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canRead} {message}[#}<li>
+        */
+       public boolean canReadFiles(Object[] dirs, String message) {
+               return ((nullcheck((Object) dirs, message + " dir array"))
+                               && canReadFiles(Arrays.asList(dirs), message));
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} files<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canRead} {message}[#}<li>
+        */
+       public boolean canReadFiles(Collection dirs, String message) {
+               if (nullcheck((Object) dirs, message + " files")) {
+                       int i = 0;
+                       for (Iterator iter = dirs.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (! (o instanceof File)) {
+                                       fail(i + ": not a file " + o);
+                               }
+                               if (!canRead((File) o, message + "[" + i++ + "]")) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               return false;
+       }
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dir array<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canReadDir} {message}[#}<li>
+        */
+       public boolean canReadDirs(Object[] dirs, String message) {
+               return ((nullcheck((Object) dirs, message + " dir array"))
+                               && canReadDirs(Arrays.asList(dirs), message));
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dirs<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canReadDir} {message}[#}<li>
+        */
+       public boolean canReadDirs(Collection dirs, String message) {
+               if (nullcheck((Object) dirs, message + " dirs")) {
+                       int i = 0;
+                       for (Iterator iter = dirs.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (! (o instanceof File)) {
+                                       fail(i + ": not a file " + o);
+                               }
+                               if (!canReadDir((File) o, message + "[" + i++ + "]")) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dir array<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canWrite} {message}[#}<li>
+        */
+       public boolean canWriteFiles(Object[] dirs, String message) {
+               return ((nullcheck((Object) dirs, message + " dir array"))
+                               && canWriteFiles(Arrays.asList(dirs), message));
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} files<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canWrite} {message}[#}<li>
+        */
+       public boolean canWriteFiles(Collection dirs, String message) {
+               if (nullcheck((Object) dirs, message + " files")) {
+                       int i = 0;
+                       for (Iterator iter = dirs.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (! (o instanceof File)) {
+                                       fail(i + ": not a file " + o);
+                               }
+                               if (!canWrite((File) o, message + "[" + i++ + "]")) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dir array<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canWriteDir} {message}[#}<li>
+        */
+       public boolean canWriteDirs(Object[] dirs, String message) {
+               return ((nullcheck((Object) dirs, message + " dir array"))
+                               && canWriteDirs(Arrays.asList(dirs), message));
+       }
+
+       /**
+        * May fail with any of the messages
+        * <li>{null check} dirs<li>
+        * <li>"#: not a File {file}"<li>
+        * <li>{canWriteDir} {message}[#}<li>
+        */
+       public boolean canWriteDirs(Collection dirs, String message) {
+               if (nullcheck((Object) dirs, message + " dirs")) {
+                       int i = 0;
+                       for (Iterator iter = dirs.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (! (o instanceof File)) {
+                                       fail(i + ": not a file " + o);
+                               }
+                               if (!canWriteDir((File) o, message + "[" + i++ + "]")) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Send an info message to any underlying handler
+        * @param message ignored if null
+        */
+       public void info(String message) {
+               if (null != message) {
+                       IMessageHandler handler = getHandler();
+                       MessageUtil.info(handler, message);
+               }
+       }
+
+       /** Fail via message or AbortException */
+       public void fail(String message) {
+               fail(message, (Throwable) null);
+       }
+
+       /**
+        * Fail via message or AbortException.
+        * All failure messages go through here,
+        * so subclasses may override to control
+        * failure-handling.
+        */
+       public void fail(String message, Throwable thrown) {
+               if ((null == message) && (null == thrown)) {
+                       message = "<Validator:no message>";
+               }
+               IMessage m = MessageUtil.fail(message, thrown);
+               if (abortOnFailure) {
+                       throw new AbortException(m);
+               } else {
+                       IMessageHandler handler = getHandler();
+                       handler.handleMessage(m);
+               }
+       }
+
+       /**
+        * Register a file temporary, i.e., to be
+        * deleted on completion.  The file need not
+        * exist (yet or ever) and may be a duplicate
+        * of existing files registered.
+        */
+       public void registerTempFile(File file) {
+               if (null != file) {
+                       tempFiles.add(file);
+               }
+       }
+
+       /**
+        * Get a writable {possibly-empty} directory.
+        * If the input dir is null, then try to create a temporary
+        * directory using name.
+        * If the input dir is not null, this tries to
+        * create it if it does not exist.
+        * Then if name is not null,
+        * it tries to get a temporary directory
+        * under this using name.
+        * If name is null, "Validator" is used.
+        * If deleteContents is true, this will try to delete
+        * any existing contents.  If this is unable to delete
+        * the contents of the input directory, this may return
+        * a new, empty temporary directory.
+        * If register is true, then any directory returned is
+        * saved for later deletion using <code>deleteTempDirs()</code>,
+        * including the input directory.
+        * When this is unable to create a result, if failMessage
+        * is not null then this will fail; otherwise it returns false;
+        */
+       public File getWritableDir(File dir, String name,
+                       boolean deleteContents, boolean register, String failMessage) {
+               // check dir
+               if (null == dir) {
+                       if (null == name) {
+                               name = "Validator";
+                       }
+                       dir = FileUtil.getTempDir(name);
+               } else {
+                       if (!dir.exists()) {
+                               dir.mkdirs();
+                       }
+               }
+               // fail if necessary
+               if ((null == dir) || (!dir.exists())) {
+                       if (null != failMessage) {
+                               fail(failMessage + ": unable to get parent " + dir);
+                       }
+               } else {
+                       FileUtil.makeNewChildDir(dir, name);
+                       if (deleteContents) {
+                               FileUtil.deleteContents(dir);
+                       }
+                       if (register) {
+                               tempFiles.add(dir);
+                       }
+               }
+               return dir;
+       }
+
+       /**
+        * Delete any temp sandboxes, files or directories saved,
+        * optionally reporting failures in the normal way.
+        * This will be ignored unless the failure policy
+        * is unlocked.
+        */
+       public void deleteTempFiles(boolean reportFailures) {
+               if (null == locker) {
+                       for (ListIterator iter = tempFiles.listIterator(); iter.hasNext();) {
+                               if (deleteFile((File) iter.next(), reportFailures)) {
+                                       iter.remove();
+                               }
+                       }
+                       for (ListIterator iter = sandboxes.listIterator(); iter.hasNext();) {
+                               Sandbox sandbox = (Sandbox) iter.next();
+                               // XXX assumes all dirs are in sandboxDir
+                               if (deleteFile(sandbox.sandboxDir, reportFailures)) {
+                                       iter.remove();
+                               }
+                       }
+               }
+       }
 
        /**
         * Manage temp files and directories of registered sandboxes.
-     * Note that a sandbox may register before it is initialized,
-     * so this must do nothing other than save the reference.
+        * Note that a sandbox may register before it is initialized,
+        * so this must do nothing other than save the reference.
         * @param sandbox the uninitialized Sandbox to track
         */
        public void registerSandbox(Sandbox sandbox) {
-          sandboxes.add(sandbox);
-    }
-    
-    
-    private boolean deleteFile(File file, boolean reportFailures) {
-        if (null == file) {
-            if (reportFailures) {
-                fail("unable to delete null file");
-            }
-            return true; // null file - skip
-        }
-        FileUtil.deleteContents(file);
-        if (file.exists()) {
-            file.delete();
-        }
-        if (!file.exists()) {
-            return true;
-        } else if (reportFailures) {
-            fail("unable to delete " + file);        
-        }
-        return false;
-    }
-    
-    /** @throws IllegalStateException if handler is null */
+               sandboxes.add(sandbox);
+       }
+
+
+       private boolean deleteFile(File file, boolean reportFailures) {
+               if (null == file) {
+                       if (reportFailures) {
+                               fail("unable to delete null file");
+                       }
+                       return true; // null file - skip
+               }
+               FileUtil.deleteContents(file);
+               if (file.exists()) {
+                       file.delete();
+               }
+               if (!file.exists()) {
+                       return true;
+               } else if (reportFailures) {
+                       fail("unable to delete " + file);
+               }
+               return false;
+       }
+
+       /** @throws IllegalStateException if handler is null */
        private IMessageHandler getHandler() {
-               IMessageHandler handler = (IMessageHandler) handlers.peek();
+               IMessageHandler handler = handlers.peek();
                if (null == handler) {
                        throw new IllegalStateException("no handler");
                }
@@ -561,4 +561,4 @@ public class Validator {
        }
 
 } // class Validator
+