public void handleLayerEvent(IStructuralChangeEvent event) {
    PositionCoordinate topLeftPosition = freezeLayer.getTopLeftPosition();
    PositionCoordinate bottomRightPosition = freezeLayer.getBottomRightPosition();

    Collection<StructuralDiff> columnDiffs = event.getColumnDiffs();
    if (columnDiffs != null) {
      int leftOffset = 0;
      int rightOffset = 0;

      for (StructuralDiff columnDiff : columnDiffs) {
        switch (columnDiff.getDiffType()) {
          case ADD:
            Range afterPositionRange = columnDiff.getAfterPositionRange();
            if (afterPositionRange.start < topLeftPosition.columnPosition) {
              leftOffset += afterPositionRange.size();
            }
            if (afterPositionRange.start <= bottomRightPosition.columnPosition) {
              rightOffset += afterPositionRange.size();
            }
            break;
          case DELETE:
            Range beforePositionRange = columnDiff.getBeforePositionRange();
            if (beforePositionRange.start < topLeftPosition.columnPosition) {
              leftOffset -=
                  Math.min(beforePositionRange.end, topLeftPosition.columnPosition + 1)
                      - beforePositionRange.start;
            }
            if (beforePositionRange.start <= bottomRightPosition.columnPosition) {
              rightOffset -=
                  Math.min(beforePositionRange.end, bottomRightPosition.columnPosition + 1)
                      - beforePositionRange.start;
            }
            break;
        }
      }

      topLeftPosition.columnPosition += leftOffset;
      bottomRightPosition.columnPosition += rightOffset;
    }

    Collection<StructuralDiff> rowDiffs = event.getRowDiffs();
    if (rowDiffs != null) {
      int leftOffset = 0;
      int rightOffset = 0;

      for (StructuralDiff rowDiff : rowDiffs) {
        switch (rowDiff.getDiffType()) {
          case ADD:
            Range afterPositionRange = rowDiff.getAfterPositionRange();
            if (afterPositionRange.start < topLeftPosition.rowPosition) {
              leftOffset += afterPositionRange.size();
            }
            if (afterPositionRange.start <= bottomRightPosition.rowPosition) {
              rightOffset += afterPositionRange.size();
            }
            break;
          case DELETE:
            Range beforePositionRange = rowDiff.getBeforePositionRange();
            if (beforePositionRange.start < topLeftPosition.rowPosition) {
              leftOffset -=
                  Math.min(beforePositionRange.end, topLeftPosition.rowPosition + 1)
                      - beforePositionRange.start;
            }
            if (beforePositionRange.start <= bottomRightPosition.rowPosition) {
              rightOffset -=
                  Math.min(beforePositionRange.end, bottomRightPosition.rowPosition + 1)
                      - beforePositionRange.start;
            }
            break;
        }
      }

      topLeftPosition.rowPosition += leftOffset;
      bottomRightPosition.rowPosition += rightOffset;
    }
  }
  public PositionCoordinate executeSearch(Object valueToMatch) {
    ILayer contextLayer = getContextLayer();
    if (!(contextLayer instanceof SelectionLayer)) {
      throw new RuntimeException(
          "For the GridSearchStrategy to work it needs the selectionLayer to be passed as the contextLayer.");
    }

    SelectionLayer selectionLayer = (SelectionLayer) contextLayer;
    PositionCoordinate selectionAnchor = selectionLayer.getSelectionAnchor();
    boolean hadSelectionAnchor = true;
    if (selectionAnchor.columnPosition < 0 || selectionAnchor.rowPosition < 0) {
      selectionAnchor.columnPosition = 0;
      selectionAnchor.rowPosition = 0;
      hadSelectionAnchor = false;
    }
    int anchorColumnPosition = selectionAnchor.columnPosition;

    int startingRowPosition;
    int[] columnsToSearch = null;
    final int columnCount = selectionLayer.getColumnCount();
    if (searchDirection.equals(ISearchDirection.SEARCH_FORWARD)) {
      int rowPosition =
          hadSelectionAnchor ? selectionAnchor.rowPosition + 1 : selectionAnchor.rowPosition;
      if (rowPosition > (contextLayer.getRowCount() - 1)) {
        rowPosition = wrapSearch ? 0 : contextLayer.getRowCount() - 1;
      }
      int rowCount = selectionLayer.getRowCount();
      startingRowPosition = rowPosition < rowCount ? rowPosition : 0;
      if (selectionAnchor.rowPosition + 1 >= rowCount
          && anchorColumnPosition + 1 >= columnCount
          && hadSelectionAnchor) {
        if (wrapSearch) {
          anchorColumnPosition = 0;
        } else {
          return null;
        }
      } else if (selectionAnchor.rowPosition == rowCount - 1
          && anchorColumnPosition < columnCount - 1) {
        anchorColumnPosition++;
      }
      columnsToSearch = getColumnsToSearchArray(columnCount, anchorColumnPosition);
    } else {
      int rowPosition = selectionAnchor.rowPosition - 1;
      if (rowPosition < 0) {
        rowPosition = wrapSearch ? contextLayer.getRowCount() - 1 : 0;
      }
      startingRowPosition = rowPosition > 0 ? rowPosition : 0;

      if (selectionAnchor.rowPosition - 1 < 0
          && anchorColumnPosition - 1 < 0
          && hadSelectionAnchor) {
        if (wrapSearch) {
          anchorColumnPosition = columnCount - 1;
        } else {
          return null;
        }
      } else if (selectionAnchor.rowPosition == 0 && anchorColumnPosition > 0) {
        anchorColumnPosition--;
      }
      columnsToSearch = getDescendingColumnsToSearchArray(anchorColumnPosition);
    }

    PositionCoordinate executeSearch =
        searchGrid(
            valueToMatch,
            contextLayer,
            selectionLayer,
            anchorColumnPosition,
            startingRowPosition,
            columnsToSearch);
    return executeSearch;
  }