class MatchMaker {

    public Map<Integer, PotentialColumn> findPotentialDates(List<? extends List<? extends String>> tableData,
            ConfigurationProvider provider)
    {
        Map<Integer, PotentialColumn> potentialDates = New.map();
        List<Pair<DateFormat, Pattern>> formatsAndPattern = compilePatterns(provider.getDateFormats().getFormats());
        int numberOfRows = tableData.size();

        Map<Integer, Integer> numberOfNonBlankCells = New.map();
        boolean hasCellsBeenCounted = false;

        for (Pair<DateFormat, Pattern> pair : formatsAndPattern)
        {
            DateFormat format = pair.getFirstObject();
            Pattern pattern = pair.getSecondObject();

            boolean isEmptyRegex = StringUtils.isEmpty(format.getRegex());

            for (List<? extends String> row : tableData)
            {
                for (int columnIndex = 0; columnIndex < row.size(); ++columnIndex)
                {
                    String cell = row.get(columnIndex);
                    Integer numColumnIndex = Integer.valueOf(columnIndex);
                    if (StringUtils.isNotEmpty(cell))
                    {
                        if (!hasCellsBeenCounted)
                        {
                            if (!numberOfNonBlankCells.containsKey(numColumnIndex))
                            {
                                numberOfNonBlankCells.put(numColumnIndex, Integer.valueOf(0));
                            }

                            numberOfNonBlankCells.put(numColumnIndex,
                                    Integer.valueOf(numberOfNonBlankCells.get(numColumnIndex).intValue() + 1));
                        }

                        boolean matches = isEmptyRegex;

                        if (!matches)
                        {
                            matches = pattern.matcher(cell).matches();
                        }

                        if (matches)
                        {
                            if (!potentialDates.containsKey(numColumnIndex))
                            {
                                PotentialColumn potential = new PotentialColumn();
                                potential.setColumnIndex(columnIndex);

                                potentialDates.put(numColumnIndex, potential);
                            }

                            PotentialColumn potential = potentialDates.get(numColumnIndex);

                            String formatKey = format.getSdf();

                            if (!potential.getFormats().containsKey(format.getSdf()))
                            {
                                SuccessfulFormat successfulFormat = new SuccessfulFormat();
                                successfulFormat.setNumberOfSuccesses(0);
                                successfulFormat.setFormat(format);

                                potential.getFormats().put(formatKey, successfulFormat);
                            }

                            SuccessfulFormat successfulFormat = potential.getFormats().get(formatKey);

                            if (!isEmptyRegex)
                            {
                                successfulFormat.setNumberOfSuccesses(successfulFormat.getNumberOfSuccesses() + 1);
                            }
                            else
                            {
                                successfulFormat.setNumberOfSuccesses(
                                        (int)(Constants.THRESHOLD_SCORE / Constants.PERCENT * numberOfRows + 1));
                            }
                        }
                    }
                }

                if (isEmptyRegex)
                {
                    break;
                }
            }

            hasCellsBeenCounted = true;
        }

        recalculateScores(numberOfNonBlankCells, potentialDates);

        return potentialDates;
    }

}