private void buildTypeDefinition(IMetaObject meta) {
    if (typeMap.containsKey(meta.getName())) return;

    typeMap.put(meta.getName(), "type" + typeCounter);
    JSONObject def = new JSONObject();
    definitions.put("type" + typeCounter, def);
    typeCounter += 1;

    def.put("type", "object");
    JSONObject properties = new JSONObject();
    def.put("properties", properties);

    for (IMetaPrimitive prim : meta.getMetaPrimitives()) {
      JSONObject type = primitiveToJSONType(prim.getType());
      if (type != null) properties.put(prim.getName(), type);
    }

    for (IMetaAssociation assoc : meta.getMetaAssociationsParent()) {
      JSONObject type = associationToJSONType(assoc);
      if (type != null) properties.put(assoc.getName().split("\\.")[1], type);
    }
  }
  private JSONObject associationToJSONType(IMetaAssociation assoc) {
    IMetaObject child = assoc.getChild();

    JSONObject type = null;

    // some kind of foreign key
    if (child.isPersistable()) {
      // only if there is a service available for that type;
      if (RestServices.getServiceForEntity(child.getName()) != null) {
        type =
            new JSONObject()
                .put("type", "string")
                .put("title", String.format("Reference to a(n) '%s'", child.getName()));
      }
    }

    // persistent object, describe this object in the service as well
    else {
      buildTypeDefinition(child); // make sure the type is available in the schema
      String targetType = typeMap.get(child.getName());
      type = new JSONObject().put("$ref", "#/definitions/" + targetType);
      if ("type1".equals(targetType)) hasReferenceToRoot = true;
    }

    // assoc should be included?
    if (type == null) return null;

    // make sure referencesets require arrays
    if (assoc.getType() == AssociationType.REFERENCESET)
      type = new JSONObject().put("type", "array").put("items", type);

    // make sure null refs are supported
    else /* not a refset */ type = orNull(type);

    return type;
  }