private void RecursiveSolve(SolverNode node, List<Matrix> solutions)
        {
            List<Cell> emptyCells = ListEmptyCells(node.MatrixState);

            if (node.MatrixState.HasSolution && !node.MatrixState.IsResolved)
            {
                foreach (Cell emptyCell in emptyCells)
                {
                    CalculatePossibilities(emptyCell, node.MatrixState);
                    if (emptyCell.Possibilities.Count == 1)
                    {
                        int foundedValue = emptyCell.Possibilities[0];
                        emptyCell.Value = foundedValue;
                        node.MatrixState.LoadValue(emptyCell.Coordinates, emptyCell.Value);
                        if (ValueAdded != null)
                            ValueAdded(this, new ValueChangedEventArgs(node.MatrixState));
                        RecursiveSolve(node, solutions);
                        if (solutions.Count == solutions.Capacity)
                            break;
                        if (!node.MatrixState.HasSolution)
                        {
                            node.Dispose();
                            node = null;
                            break;
                        }
                    }

                }
            }

            if (emptyCells.Count == 0 && !node.MatrixState.IsResolved)
            {
                node.MatrixState.IsResolved = true;
                if (!solutions.Contains(node.MatrixState, Matrix.Comparer) && solutions.Count < solutions.Capacity)
                    solutions.Add(node.MatrixState);


            }
            else
            {
                
                if (node != null && node.ChildNodes.Count == 0 && !node.MatrixState.IsResolved && node.MatrixState.HasSolution)
                {
                    
                    
                    List<Cell> orderedEmptyCells = (from emptyCell in emptyCells orderby emptyCell.Possibilities.Count select emptyCell).ToList();
                    if (orderedEmptyCells.Count > 0)
                    {
                        
                        Cell lessPossibilitiesCell = orderedEmptyCells[0];
                        if (lessPossibilitiesCell.Possibilities.Count > 0)
                        {
                            foreach (int possibility in lessPossibilitiesCell.Possibilities)
                            {
                                Matrix possibleState = new Matrix(node.MatrixState);
                                possibleState.LoadValue(lessPossibilitiesCell.Coordinates, possibility);

                                if (ValueAdded != null)
                                    ValueAdded(this, new ValueChangedEventArgs(possibleState));
                                node.ChildNodes.Add(new SolverNode(possibleState));

                            }
                            int noSolutionCount = 0;
                            foreach (SolverNode childNode in node.ChildNodes)
                            {
                                RecursiveSolve(childNode, solutions);

                                if (solutions.Count == solutions.Capacity)
                                    break;
                                if (!node.MatrixState.HasSolution)
                                {
                                    node.Dispose();
                                    node = null;
                                    break;
                                }
                                if (!childNode.MatrixState.HasSolution)
                                {
                                    noSolutionCount++;
                                }
                            }
                            if (node.ChildNodes.Count > 0 && node.ChildNodes.Count == noSolutionCount && !node.MatrixState.IsResolved)
                            {
                                node.MatrixState.HasSolution = false;
                                if (ValueRemoved != null)
                                    ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                 
                            }
                        }
                        else
                        {
                            node.MatrixState.HasSolution = false;
                            if (ValueRemoved != null)
                                ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                 
                        }
                    }
                    else
                    {
                        node.MatrixState.HasSolution = false;
                        if (ValueRemoved != null)
                            ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                    }
                }
            }

        }