private void solve() {

    if (pe == null) {
      GuiUtils.errorMessage(getConsole(), "Coverage Plan Solver", "The polygon is not valid");
      return;
    }

    double north, east, south, west;
    double[] bounds = pe.getBounds3d();

    south = bounds[PathElement.SOUTH_COORD];
    west = bounds[PathElement.WEST_COORD];
    north = bounds[PathElement.NORTH_COORD];
    east = bounds[PathElement.EAST_COORD];

    CoverageCell[][] cells =
        new CoverageCell[(int) ((north - south) / grid) + 1][(int) ((east - west) / grid) + 1];

    for (int i = 0; i < cells.length; i++)
      for (int j = 0; j < cells[i].length; j++) {
        cells[i][j] = new CoverageCell();
        cells[i][j].i = i;
        cells[i][j].j = j;
      }

    int i = 0, j = 0;
    int desiredCells = 0;
    for (double n = south + grid / 2; n < north; n += grid) {
      j = 0;
      for (double e = west + grid / 2; e < east; e += grid) {
        LocationType lt = new LocationType(pe.getCenterLocation());
        lt.translatePosition(n, e, 0);
        CoverageCell cell = cells[i][j];
        cell.realWorldLoc = lt.getNewAbsoluteLatLonDepth();
        if (pe.containsPoint(lt, null)) {
          cell.desired = true;
          desiredCells++;
        }
        cells[i][j] = cell;
        j++;
      }
      i++;
    }

    CoverageCell initialCell = null;
    i = 0;
    for (j = 0; j < cells[0].length - 1 && initialCell == null; j++)
      for (i = 0; i < cells.length && initialCell == null; i++)
        if (cells[i][j].desired) initialCell = cells[i][j];

    if (initialCell == null) {
      GuiUtils.errorMessage("Polygon coverage", "Polygon area is invalid");
      return;
    }

    CoverageCell current = initialCell;
    desiredCells--;

    int dir = -1;

    while (desiredCells > 0) {
      current.visited = true;
      current.active = false;
      if (dir == 1) {
        if (current.i < cells.length - 1
            && cells[current.i + 1][current.j].desired == true
            && cells[current.i + 1][current.j].visited == false) {
          current.next = cells[current.i + 1][current.j];
          cells[current.i + 1][current.j].previous = current;
          current = current.next;
          current.active = true;
        } else {
          dir = -1;
          if (current.j == cells[0].length - 1) break;

          while (!cells[current.i][current.j + 1].desired && i > 0 && current.previous != null) {
            current.active = false;
            current = current.previous;
          }

          if (i == 0) break;

          current.next = cells[current.i][current.j + 1];
          cells[current.i][current.j + 1].previous = current;
          current = current.next;
          current.active = true;
        }
      } else {
        if (current.i > 0
            && cells[current.i - 1][current.j].desired == true
            && cells[current.i - 1][current.j].visited == false) {
          current.next = cells[current.i - 1][current.j];
          cells[current.i - 1][current.j].previous = current;
          current = current.next;
          current.active = true;
        } else {
          dir = 1;
          if (current.j == cells[0].length - 1) break;

          while (current.previous != null
              && !cells[current.i][current.j + 1].desired
              && i < cells.length) {
            current.active = false;
            current = current.previous;
          }

          if (i == cells.length) break;

          current.next = cells[current.i][current.j + 1];
          cells[current.i][current.j + 1].previous = current;
          current = current.next;
          current.active = true;
        }
      }
      desiredCells--;
    }
    generatePlans(cells, initialCell);
  }