/**
   * Computes actual grid specification (origin + single cell width and height) in the coordinates
   * relative to the diagram content pane.
   *
   * <p>This specification depends only on the grid-relative properties stored in the {@link
   * EditPartViewer}, so client may cache it and rely on {@link
   * EditPartViewer#addPropertyChangeListener(PropertyChangeListener)}
   *
   * @param viewer
   * @return grid specification in the coordinate system relative to diagram content pane, or <code>
   *     null</code> if grid is not enabled
   */
  private static PrecisionRectangle getRelativeGridSpec(EditPartViewer viewer) {
    Boolean enabled = (Boolean) viewer.getProperty(SnapToGrid.PROPERTY_GRID_ENABLED);
    if (enabled == null || !enabled) {
      return null;
    }
    double gridX = 0;
    double gridY = 0;
    Dimension spacing = (Dimension) viewer.getProperty(SnapToGrid.PROPERTY_GRID_SPACING);
    if (spacing != null) {
      gridX = spacing.preciseWidth();
      gridY = spacing.preciseHeight();
    }
    if (gridX <= 0) {
      gridX = SnapToGrid.DEFAULT_GRID_SIZE;
    }
    if (gridY <= 0) {
      gridY = SnapToGrid.DEFAULT_GRID_SIZE;
    }
    Point origin = (Point) viewer.getProperty(SnapToGrid.PROPERTY_GRID_ORIGIN);
    PrecisionRectangle result =
        new PrecisionRectangle( //
            origin == null ? 0 : origin.preciseX(),
            origin == null ? 0 : origin.preciseY(),
            gridX,
            gridY);

    return result;
  }