@Override
    @SuppressWarnings("rawtypes")
    public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters,
            SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers) {
        MetaData.Builder metaData = new MetaData.Builder(sanitize, hostName, clock.getTime() / 1000, period)
                .type(COLLECTD_TYPE_GAUGE);
        try {
            connect(sender);
            for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
                serializeGauge(metaData.plugin(entry.getKey()), entry.getValue());
            }
            for (Map.Entry<String, Counter> entry : counters.entrySet()) {
                serializeCounter(metaData.plugin(entry.getKey()), entry.getValue());
            }
            for (Map.Entry<String, Histogram> entry : histograms.entrySet()) {
                serializeHistogram(metaData.plugin(entry.getKey()), entry.getValue());
            }
            for (Map.Entry<String, Meter> entry : meters.entrySet()) {
                serializeMeter(metaData.plugin(entry.getKey()), entry.getValue());
            }
            for (Map.Entry<String, Timer> entry : timers.entrySet()) {
                serializeTimer(metaData.plugin(entry.getKey()), entry.getValue());
            }
        } catch (IOException e) {
            LOG.warn("Unable to report to Collectd", e);
        } finally {
            disconnect(sender);
        }
    }
@Test
    public void reportsTimers() throws Exception {
        Timer timer = mock(Timer.class);
        Snapshot snapshot = mock(Snapshot.class);
        when(timer.getSnapshot()).thenReturn(snapshot);
        when(timer.getCount()).thenReturn(1L);
        when(timer.getSnapshot()).thenReturn(snapshot);
        when(snapshot.getMax()).thenReturn(MILLISECONDS.toNanos(100));
        when(snapshot.getMean()).thenReturn((double) MILLISECONDS.toNanos(200));
        when(snapshot.getMin()).thenReturn(MILLISECONDS.toNanos(300));
        when(snapshot.getStdDev()).thenReturn((double) MILLISECONDS.toNanos(400));
        when(snapshot.getMedian()).thenReturn((double) MILLISECONDS.toNanos(500));
        when(snapshot.get75thPercentile()).thenReturn((double) MILLISECONDS.toNanos(600));
        when(snapshot.get95thPercentile()).thenReturn((double) MILLISECONDS.toNanos(700));
        when(snapshot.get98thPercentile()).thenReturn((double) MILLISECONDS.toNanos(800));
        when(snapshot.get99thPercentile()).thenReturn((double) MILLISECONDS.toNanos(900));
        when(snapshot.get999thPercentile()).thenReturn((double) MILLISECONDS.toNanos(1000));
        when(timer.getOneMinuteRate()).thenReturn(11.0);
        when(timer.getFiveMinuteRate()).thenReturn(12.0);
        when(timer.getFifteenMinuteRate()).thenReturn(13.0);
        when(timer.getMeanRate()).thenReturn(14.0);

        reporter.report(
                map(),
                map(),
                map(),
                map(),
                map("timer", timer));

        assertThat(nextValues(receiver)).containsExactly(1d);
        assertThat(nextValues(receiver)).containsExactly(100d);
        assertThat(nextValues(receiver)).containsExactly(200d);
        assertThat(nextValues(receiver)).containsExactly(300d);
        assertThat(nextValues(receiver)).containsExactly(400d);
        assertThat(nextValues(receiver)).containsExactly(500d);
        assertThat(nextValues(receiver)).containsExactly(600d);
        assertThat(nextValues(receiver)).containsExactly(700d);
        assertThat(nextValues(receiver)).containsExactly(800d);
        assertThat(nextValues(receiver)).containsExactly(900d);
        assertThat(nextValues(receiver)).containsExactly(1000d);
        assertThat(nextValues(receiver)).containsExactly(11d);
        assertThat(nextValues(receiver)).containsExactly(12d);
        assertThat(nextValues(receiver)).containsExactly(13d);
        assertThat(nextValues(receiver)).containsExactly(14d);
    }