@SuppressWarnings("CallToThreadDumpStack")
    private ArrayList<FieldCandidate> split_line(ArrayList<FieldCandidate> candidates, int start, int maxFields) {

        ArrayList<FieldCandidate> selectedCandidates = new ArrayList<>();

        try {
            for (int posList = start; posList < candidates.size(); posList++) {

                FieldCandidate candidate = candidates.get(posList);
                boolean mustAdd = true;

                for (int i = 0; i < selectedCandidates.size(); i++) {

                    FieldCandidate selectedCandidate = selectedCandidates.get(i);

                    if (hasIntersection(candidate, selectedCandidate)) {
                        mustAdd = false;
                        break;
                    }
                }

                if (mustAdd) {
                    if (maxFields != Integer.MAX_VALUE) {

                        ArrayList<FieldCandidate> selectedCandidates2 = split_line(candidates, posList + 1, Integer.MAX_VALUE);

                        if (selectedCandidates.size() + selectedCandidates2.size() < maxFields) {

                            selectedCandidates.add(candidates.get(posList));
                        }
                    } else {

                        selectedCandidates.add(candidates.get(posList));
                    }
                }
            }
            //Call the Garbage Collector
            System.gc();

        } catch (Exception error) {
            /**
             * Show the StackTrace error [for debug]
             */
            error.printStackTrace();
//            System.out.println("Exception: " + error);
        }
        return selectedCandidates;
    }