docs: @SuppressWarnings("ObjectAllocationInLoop")
      public void add(NodeBase source, NodeBase dest) {
          // amount of commutative nodes
          int n = 0;
          for (NodeBase node : source.getDescendants()) {
              if (node instanceof CommutativeOperator) {
                  n++;
              }
          }
          for (int i = 0; i < 1 << n; i++) {
              Root root = new Root(source.getClone());
              int j = 0;
              for (NodeBase node : root.getDescendants()) {
                  if (node instanceof CommutativeOperator) {
                      if ((i & 1 << j) != 0) {
                          ((CommutativeOperator) node).flipChildren();
                      }
                      j++;
                  }
              }
              rules.add(new OptimizationRule(root.getChild(), dest));
          }
      }