/**
   * Gets a Rectangle from {@link #getBox()} and returns the Point where a line from the center of
   * the Rectangle to the Point <i>reference</i> intersects the Rectangle.
   *
   * @param reference The reference point
   * @return The anchor location
   */
  public Point getLocation(Point reference) {
    Rectangle r = Rectangle.SINGLETON;
    r.setBounds(getBox());
    r.translate(-1, -1);
    r.resize(1, 1);

    getOwner().translateToAbsolute(r);
    float centerX = r.x + 0.5f * r.width;
    float centerY = r.y + 0.5f * r.height;

    if (r.isEmpty() || (reference.x == (int) centerX && reference.y == (int) centerY))
      return new Point((int) centerX, (int) centerY); // This avoids divide-by-zero

    float dx = reference.x - centerX;
    float dy = reference.y - centerY;

    // r.width, r.height, dx, and dy are guaranteed to be non-zero.
    float scale = 0.5f / Math.max(Math.abs(dx) / r.width, Math.abs(dy) / r.height);

    dx *= scale;
    dy *= scale;
    centerX += dx;
    centerY += dy;

    return new Point(Math.round(centerX), Math.round(centerY));
  }
  private void setAnimationStatesForOtherMethods(
      MethodBoxFigure figure, Rectangle rect1, Rectangle rect2) {
    Rectangle invocationBounds = figure.getPartner().getBounds().getCopy();
    rect1.y = invocationBounds.y;
    rect2.y = invocationBounds.y;

    rect1.x = rect2.x - 1; // kluge to avoid the rect1==rect2 continue in animation playback
    rect1.height = rect2.height;
    rect1.width = rect2.width;
  }
  public void relocate(CellEditor celleditor) {
    if (celleditor == null) return;
    Text text = (Text) celleditor.getControl();

    Rectangle rect = fig.getClientArea(Rectangle.SINGLETON);
    if (fig instanceof Label) rect = ((Label) fig).getTextBounds().intersect(rect);
    fig.translateToAbsolute(rect);

    org.eclipse.swt.graphics.Rectangle trim = text.computeTrim(0, 0, 0, 0);
    rect.translate(trim.x, trim.y);
    rect.width += trim.width;
    rect.height += trim.height;

    text.setBounds(rect.x, rect.y, rect.width, rect.height);
  }
 @Override
 public void setAnimationStates(IFigure figure, Rectangle rect1, Rectangle rect2) {
   if (figure.equals(getDeclarationFigure())) {
     setAnimationStatesForNewDecl(rect1, rect2);
   } else if (isCallToDifferentClass()
       && figure.equals(getInstanceOfDeclFigure().getChildrenContainer())) {
     setAnimationStatesForInstanceChildrenContainer(figure, rect1, rect2);
   } else if (isCallToDifferentClass()
       && figure instanceof MethodBoxFigure
       && MethodBoxModel.declaration == ((MethodBoxFigure) figure).getType()
       && ((MethodBoxFigure) figure).getPartner() != null) {
     setAnimationStatesForOtherMethods((MethodBoxFigure) figure, rect1, rect2);
   } else {
     rect1.x = rect2.x;
     rect1.y = rect2.y;
     rect1.width = rect2.width;
     rect1.height = rect2.height;
   }
 }
  private void setAnimationStatesForNewDecl(Rectangle rect1, Rectangle rect2) {
    if (isCallToDifferentClass()) {
      Rectangle invocationFigBounds = getInvocationFigure().getBounds().getCopy();

      rect1.x = invocationFigBounds.x;
      rect1.y = invocationFigBounds.y;
      rect1.width = rect2.width;
      rect1.height = rect2.height;

      rect2.y = invocationFigBounds.y;
    } else if (isCallToSameClass()) {
      rect1.x = rect2.x;
      rect1.y = rect2.height / 2 + rect2.y;
      rect1.width = rect2.width;
      rect1.height = 0;
    }
  }
  @Override
  public void makeAdjustmentsForAnimationPlayback(
      IFigure figure, Rectangle rect1, Rectangle rect2, Map<Object, Object> finalStates) {
    if (!isCallToDifferentClass() || !figure.equals(getDeclarationFigure())) return;

    Rectangle parentinstanceBounds =
        (Rectangle) finalStates.get(getInstanceOfDeclFigure().getChildrenContainer());
    rect2.x =
        (parentinstanceBounds.x + parentinstanceBounds.x + parentinstanceBounds.width) / 2
            - rect2.width / 2
            - 1;
  }
  private void setAnimationStatesForInstanceChildrenContainer(
      IFigure figure, Rectangle rect1, Rectangle rect2) {
    Rectangle instanceFigBounds = getInstanceOfDeclFigure().getInstanceBox().getBounds().getCopy();

    if (rect2.x + rect2.width < instanceFigBounds.x + instanceFigBounds.width)
      rect2.width = instanceFigBounds.width;
    rect2.height = LayoutUtil.getHeightToContainAllChildren(figure);

    Rectangle invocationFigBounds = getInvocationFigure().getBounds().getCopy();
    rect1.x = invocationFigBounds.x;
    rect1.y = rect2.y;
    rect1.width = rect2.width + rect2.x - invocationFigBounds.x;
    rect1.height = rect2.height;
  }