class ComparableDependency extends AbstractDependency {

    @Override
    public final CheckResult call() throws Exception {
        // TODO Replace this with a SimpleDependency and a CheckMethod that accepts a WallClock.
        final long start = System.currentTimeMillis();
        try {
            final T value = getValue();
            final CheckStatus status;
            final T threshold;
            if (value.compareTo(maxOK) <= 0) {
                threshold = null;
                status = CheckStatus.OK;
            } else if (maxMinor != null && value.compareTo(maxMinor) <= 0) {
                threshold = maxOK;
                status = CheckStatus.MINOR;
            } else if (maxMajor != null && value.compareTo(maxMajor) <= 0) {
                threshold = maxMinor;
                status = CheckStatus.MAJOR;
            } else {
                threshold = maxMajor != null ? maxMajor : (maxMinor != null ? maxMinor : maxOK);
                status = CheckStatus.OUTAGE;
            }
            final long duration = System.currentTimeMillis() - start;
            final String errorMessage = formatErrorMessage(status, value, threshold, start, duration, null);
            return CheckResult.newBuilder(this, status, errorMessage)
                    .setTimestamp(start)
                    .setDuration(duration)
                    .build();

        } catch (final Exception e) {
            final long duration = System.currentTimeMillis() - start;
            final String errorMessage = formatErrorMessage(CheckStatus.OUTAGE, null, null, start, duration, e);
            return CheckResult.newBuilder(this, CheckStatus.OUTAGE, errorMessage)
                    .setTimestamp(start)
                    .setDuration(duration)
                    .setThrowable(e)
                    .build();
        }
    }

}

class ComparableDependencyTest {

    @Test
    public void testSane() throws Exception {

        final AtomicInteger val = new AtomicInteger(0);
        final CompDep compDep = new CompDep(val, 5, 10, 15);

        val.set(0);
        assertEquals("OK,0,null,null", compDep.call().getErrorMessage());

        val.set(5);
        assertEquals("OK,5,null,null", compDep.call().getErrorMessage());

        val.set(6);
        assertEquals("MINOR,6,5,null", compDep.call().getErrorMessage());

        val.set(10);
        assertEquals("MINOR,10,5,null", compDep.call().getErrorMessage());

        val.set(11);
        assertEquals("MAJOR,11,10,null", compDep.call().getErrorMessage());

        val.set(15);
        assertEquals("MAJOR,15,10,null", compDep.call().getErrorMessage());

        val.set(16);
        assertEquals("OUTAGE,16,15,null", compDep.call().getErrorMessage());
    }

}