public static CanonicMultiStageLayouter createHierarchicalLayouter(
      final HierarchicStyle style,
      final long minLayerDist,
      final long minNodeDist,
      final long minEdgeDist,
      final long minNodeEdgeDist,
      final HierarchicOrientation orientation) {
    Preconditions.checkNotNull(style, "Internal Error: Layout style can't be null");
    Preconditions.checkArgument(
        minLayerDist >= 0, "Internal Error: Minimum layer distance can't be negative");
    Preconditions.checkArgument(
        minNodeDist >= 0, "Internal Error: Minimum node distance can't be negative");
    Preconditions.checkArgument(
        minEdgeDist >= 0, "Internal Error: Minimum edge distance can't be negative");

    final IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
    layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
    layouter.setConsiderNodeLabelsEnabled(true);
    layouter.setRecursiveGroupLayeringEnabled(true);
    layouter.setLayoutOrientation(
        orientation == HierarchicOrientation.HORIZONTAL
            ? OrientationLayouter.TOP_TO_BOTTOM
            : OrientationLayouter.LEFT_TO_RIGHT);
    layouter.setBackloopRoutingEnabled(true);

    final EdgeLayoutDescriptor edgeLayout = layouter.getEdgeLayoutDescriptor();
    edgeLayout.setSourcePortOptimizationEnabled(true);
    edgeLayout.setTargetPortOptimizationEnabled(true);
    edgeLayout.setMinimumFirstSegmentLength(25);
    edgeLayout.setMinimumLastSegmentLength(25);

    final NodeLayoutDescriptor nodeLayout = layouter.getNodeLayoutDescriptor();
    nodeLayout.setLayerAlignment(0.0);

    final SelfLoopLayouter sll = new SelfLoopLayouter(layouter);
    sll.setSmartSelfloopPlacementEnabled(true);

    switch (style) {
      case OCTLINEAR_OPTIMAL:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_OPTIMAL,
              RoutingStyle.EDGE_STYLE_OCTILINEAR,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case ORTHOGONAL_OPTIMAL:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_OPTIMAL,
              RoutingStyle.EDGE_STYLE_ORTHOGONAL,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case POLYLINE_OPTIMAL:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_OPTIMAL,
              RoutingStyle.EDGE_STYLE_POLYLINE,
              false,
              layouter,
              edgeLayout);
          break;
        }
      case OCTLINEAR_TOPMOST:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TOPMOST,
              RoutingStyle.EDGE_STYLE_OCTILINEAR,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case ORTHOGONAL_TOPMOST:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TOPMOST,
              RoutingStyle.EDGE_STYLE_ORTHOGONAL,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case POLYLINE_TOPMOST:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TOPMOST,
              RoutingStyle.EDGE_STYLE_POLYLINE,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case OCTLINEAR_TIGHT_TREE:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TIGHT_TREE,
              RoutingStyle.EDGE_STYLE_OCTILINEAR,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case ORTHOGONAL_TIGHT_TREE:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TIGHT_TREE,
              RoutingStyle.EDGE_STYLE_ORTHOGONAL,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case POLYLINE_TIGHT_TREE:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TIGHT_TREE,
              RoutingStyle.EDGE_STYLE_POLYLINE,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case OCTLINEAR_BFS:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_BFS,
              RoutingStyle.EDGE_STYLE_OCTILINEAR,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case ORTHOGONAL_BFS:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_BFS,
              RoutingStyle.EDGE_STYLE_ORTHOGONAL,
              true,
              layouter,
              edgeLayout);
          break;
        }
      case POLYLINE_BFS:
        {
          setStyle(
              IncrementalHierarchicLayouter.LAYERING_STRATEGY_BFS,
              RoutingStyle.EDGE_STYLE_POLYLINE,
              false,
              layouter,
              edgeLayout);
          break;
        }
      default:
        throw new IllegalStateException("Internal Error: Unknown layout style");
    }

    layouter.setMinimumLayerDistance(minLayerDist);
    layouter.setNodeToNodeDistance(minNodeDist);
    layouter.setNodeToEdgeDistance(minEdgeDist);
    layouter.setEdgeToEdgeDistance(minNodeEdgeDist);

    return layouter;
  }
Creates graph layouter objects that are used to layout ZyGraphs.
java/zylib/src/main/java/com/google/security/zynamics/zylib/yfileswrap/gui/zygraph/layouters/ZyGraphLayouter.java