class TimerSerializer extends StdSerializer<Timer> {

        private static final long serialVersionUID = 6283520188524929099L;

        private final String rateUnit;
        private final double rateFactor;
        private final String durationUnit;
        private final double durationFactor;
        private final boolean showSamples;

        private TimerSerializer(TimeUnit rateUnit, TimeUnit durationUnit,
                                boolean showSamples) {
            super(Timer.class);
            this.rateUnit = calculateRateUnit(rateUnit, "calls");
            this.rateFactor = rateUnit.toSeconds(1);
            this.durationUnit = durationUnit.toString().toLowerCase(Locale.US);
            this.durationFactor = 1.0 / durationUnit.toNanos(1);
            this.showSamples = showSamples;
        }

        @Override
        public void serialize(Timer timer, JsonGenerator json,
                              SerializerProvider provider) throws IOException {<FILL_FUNCTION_BODY>}
    }

            json.writeStartObject();
            final Snapshot snapshot = timer.getSnapshot();
            json.writeNumberField("count", timer.getCount());
            json.writeNumberField("min", snapshot.getMin() *
                                         this.durationFactor);
            json.writeNumberField("mean", snapshot.getMean() *
                                          this.durationFactor);
            json.writeNumberField("max", snapshot.getMax() *
                                         this.durationFactor);
            json.writeNumberField("stddev", snapshot.getStdDev() *
                                            this.durationFactor);

            json.writeNumberField("p50", snapshot.getMedian() *
                                         this.durationFactor);
            json.writeNumberField("p75", snapshot.get75thPercentile() *
                                         this.durationFactor);
            json.writeNumberField("p95", snapshot.get95thPercentile() *
                                         this.durationFactor);
            json.writeNumberField("p98", snapshot.get98thPercentile() *
                                         this.durationFactor);
            json.writeNumberField("p99", snapshot.get99thPercentile() *
                                         this.durationFactor);
            json.writeNumberField("p999", snapshot.get999thPercentile() *
                                          this.durationFactor);
            json.writeStringField("duration_unit", this.durationUnit);

            if (this.showSamples) {
                final long[] values = snapshot.getValues();
                final double[] scaledValues = new double[values.length];
                for (int i = 0; i < values.length; i++) {
                    scaledValues[i] = values[i] * this.durationFactor;
                }
                json.writeObjectField("values", scaledValues);
            }

            json.writeNumberField("mean_rate", timer.getMeanRate() *
                                               this.rateFactor);
            json.writeNumberField("m15_rate", timer.getFifteenMinuteRate() *
                                              this.rateFactor);
            json.writeNumberField("m5_rate", timer.getFiveMinuteRate() *
                                             this.rateFactor);
            json.writeNumberField("m1_rate", timer.getOneMinuteRate() *
                                             this.rateFactor);
            json.writeStringField("rate_unit", this.rateUnit);
            json.writeEndObject();
        
<no_super_class>