@@ -0,0 +1,2669 @@
+package com.bugsnag;%0A%0Aimport java.util.List;%0Aimport java.util.HashMap;%0Aimport java.util.Map;%0A%0Aimport org.json.JSONObject;%0Aimport org.json.JSONArray;%0Aimport org.json.JSONException;%0A%0Apublic class MetaData extends HashMap%3CString, Object%3E %7B%0A    public void addToTab(String tabName, String key, Object value) %7B%0A        Object tab = get(tabName);%0A        if(tab == null %7C%7C !(tab instanceof Map)) %7B%0A            tab = new HashMap%3CString, Object%3E();%0A            put(tabName, tab);%0A        %7D%0A%0A        if(value != null) %7B%0A            ((Map)tab).put(key, value);%0A        %7D else %7B%0A            ((Map)tab).remove(key);%0A        %7D%0A    %7D%0A%0A    public void clearTab(String tabName)%7B%0A        remove(tabName);%0A    %7D%0A%0A    public JSONObject toJSON(String%5B%5D filters) %7B%0A        return mapToJSONObject(this, filters);%0A    %7D%0A%0A    private static boolean matchesFilter(String key, String%5B%5D filters) %7B%0A        if(filters == null %7C%7C key == null) %7B%0A            return false;%0A        %7D%0A%0A        for(String filter : filters) %7B%0A            if(key.contains(filter)) %7B%0A                return true;%0A            %7D%0A        %7D%0A        %0A        return false;%0A    %7D%0A%0A    private static JSONArray listToJSONArray(List%3CObject%3E source, String%5B%5D filters) %7B%0A        if(source == null) return null;%0A%0A        JSONArray returnValue = new JSONArray();%0A        for (Object value : source) %7B%0A            if(value instanceof Map) %7B%0A                returnValue.put(mapToJSONObject((Map%3CString,Object%3E)value, filters));%0A            %7D else if(value instanceof List) %7B%0A                returnValue.put(listToJSONArray((List%3CObject%3E)value, filters));%0A            %7D else %7B%0A                returnValue.put(value);%0A            %7D%0A        %7D%0A        return returnValue;%0A    %7D%0A%0A    private static  JSONObject mapToJSONObject(Map%3CString,Object%3E source, String%5B%5D filters) %7B%0A        if(source == null) return null;%0A%0A        JSONObject returnValue = new JSONObject();%0A        for (Map.Entry%3CString, Object%3E entry : source.entrySet()) %7B%0A            String key = entry.getKey();%0A            Object value = entry.getValue();%0A%0A            if(matchesFilter(key, filters)) %7B%0A                Util.addToJSONObject(returnValue, key, %22%5BFILTERED%5D%22);%0A            %7D else %7B%0A                if(value instanceof Map) %7B%0A                    Util.addToJSONObject(returnValue, key, mapToJSONObject((Map%3CString,Object%3E)value, filters));%0A                %7D else if(value instanceof List) %7B%0A                    Util.addToJSONObject(returnValue, key, listToJSONArray((List%3CObject%3E)value, filters));%0A                %7D else %7B%0A                    Util.addToJSONObject(returnValue, key, value);%0A                %7D%0A            %7D%0A        %7D%0A        return returnValue;%0A    %7D%0A%7D

Move to metadata object