protected FeatureTreeNode createNodes() throws FeatureModelException { int countFeatures = 1; Vector<FeatureTreeNode> fmNodes = new Vector<FeatureTreeNode>(); String featureName = "R"; countFeatures++; RootNode root = new RootNode(featureName, featureName); fmNodes.add(root); FeatureTreeNode parentNode = null; while (countFeatures <= numberOfFeatures) { parentNode = fmNodes.firstElement(); fmNodes.removeElement(parentNode); int numberOfChildNodesToCreate = Math.min( numberOfFeatures - countFeatures + 1, (Math.abs(new Random().nextInt()) % (childFeaturesOdds - minChildFeature + 1)) + minChildFeature); // prevents an early end of the recursion when all nodes happen to have no children if (numberOfChildNodesToCreate == 0) { if (fmNodes.size() == 0) { numberOfChildNodesToCreate = 1; } } if (numberOfChildNodesToCreate > 0) { for (int i = 0; i < numberOfChildNodesToCreate && countFeatures <= numberOfFeatures; i++) { String childFeatureName = parentNode.getID().substring(1) + (i + 1); FeatureTreeNode randomNode = createRandomNode( childFeatureName, solitaireOdds, groupOdds, minGroupCard, maxGroupCard); parentNode.add(randomNode); if (randomNode instanceof FeatureGroup) { FeatureGroup groupRandomNode = (FeatureGroup) randomNode; int countGroupedNodes = groupRandomNode.getChildCount(); for (int j = 0; j < countGroupedNodes; j++) { fmNodes.add((FeatureTreeNode) groupRandomNode.getChildAt(j)); } countFeatures += (countGroupedNodes); } else { fmNodes.add(randomNode); countFeatures++; } } } } return root; }