public static Map<String, Object> defaultSerialize(Object o) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("T", "L");
        
        Map<String, Object> classesData = new HashMap<String, Object>();
        data.put("data", classesData);
        
        Class<?> clazz = o.getClass();
        data.put("class", clazz.getName());
        
        // write all @Serialize'd fields
        do {
            Map<String, Object> classData = new HashMap<String, Object>();
            classesData.put(clazz.getName(), classData);
            for (Field f : clazz.getDeclaredFields()) {
                f.setAccessible(true);
                if (f.isAnnotationPresent(Serialize.class)) {
                    try {
                        classData.put(f.getName(), serialize(f.get(o)));
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
            }
        } while ((clazz = clazz.getSuperclass()) != Object.class);
        
        return data;
    }