@Override
  protected void paint(DecorationLayer layer, Graphics2D g, RadComponent container) {
    if (!layer.showSelection() || container.getClientProperty(SnapPointFeedbackHost.KEY) != null) {
      return;
    }

    Stroke stroke = g.getStroke();
    g.setStroke(SnapPointFeedbackHost.STROKE);
    g.setColor(SnapPointFeedbackHost.COLOR);

    Rectangle bounds = container.getBounds(layer);
    Map<RadComponent, RelativeInfo> relativeInfos = container.getClientProperty(RelativeInfo.KEY);
    List<RadComponent> selection = layer.getArea().getSelection();

    for (RadComponent component : selection) {
      RelativeInfo info = relativeInfos.get(component);
      if (info != null) {
        paintOutRelative(layer, g, component, info);
        paintContainerRelative(g, bounds, info);
      }
    }

    g.setStroke(stroke);
    g.setColor(JBColor.ORANGE);

    for (RadComponent component : selection) {
      RelativeInfo info = relativeInfos.get(component);
      if (info != null) {
        paintContainerMarginRelative(layer, g, bounds, (RadViewComponent) component, info);
      }
    }
  }
  private static void delete(
      List<RadComponent> deletedComponents,
      GridInfo gridInfo,
      RadComponent[][] components,
      RadCaptionGridRow row)
      throws Exception {
    if (row.myIndex > 0) {
      GridLayoutOperation.shiftRowSpan(gridInfo, row.myIndex - 1, -1);
    }

    for (RadComponent component : components[row.myIndex]) {
      if (component != null) {
        Rectangle cellIndex = RadGridLayoutComponent.getCellInfo(component);
        GridInfo.setNull(
            components,
            gridInfo.components,
            cellIndex.y,
            cellIndex.y + cellIndex.height,
            cellIndex.x,
            cellIndex.x + cellIndex.width);
        component.delete();
        deletedComponents.add(component);
      }
    }
  }
  private static void componentToPath(RadComponent component, IntArrayList path) {
    RadComponent parent = component.getParent();

    if (parent != null) {
      path.add(0, parent.getChildren().indexOf(component));
      componentToPath(parent, path);
    }
  }
  private static void paintHorizontal(
      DecorationLayer layer, Graphics2D g, Rectangle from, RadComponent toComponent, int yType) {
    if (toComponent == null) {
      return;
    }

    Rectangle to = toComponent.getBounds(layer);

    int x1, x2;
    if (from.x < to.x) {
      x1 = from.x - SnapPointFeedbackHost.EXPAND_SIZE;
      x2 = to.x + to.width + SnapPointFeedbackHost.EXPAND_SIZE;
    } else {
      x1 = to.x - SnapPointFeedbackHost.EXPAND_SIZE;
      x2 = from.x + from.width + SnapPointFeedbackHost.EXPAND_SIZE;
    }

    int y;
    if (yType == TOP) {
      y = from.y;
    } else if (yType == BOTTOM) {
      y = from.y + from.height;
    } else {
      y = to.y;

      int baseline = ((RadViewComponent) toComponent).getBaseline();
      if (baseline != -1) {
        y += baseline;
      }
    }

    g.drawLine(x1, y, x2, y);
  }
  @Override
  protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
    g.setColor(myColor);
    if (myLineWidth > 1) {
      g.setStroke(new BasicStroke(myLineWidth));
    }

    Rectangle bounds = component.getBounds(layer);
    g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
  }
    public Dimension getPreferredSize() {
      int width = 0;
      int height = 0;

      if (myRootComponent != null) {
        width = Math.max(width, (int) myRootComponent.getBounds().getMaxX());
        height = Math.max(height, (int) myRootComponent.getBounds().getMaxY());

        for (RadComponent component : myRootComponent.getChildren()) {
          width = Math.max(width, (int) component.getBounds().getMaxX());
          height = Math.max(height, (int) component.getBounds().getMaxY());
        }
      }

      width += 50;
      height += 40;

      Rectangle bounds = myScrollPane.getViewport().getBounds();

      return new Dimension(Math.max(width, bounds.width), Math.max(height, bounds.height));
    }
 private static void pathToComponent(
     List<RadComponent> components, RadComponent component, int[] path, int index) {
   if (index == path.length) {
     components.add(component);
   } else {
     List<RadComponent> children = component.getChildren();
     int componentIndex = path[index];
     if (0 <= componentIndex && componentIndex < children.size()) {
       pathToComponent(components, children.get(componentIndex), path, index + 1);
     }
   }
 }
  private static void paintOutRelative(
      DecorationLayer layer, Graphics2D g, RadComponent component, RelativeInfo info) {
    Rectangle bounds = component.getBounds(layer);

    paintHorizontal(layer, g, bounds, info.alignTop, TOP);
    paintHorizontal(layer, g, bounds, info.alignBottom, BOTTOM);
    paintHorizontal(layer, g, bounds, info.below, TOP);
    paintHorizontal(layer, g, bounds, info.above, BOTTOM);

    paintHorizontal(layer, g, bounds, info.alignBaseline, BASELINE);

    paintVertical(layer, g, bounds, info.alignLeft, LEFT);
    paintVertical(layer, g, bounds, info.alignRight, RIGHT);
    paintVertical(layer, g, bounds, info.toRightOf, LEFT);
    paintVertical(layer, g, bounds, info.toLeftOf, RIGHT);
  }
  @Override
  public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) {
    Rectangle bounds = component.getBounds(layer);
    int lineWidth = Math.max(myLineWidth, 2);

    Rectangle top = new Rectangle(bounds.x, bounds.y, bounds.width, lineWidth);
    Rectangle bottom =
        new Rectangle(bounds.x, bounds.y + bounds.height - lineWidth, bounds.width, lineWidth);
    Rectangle left = new Rectangle(bounds.x, bounds.y, lineWidth, bounds.height);
    Rectangle right =
        new Rectangle(bounds.x + bounds.width - lineWidth, bounds.y, lineWidth, bounds.height);

    if (top.contains(x, y)
        || bottom.contains(x, y)
        || left.contains(x, y)
        || right.contains(x, y)) {
      return new DragTracker(component);
    }

    return null;
  }
  private static void paintVertical(
      DecorationLayer layer, Graphics2D g, Rectangle from, RadComponent toComponent, int xType) {
    if (toComponent == null) {
      return;
    }

    Rectangle to = toComponent.getBounds(layer);

    int y1, y2;
    if (from.y < to.y) {
      y1 = from.y - SnapPointFeedbackHost.EXPAND_SIZE;
      y2 = to.y + to.height + SnapPointFeedbackHost.EXPAND_SIZE;
    } else {
      y1 = to.y - SnapPointFeedbackHost.EXPAND_SIZE;
      y2 = from.y + from.height + SnapPointFeedbackHost.EXPAND_SIZE;
    }

    int x = xType == LEFT ? from.x : from.x + from.width;

    g.drawLine(x, y1, x, y2);
  }