public void DecomposeTree(AbstractTree parentNode, AbstractTree node, TreeBranch branch, TreePath path) { if (!path.IsAdded) { Possibilities.Add(path); path.IsAdded = true; } // Recursive browse if (node is TreeConnector) { TreeConnector treeConnector = (TreeConnector)node; if (treeConnector.Connection == "&") { DecomposeTree(treeConnector, treeConnector.LeftTree, TreeBranch.Left, path); DecomposeTree(treeConnector, treeConnector.RightTree, TreeBranch.Right, path); } else if (treeConnector.Connection == "|") { // In this case, parentNode is a TreeOperator if (parentNode != null) { // Left distribution TreePath clonedPathLeftDistribution = (TreePath)path.Clone(); TreeConnector parentTreeConnectorLeftDistribution = (TreeConnector)parentNode.Clone(); // Right distribution TreePath clonedPathRightDistribution = (TreePath)path.Clone(); TreeConnector parentTreeConnectorRightDistribution = (TreeConnector)parentNode.Clone(); if (branch == TreeBranch.Left) { parentTreeConnectorLeftDistribution.LeftTree = treeConnector.LeftTree; parentTreeConnectorRightDistribution.LeftTree = treeConnector.RightTree; } else if (branch == TreeBranch.Right) { parentTreeConnectorLeftDistribution.RightTree = treeConnector.LeftTree; parentTreeConnectorRightDistribution.RightTree = treeConnector.RightTree; } // Remove obsolete path Possibilities.Remove(path); // Browse recursively distributed tree ; the path must be different (by ref) if the parent operator is 'OR' DecomposeTree( parentTreeConnectorLeftDistribution, parentTreeConnectorLeftDistribution.LeftTree, TreeBranch.Left, parentTreeConnectorLeftDistribution.Connection == "|" ? (TreePath)clonedPathLeftDistribution.Clone() : clonedPathLeftDistribution ); DecomposeTree( parentTreeConnectorLeftDistribution, parentTreeConnectorLeftDistribution.RightTree, TreeBranch.Right, clonedPathLeftDistribution ); DecomposeTree( parentTreeConnectorRightDistribution, parentTreeConnectorRightDistribution.LeftTree, TreeBranch.Left, parentTreeConnectorLeftDistribution.Connection == "|" ? (TreePath)clonedPathRightDistribution.Clone() : clonedPathRightDistribution ); DecomposeTree( parentTreeConnectorRightDistribution, parentTreeConnectorRightDistribution.RightTree, TreeBranch.Right, clonedPathRightDistribution ); } // The operator is the root of the tree; we simply divide the path else { TreePath clonedLeftPath = (TreePath)path.Clone(); TreePath clonedRightPath = (TreePath)path.Clone(); // Remove obsolete path Possibilities.Remove(path); DecomposeTree(treeConnector, treeConnector.LeftTree, TreeBranch.Left, clonedLeftPath); DecomposeTree(treeConnector, treeConnector.RightTree, TreeBranch.Right, clonedRightPath); } } break; } // Leaf else if (node is TreeValue) { TreeValue treeValue = (TreeValue)node; path.Add(treeValue); } }