public List<ColumnMatchResult<?>> getMismatchedColumns(List<Column> columns, ChecksumResult controlChecksum, ChecksumResult testChecksum)
    {
        return columns.stream()
                .flatMap(column -> columnValidators.get(column.getCategory()).get().validate(column, controlChecksum, testChecksum).stream())
                .filter(columnMatchResult -> !columnMatchResult.isMatched())
                .collect(toImmutableList());
    }
@Test
    public void testValidateVarcharMapAsDouble()
    {
        Map<String, Object> keyEqualNullCount = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_key_array$null_count", 1L)
                .put("map_varchar_varchar_key_array_as_double$null_count", 1L)
                .build();
        Map<String, Object> keyUnequalNullCount = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_key_array$null_count", 1L)
                .put("map_varchar_varchar_key_array_as_double$null_count", 2L)
                .build();
        Map<String, Object> keyAsDoubleArrayCounts = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_key_array_as_double$nan_count", 2L)
                .put("map_varchar_varchar_key_array_as_double$pos_inf_count", 3L)
                .put("map_varchar_varchar_key_array_as_double$neg_inf_count", 4L)
                .build();
        Map<String, Object> valueEqualNullCount = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_value_array$null_count", 1L)
                .put("map_varchar_varchar_value_array_as_double$null_count", 1L)
                .build();
        Map<String, Object> valueUnequalNullCount = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_value_array$null_count", 1L)
                .put("map_varchar_varchar_value_array_as_double$null_count", 2L)
                .build();
        Map<String, Object> valueAsDoubleArrayCounts = ImmutableMap.<String, Object>builder()
                .put("map_varchar_varchar_value_array_as_double$nan_count", 2L)
                .put("map_varchar_varchar_value_array_as_double$pos_inf_count", 3L)
                .put("map_varchar_varchar_value_array_as_double$neg_inf_count", 4L)
                .build();

        List<Column> columns = ImmutableList.of(MAP_VARCHAR_VARCHAR_COLUMN);

        // Matched, by keys as double and values as varchar.
        ChecksumResult controlChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(valueUnequalNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        ChecksumResult testChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0 + RELATIVE_ERROR_MARGIN)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(valueUnequalNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0 - RELATIVE_ERROR_MARGIN * 10)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        assertTrue(stringAsDoubleValidator.getMismatchedColumns(columns, controlChecksum, testChecksum).isEmpty());

        // Matched, by keys as varchar and values as double.
        controlChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(keyUnequalNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(valueEqualNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        testChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(keyUnequalNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0 - RELATIVE_ERROR_MARGIN * 10)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(valueEqualNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0 + RELATIVE_ERROR_MARGIN)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        assertTrue(stringAsDoubleValidator.getMismatchedColumns(columns, controlChecksum, testChecksum).isEmpty());

        // Unmatched, due to matched keys as double and unmatched values as varchar.
        controlChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(valueUnequalNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        testChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0 + RELATIVE_ERROR_MARGIN)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(valueUnequalNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        assertMismatchedColumns(columns, controlChecksum, testChecksum, stringAsDoubleValidator, MAP_VARCHAR_VARCHAR_COLUMN);

        // Unmatched, due to unmatched keys as double and matched values as double.
        controlChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0xa}))
                        .putAll(valueEqualNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        testChecksum = new ChecksumResult(
                10,
                ImmutableMap.<String, Object>builder()
                        .put("map_varchar_varchar$checksum", new SqlVarbinary(new byte[] {0xb}))
                        .put("map_varchar_varchar$cardinality_checksum", new SqlVarbinary(new byte[] {0xd}))
                        .put("map_varchar_varchar$cardinality_sum", 10L)

                        .put("map_varchar_varchar$keys_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(keyEqualNullCount)
                        .put("map_varchar_varchar_key_array_as_double$sum", 1.0 - RELATIVE_ERROR_MARGIN * 10)
                        .putAll(keyAsDoubleArrayCounts)

                        .put("map_varchar_varchar$values_checksum", new SqlVarbinary(new byte[] {0x1a}))
                        .putAll(valueEqualNullCount)
                        .put("map_varchar_varchar_value_array_as_double$sum", 1.0 + RELATIVE_ERROR_MARGIN)
                        .putAll(valueAsDoubleArrayCounts)
                        .build());
        assertMismatchedColumns(columns, controlChecksum, testChecksum, stringAsDoubleValidator, MAP_VARCHAR_VARCHAR_COLUMN);
    }