code: package it.unibz.inf.ontop.iq.transform;
  
  import com.google.common.collect.ImmutableList;
  import it.unibz.inf.ontop.iq.IQTree;
  import it.unibz.inf.ontop.iq.LeafIQTree;
  import it.unibz.inf.ontop.iq.node.*;
  
  
  /**
   *  For composite IQ trees, the tree itself is passed as a first argument,
   *  in case the transformer does not transform the tree,
   *  so as to avoid creating unnecessary new objects.
   */
  public interface IQTreeVisitingTransformer extends IQTreeTransformer {
  
      IQTree transformIntensionalData(IntensionalDataNode rootNode);
      IQTree transformExtensionalData(ExtensionalDataNode rootNode);
      IQTree transformEmpty(EmptyNode rootNode);
      IQTree transformTrue(TrueNode rootNode);
      IQTree transformValues(ValuesNode valuesNode);
      IQTree transformNonStandardLeafNode(LeafIQTree rootNode);
  
      IQTree transformConstruction(IQTree tree, ConstructionNode rootNode, IQTree child);
      IQTree transformAggregation(IQTree tree, AggregationNode aggregationNode, IQTree child);
      IQTree transformFlatten(IQTree tree, FlattenNode node, IQTree child);
      IQTree transformFilter(IQTree tree, FilterNode rootNode, IQTree child);
      IQTree transformDistinct(IQTree tree, DistinctNode rootNode, IQTree child);
      IQTree transformSlice(IQTree tree, SliceNode rootNode, IQTree child);
      IQTree transformOrderBy(IQTree tree, OrderByNode rootNode, IQTree child);
      IQTree transformNonStandardUnaryNode(IQTree tree, UnaryOperatorNode rootNode, IQTree child);
  
      IQTree transformLeftJoin(IQTree tree, LeftJoinNode rootNode, IQTree leftChild, IQTree rightChild);
      IQTree transformNonStandardBinaryNonCommutativeNode(IQTree tree, BinaryNonCommutativeOperatorNode rootNode,
                                                          IQTree leftChild, IQTree rightChild);
  
      IQTree transformInnerJoin(IQTree tree, InnerJoinNode rootNode, ImmutableList<IQTree> children);
      IQTree transformUnion(IQTree tree, UnionNode rootNode, ImmutableList<IQTree> children);
      IQTree transformNonStandardNaryNode(IQTree tree, NaryOperatorNode rootNode, ImmutableList<IQTree> children);
  
      default IQTree transform(IQTree tree) {
          return tree.acceptTransformer(this);
      }
  }
  