public List<EquationGroup> getEquationGroups() {

        if (equationGroups == null) {

            List<Equation> equations = new ArrayList<>();
            for (int row=0; row<rows; row++) {
                for (int column=0; column<columns; column++) {

                    if (isNumber(row, column)) {

                        // We've found an exposed number in a cell.  Look at all the cells around it and subtract
                        // one for all the currently marked mines, and collect all the uncleared cells.  The
                        // resulting sum (if > 0) and uncleared cells (if there are any) constitute an equation.
                        int sum = cells[row][column];
                        List<Coordinate> adjacentUncleared = new ArrayList<>();
                        for (Coordinate adjacent : findAdjacentCoordinates(row, column)) {
                            int adjacentRow = adjacent.getRow();
                            int adjacentColumn = adjacent.getColumn();
                            if (isMine(adjacentRow, adjacentColumn)) {
                                sum--;
                            } else if (isUncleared(adjacentRow, adjacentColumn)) {
                                adjacentUncleared.add(new Coordinate(adjacentRow, adjacentColumn));
                            }

                            // If sum == 0, it means there are enough mines around this square to satisfy
                            if (sum > 0 && !adjacentUncleared.isEmpty()) {
                                equations.add(new Equation(adjacentUncleared, sum));
                            }
                        }
                    }
                }
            }
            equationGroups = groupEquations(equations);
        }
        return equationGroups;
    }