// Path: src/main/java/org/rhq/wfly/monitor/extension/MonitorLogger.java
// @MessageLogger(projectCode = "<<none>>")
// public interface MonitorLogger extends BasicLogger {
//     /**
//      * A logger with the category {@code org.rhq.wfly.monitor}.
//      */
//     MonitorLogger LOGGER = Logger.getMessageLogger(MonitorLogger.class, "org.rhq.wfly.monitor");
// 
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/ModelControllerClientFactory.java
// public interface ModelControllerClientFactory {
//     ModelControllerClient createClient();
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/SchedulerLogger.java
// @MessageLogger(projectCode = "<<none>>")
// public interface SchedulerLogger extends BasicLogger {
//     /**
//      * A logger with the category {@code org.wildfly.metrics.scheduler}.
//      */
//     SchedulerLogger LOGGER = Logger.getMessageLogger(SchedulerLogger.class, "org.wildfly.metrics.scheduler");
// 
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/diagnose/Diagnostics.java
// public interface Diagnostics {
//     Timer getRequestTimer();
//     Meter getErrorRate();
//     Meter getDelayedRate();
// 
//     Meter getStorageErrorRate();
//     Counter getStorageBufferSize();
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/storage/DataPoint.java
// public final class DataPoint {
//     private Task task;
//     private long timestamp;
//     private double value;
// 
//     public DataPoint(Task task, double value) {
//         this.task = task;
//         this.timestamp = System.currentTimeMillis();
//         this.value = value;
//     }
// 
//     public Task getTask() {
//         return task;
//     }
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// }


import com.codahale.metrics.Timer;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.rhq.wfly.monitor.extension.MonitorLogger;
import org.wildfly.metrics.scheduler.ModelControllerClientFactory;
import org.wildfly.metrics.scheduler.SchedulerLogger;
import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
import org.wildfly.metrics.scheduler.storage.DataPoint;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.wildfly.metrics.scheduler.polling.Scheduler.State.RUNNING;
import static org.wildfly.metrics.scheduler.polling.Scheduler.State.STOPPED;

                long durationMs = requestContext.stop() / 1000000;

                String outcome = response.get(OUTCOME).asString();
                if (SUCCESS.equals(outcome))
                {

                    if (durationMs > group.getInterval().millis()) {
                        monitor.getDelayedRate().mark(1);
                    }

                    List<Property> steps = response.get(RESULT).asPropertyList();
                    assert steps.size() == group.size() : "group structure doesn't match actual response structure";

                    int i=0;
                    for (Property step : steps) {
                        Task task = group.getTask(i);

                        // deconstruct model node
                        ModelNode data = step.getValue();
                        Double value = null;
                        if(task.getSubref()!=null)
                        {
                            value = data.get(RESULT).get(task.getSubref()).asDouble();
                        }
                        else
                        {
                            value = data.get(RESULT).asDouble();
                        }

// Path: src/main/java/org/rhq/wfly/monitor/extension/MonitorLogger.java
// @MessageLogger(projectCode = "<<none>>")
// public interface MonitorLogger extends BasicLogger {
//     /**
//      * A logger with the category {@code org.rhq.wfly.monitor}.
//      */
//     MonitorLogger LOGGER = Logger.getMessageLogger(MonitorLogger.class, "org.rhq.wfly.monitor");
// 
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/ModelControllerClientFactory.java
// public interface ModelControllerClientFactory {
//     ModelControllerClient createClient();
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/SchedulerLogger.java
// @MessageLogger(projectCode = "<<none>>")
// public interface SchedulerLogger extends BasicLogger {
//     /**
//      * A logger with the category {@code org.wildfly.metrics.scheduler}.
//      */
//     SchedulerLogger LOGGER = Logger.getMessageLogger(SchedulerLogger.class, "org.wildfly.metrics.scheduler");
// 
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/diagnose/Diagnostics.java
// public interface Diagnostics {
//     Timer getRequestTimer();
//     Meter getErrorRate();
//     Meter getDelayedRate();
// 
//     Meter getStorageErrorRate();
//     Counter getStorageBufferSize();
// }
// 
// Path: src/main/java/org/wildfly/metrics/scheduler/storage/DataPoint.java
// public final class DataPoint {
//     private Task task;
//     private long timestamp;
//     private double value;
// 
//     public DataPoint(Task task, double value) {
//         this.task = task;
//         this.timestamp = System.currentTimeMillis();
//         this.value = value;
//     }
// 
//     public Task getTask() {
//         return task;
//     }
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// }


// Path: src/main/java/org/wildfly/metrics/scheduler/polling/IntervalBasedScheduler.java
import com.codahale.metrics.Timer;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.rhq.wfly.monitor.extension.MonitorLogger;
import org.wildfly.metrics.scheduler.ModelControllerClientFactory;
import org.wildfly.metrics.scheduler.SchedulerLogger;
import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
import org.wildfly.metrics.scheduler.storage.DataPoint;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.wildfly.metrics.scheduler.polling.Scheduler.State.RUNNING;
import static org.wildfly.metrics.scheduler.polling.Scheduler.State.STOPPED;


                long durationMs = requestContext.stop() / 1000000;

                String outcome = response.get(OUTCOME).asString();
                if (SUCCESS.equals(outcome))
                {

                    if (durationMs > group.getInterval().millis()) {
                        monitor.getDelayedRate().mark(1);
                    }

                    List<Property> steps = response.get(RESULT).asPropertyList();
                    assert steps.size() == group.size() : "group structure doesn't match actual response structure";

                    int i=0;
                    for (Property step : steps) {
                        Task task = group.getTask(i);

                        // deconstruct model node
                        ModelNode data = step.getValue();
                        Double value = null;
                        if(task.getSubref()!=null)
                        {
                            value = data.get(RESULT).get(task.getSubref()).asDouble();
                        }
                        else
                        {
                            value = data.get(RESULT).asDouble();
                        }

                        completionHandler.onCompleted(new DataPoint(task, value));