// Path: src/main/java/com/stackify/api/ErrorItem.java
// @AllArgsConstructor
// @NoArgsConstructor
// @Builder(builderClassName = "Builder", builderMethodName = "newBuilder", toBuilder = true)
// @Data
// @JsonInclude(JsonInclude.Include.NON_NULL)
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class ErrorItem {
// 
//     /**
//      * The error message
//      */
//     @Setter
//     @JsonProperty("Message")
//     private String message;
// 
//     /**
//      * The error's class name
//      */
//     @JsonProperty("ErrorType")
//     private String errorType;
// 
//     /**
//      * The error type code
//      */
//     @JsonProperty("ErrorTypeCode")
//     private String errorTypeCode;
// 
//     /**
//      * Custom data for the error
//      */
//     @JsonProperty("Data")
//     private Map<String, String> data;
// 
//     /**
//      * The method name
//      */
//     @JsonProperty("SourceMethod")
//     private String sourceMethod;
// 
//     /**
//      * The stack trace
//      */
//     @JsonProperty("StackTrace")
//     private List<TraceFrame> stackTrace;
// 
//     /**
//      * The cause of this error
//      */
//     @JsonProperty("InnerError")
//     private ErrorItem innerError;
// 
// }
// 
// Path: src/main/java/com/stackify/api/StackifyError.java
// @AllArgsConstructor
// @NoArgsConstructor
// @Builder(builderClassName = "Builder", builderMethodName = "newBuilder", toBuilder = true)
// @Data
// @JsonInclude(JsonInclude.Include.NON_NULL)
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class StackifyError {
// 
//     /**
//      * Environment
//      */
//     @JsonProperty("EnvironmentDetail")
//     private EnvironmentDetail environmentDetail;
// 
//     /**
//      * Date/time of the error
//      */
//     @JsonProperty("OccurredEpochMillis")
//     private Long occurredEpochMillis;
// 
//     /**
//      * Error details
//      */
//     @JsonProperty("Error")
//     private ErrorItem error;
// 
//     /**
//      * Details of the web request
//      */
//     @JsonProperty("WebRequestDetail")
//     private WebRequestDetail webRequestDetail;
// 
//     /**
//      * Server variables
//      */
//     @JsonProperty("ServerVariables")
//     private Map<String, String> serverVariables;
// 
//     /**
//      * Customer name
//      */
//     @JsonProperty("CustomerName")
//     private String customerName;
// 
//     /**
//      * User name
//      */
//     @JsonProperty("UserName")
//     private String userName;
// 
// }
// 
// Path: src/main/java/com/stackify/api/common/codec/MessageDigests.java
// public class MessageDigests {
// 
//     /**
//      * Generates an MD5 hash hex string for the input string
//      * @param input The input string
//      * @return MD5 hash hex string
//      */
//     public static String md5Hex(final String input) {
// 		if (input == null) {
// 			throw new NullPointerException("String is null");
// 		}
// 
//     	MessageDigest digest = null;
//     	
//     	try {
//     		digest = MessageDigest.getInstance("MD5");
//     	} catch (NoSuchAlgorithmException e) {
//     		// this should never happen
//     		throw new RuntimeException(e);
//     	}
//         
//         byte[] hash = digest.digest(input.getBytes());
//         
//         return DatatypeConverter.printHexBinary(hash);
//     }
// 	
// 	/**
// 	 * Hidden to prevent construction
// 	 */
// 	private MessageDigests() {
// 		// do nothing
// 	}
// }


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.stackify.api.ErrorItem;
import com.stackify.api.StackifyError;
import com.stackify.api.common.codec.MessageDigests;
			throw new NullPointerException("StackifyError is null");
		}

		ErrorItem errorItem = error.getError();

        if (errorItem != null) {
            while (errorItem.getInnerError() != null) {
                errorItem = errorItem.getInnerError();
            }
        }

        return errorItem;
    }
    
    /**
     * Generates a unique key based on the error. The key will be an MD5 hash of the type, type code, and method.
     * @param errorItem The error item
     * @return The unique key for the error
     */
    public static String getUniqueKey(final ErrorItem errorItem) {
		if (errorItem == null) {
			throw new NullPointerException("ErrorItem is null");
		}
		
		String type = errorItem.getErrorType();
    	String typeCode = errorItem.getErrorTypeCode();
    	String method = errorItem.getSourceMethod();

    	String uniqueKey = String.format("%s-%s-%s", type, typeCode, method);
    	
// Path: src/main/java/com/stackify/api/ErrorItem.java
// @AllArgsConstructor
// @NoArgsConstructor
// @Builder(builderClassName = "Builder", builderMethodName = "newBuilder", toBuilder = true)
// @Data
// @JsonInclude(JsonInclude.Include.NON_NULL)
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class ErrorItem {
// 
//     /**
//      * The error message
//      */
//     @Setter
//     @JsonProperty("Message")
//     private String message;
// 
//     /**
//      * The error's class name
//      */
//     @JsonProperty("ErrorType")
//     private String errorType;
// 
//     /**
//      * The error type code
//      */
//     @JsonProperty("ErrorTypeCode")
//     private String errorTypeCode;
// 
//     /**
//      * Custom data for the error
//      */
//     @JsonProperty("Data")
//     private Map<String, String> data;
// 
//     /**
//      * The method name
//      */
//     @JsonProperty("SourceMethod")
//     private String sourceMethod;
// 
//     /**
//      * The stack trace
//      */
//     @JsonProperty("StackTrace")
//     private List<TraceFrame> stackTrace;
// 
//     /**
//      * The cause of this error
//      */
//     @JsonProperty("InnerError")
//     private ErrorItem innerError;
// 
// }
// 
// Path: src/main/java/com/stackify/api/StackifyError.java
// @AllArgsConstructor
// @NoArgsConstructor
// @Builder(builderClassName = "Builder", builderMethodName = "newBuilder", toBuilder = true)
// @Data
// @JsonInclude(JsonInclude.Include.NON_NULL)
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class StackifyError {
// 
//     /**
//      * Environment
//      */
//     @JsonProperty("EnvironmentDetail")
//     private EnvironmentDetail environmentDetail;
// 
//     /**
//      * Date/time of the error
//      */
//     @JsonProperty("OccurredEpochMillis")
//     private Long occurredEpochMillis;
// 
//     /**
//      * Error details
//      */
//     @JsonProperty("Error")
//     private ErrorItem error;
// 
//     /**
//      * Details of the web request
//      */
//     @JsonProperty("WebRequestDetail")
//     private WebRequestDetail webRequestDetail;
// 
//     /**
//      * Server variables
//      */
//     @JsonProperty("ServerVariables")
//     private Map<String, String> serverVariables;
// 
//     /**
//      * Customer name
//      */
//     @JsonProperty("CustomerName")
//     private String customerName;
// 
//     /**
//      * User name
//      */
//     @JsonProperty("UserName")
//     private String userName;
// 
// }
// 
// Path: src/main/java/com/stackify/api/common/codec/MessageDigests.java
// public class MessageDigests {
// 
//     /**
//      * Generates an MD5 hash hex string for the input string
//      * @param input The input string
//      * @return MD5 hash hex string
//      */
//     public static String md5Hex(final String input) {
// 		if (input == null) {
// 			throw new NullPointerException("String is null");
// 		}
// 
//     	MessageDigest digest = null;
//     	
//     	try {
//     		digest = MessageDigest.getInstance("MD5");
//     	} catch (NoSuchAlgorithmException e) {
//     		// this should never happen
//     		throw new RuntimeException(e);
//     	}
//         
//         byte[] hash = digest.digest(input.getBytes());
//         
//         return DatatypeConverter.printHexBinary(hash);
//     }
// 	
// 	/**
// 	 * Hidden to prevent construction
// 	 */
// 	private MessageDigests() {
// 		// do nothing
// 	}
// }


// Path: src/main/java/com/stackify/api/common/error/ErrorCounter.java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.stackify.api.ErrorItem;
import com.stackify.api.StackifyError;
import com.stackify.api.common.codec.MessageDigests;

			throw new NullPointerException("StackifyError is null");
		}

		ErrorItem errorItem = error.getError();

        if (errorItem != null) {
            while (errorItem.getInnerError() != null) {
                errorItem = errorItem.getInnerError();
            }
        }

        return errorItem;
    }
    
    /**
     * Generates a unique key based on the error. The key will be an MD5 hash of the type, type code, and method.
     * @param errorItem The error item
     * @return The unique key for the error
     */
    public static String getUniqueKey(final ErrorItem errorItem) {
		if (errorItem == null) {
			throw new NullPointerException("ErrorItem is null");
		}
		
		String type = errorItem.getErrorType();
    	String typeCode = errorItem.getErrorTypeCode();
    	String method = errorItem.getSourceMethod();

    	String uniqueKey = String.format("%s-%s-%s", type, typeCode, method);
    	
    	return MessageDigests.md5Hex(uniqueKey);