// Path: core/src/main/java/com/caseystella/analytics/DataPoint.java
// public class DataPoint {
//     private long timestamp;
//     private double value;
//     private Map<String, String> metadata;
//     private String source;
// 
//     public DataPoint() {
// 
//     }
// 
//     public DataPoint(long timestamp, double value, Map<String, String> metadata, String source) {
//         this.timestamp = timestamp;
//         this.value = value;
//         this.metadata = metadata;
//         this.source = source;
//     }
// 
//     public String getSource() {
//         return source;
//     }
// 
//     public void setSource(String source) {
//         this.source = source;
//     }
// 
// 
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public void setTimestamp(long timestamp) {
//         this.timestamp = timestamp;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// 
//     public void setValue(double value) {
//         this.value = value;
//     }
// 
//     public Map<String, String> getMetadata() {
//         return metadata;
//     }
// 
//     public void setMetadata(Map<String, String> metadata) {
//         this.metadata = metadata;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         DataPoint dataPoint = (DataPoint) o;
// 
//         if (getTimestamp() != dataPoint.getTimestamp()) return false;
//         if (Double.compare(dataPoint.getValue(), getValue()) != 0) return false;
//         if (getMetadata() != null ? !getMetadata().equals(dataPoint.getMetadata()) : dataPoint.getMetadata() != null)
//             return false;
//         return source != null ? source.equals(dataPoint.source) : dataPoint.source == null;
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result;
//         long temp;
//         result = (int) (getTimestamp() ^ (getTimestamp() >>> 32));
//         temp = Double.doubleToLongBits(getValue());
//         result = 31 * result + (int) (temp ^ (temp >>> 32));
//         result = 31 * result + (getMetadata() != null ? getMetadata().hashCode() : 0);
//         result = 31 * result + (source != null ? source.hashCode() : 0);
//         return result;
//     }
//     @Override
//     public String toString() {
//         return "(" +
//                 "timestamp=" + timestamp +
//                 ", value=" + value +
//                 ", metadata=" + metadata +
//                 ", source=" + source+
//                 ')';
//     }
// 
// }
// 
// Path: core/src/main/java/com/caseystella/analytics/util/JSONUtil.java
// public enum JSONUtil {
//     INSTANCE;
//     static ThreadLocal<ObjectMapper> MAPPER = new ThreadLocal<ObjectMapper>() {
//         /**
//          * Returns the current thread's "initial value" for this
//          * thread-local variable.  This method will be invoked the first
//          * time a thread accesses the variable with the {@link #get}
//          * method, unless the thread previously invoked the {@link #set}
//          * method, in which case the <tt>initialValue</tt> method will not
//          * be invoked for the thread.  Normally, this method is invoked at
//          * most once per thread, but it may be invoked again in case of
//          * subsequent invocations of {@link #remove} followed by {@link #get}.
//          * <p/>
//          * <p>This implementation simply returns <tt>null</tt>; if the
//          * programmer desires thread-local variables to have an initial
//          * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be
//          * subclassed, and this method overridden.  Typically, an
//          * anonymous inner class will be used.
//          *
//          * @return the initial value for this thread-local
//          */
//         @Override
//         protected ObjectMapper initialValue() {
//             return new ObjectMapper();
//         }
//     };
// 
//     public <T> T load(File f, Class<T> clazz) throws IOException {
//         return load(new FileInputStream(f), clazz);
//     }
// 
//     public <T> T load(InputStream is, Class<T> clazz) throws IOException {
//         T ret = MAPPER.get().readValue(is, clazz);
//         return ret;
//     }
//     public <T> T load(String s, Charset c, Class<T> clazz) throws IOException {
//         return load( new ByteArrayInputStream(s.getBytes(c)), clazz);
//     }
//     public <T> T load(String s, Class<T> clazz) throws IOException {
//         return load( s, Charset.defaultCharset(), clazz);
//     }
//     public <T> T load(InputStream is, TypeReference<T> reference) throws IOException {
//         T ret = MAPPER.get().readValue(is, reference);
//         return ret;
//     }
//     public <T> T load(String s, Charset c, TypeReference<T> reference) throws IOException {
//         return load( new ByteArrayInputStream(s.getBytes(c)), reference);
//     }
//     public <T> T load(String s, TypeReference<T> reference) throws IOException {
//         return load( s, Charset.defaultCharset(), reference);
//     }
// 
//     public  String toJSON(Object bean ) throws JsonProcessingException {
//         return MAPPER.get().writerWithDefaultPrettyPrinter().writeValueAsString(bean);
//     }
// 
// }


import com.caseystella.analytics.DataPoint;
import com.caseystella.analytics.util.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import java.util.*;
package com.caseystella.analytics.outlier;



public enum OutlierHelper {
    INSTANCE;
// Path: core/src/main/java/com/caseystella/analytics/DataPoint.java
// public class DataPoint {
//     private long timestamp;
//     private double value;
//     private Map<String, String> metadata;
//     private String source;
// 
//     public DataPoint() {
// 
//     }
// 
//     public DataPoint(long timestamp, double value, Map<String, String> metadata, String source) {
//         this.timestamp = timestamp;
//         this.value = value;
//         this.metadata = metadata;
//         this.source = source;
//     }
// 
//     public String getSource() {
//         return source;
//     }
// 
//     public void setSource(String source) {
//         this.source = source;
//     }
// 
// 
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public void setTimestamp(long timestamp) {
//         this.timestamp = timestamp;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// 
//     public void setValue(double value) {
//         this.value = value;
//     }
// 
//     public Map<String, String> getMetadata() {
//         return metadata;
//     }
// 
//     public void setMetadata(Map<String, String> metadata) {
//         this.metadata = metadata;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         DataPoint dataPoint = (DataPoint) o;
// 
//         if (getTimestamp() != dataPoint.getTimestamp()) return false;
//         if (Double.compare(dataPoint.getValue(), getValue()) != 0) return false;
//         if (getMetadata() != null ? !getMetadata().equals(dataPoint.getMetadata()) : dataPoint.getMetadata() != null)
//             return false;
//         return source != null ? source.equals(dataPoint.source) : dataPoint.source == null;
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result;
//         long temp;
//         result = (int) (getTimestamp() ^ (getTimestamp() >>> 32));
//         temp = Double.doubleToLongBits(getValue());
//         result = 31 * result + (int) (temp ^ (temp >>> 32));
//         result = 31 * result + (getMetadata() != null ? getMetadata().hashCode() : 0);
//         result = 31 * result + (source != null ? source.hashCode() : 0);
//         return result;
//     }
//     @Override
//     public String toString() {
//         return "(" +
//                 "timestamp=" + timestamp +
//                 ", value=" + value +
//                 ", metadata=" + metadata +
//                 ", source=" + source+
//                 ')';
//     }
// 
// }
// 
// Path: core/src/main/java/com/caseystella/analytics/util/JSONUtil.java
// public enum JSONUtil {
//     INSTANCE;
//     static ThreadLocal<ObjectMapper> MAPPER = new ThreadLocal<ObjectMapper>() {
//         /**
//          * Returns the current thread's "initial value" for this
//          * thread-local variable.  This method will be invoked the first
//          * time a thread accesses the variable with the {@link #get}
//          * method, unless the thread previously invoked the {@link #set}
//          * method, in which case the <tt>initialValue</tt> method will not
//          * be invoked for the thread.  Normally, this method is invoked at
//          * most once per thread, but it may be invoked again in case of
//          * subsequent invocations of {@link #remove} followed by {@link #get}.
//          * <p/>
//          * <p>This implementation simply returns <tt>null</tt>; if the
//          * programmer desires thread-local variables to have an initial
//          * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be
//          * subclassed, and this method overridden.  Typically, an
//          * anonymous inner class will be used.
//          *
//          * @return the initial value for this thread-local
//          */
//         @Override
//         protected ObjectMapper initialValue() {
//             return new ObjectMapper();
//         }
//     };
// 
//     public <T> T load(File f, Class<T> clazz) throws IOException {
//         return load(new FileInputStream(f), clazz);
//     }
// 
//     public <T> T load(InputStream is, Class<T> clazz) throws IOException {
//         T ret = MAPPER.get().readValue(is, clazz);
//         return ret;
//     }
//     public <T> T load(String s, Charset c, Class<T> clazz) throws IOException {
//         return load( new ByteArrayInputStream(s.getBytes(c)), clazz);
//     }
//     public <T> T load(String s, Class<T> clazz) throws IOException {
//         return load( s, Charset.defaultCharset(), clazz);
//     }
//     public <T> T load(InputStream is, TypeReference<T> reference) throws IOException {
//         T ret = MAPPER.get().readValue(is, reference);
//         return ret;
//     }
//     public <T> T load(String s, Charset c, TypeReference<T> reference) throws IOException {
//         return load( new ByteArrayInputStream(s.getBytes(c)), reference);
//     }
//     public <T> T load(String s, TypeReference<T> reference) throws IOException {
//         return load( s, Charset.defaultCharset(), reference);
//     }
// 
//     public  String toJSON(Object bean ) throws JsonProcessingException {
//         return MAPPER.get().writerWithDefaultPrettyPrinter().writeValueAsString(bean);
//     }
// 
// }


// Path: core/src/main/java/com/caseystella/analytics/outlier/OutlierHelper.java
import com.caseystella.analytics.DataPoint;
import com.caseystella.analytics.util.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import java.util.*;

package com.caseystella.analytics.outlier;



public enum OutlierHelper {
    INSTANCE;
    public Map<String, Object> toJson(DataPoint dp) {