public Map<Long, Map<String, List<FileRef>>> groupByCRC(Map<Long, List<FileRef>> filesBySizeMap) {
        Map<Long, Map<String, List<FileRef>>> retval = new HashMap<Long, Map<String, List<FileRef>>>();
        if (filesBySizeMap != null) {
            Iterator<Map.Entry<Long, List<FileRef>>> iter = filesBySizeMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Long, List<FileRef>> entry = iter.next();
                List<FileRef> fileList = entry.getValue();
                Map<String, List<FileRef>> filesByCRC = new HashMap<String, List<FileRef>>();
                if (fileList != null) {
                    // group by CRC
                    for (FileRef fileRef : fileList) {
                        try {
                            fileRef.calculateMD5();
                            if (!filesByCRC.containsKey(fileRef.getMD5())) {
                                filesByCRC.put(fileRef.getMD5(), new ArrayList<FileRef>());
                            }
                            filesByCRC.get(fileRef.getMD5()).add(fileRef);
                        }
                        catch (Exception ex) {
                            // Log.Error
                        }
                    }

                    // remove groups with only one entry
                    Iterator<Map.Entry<String, List<FileRef>>> crcGroupIterator = filesByCRC.entrySet().iterator();
                    while (crcGroupIterator.hasNext()) {
                        Map.Entry<String, List<FileRef>> crcGroupEntry = crcGroupIterator.next();
                        if (crcGroupEntry.getValue().size() < 2) {
                            crcGroupIterator.remove();
                        }
                    }

                    if (filesByCRC.size() > 0) {
                        Long fileSize = entry.getKey();
                        retval.put(fileSize, filesByCRC);
                    }

                }
            }
        }
        return retval;
    }