private void buildToJsonForOption(
      PropertyWrapper pWrap, OJAnnotatedClass annotatedClass, OJBlock block) {

    SortedSet<Classifier> concreteImplementations =
        new TreeSet<Classifier>(
            new Comparator<Classifier>() {
              @Override
              public int compare(Classifier o1, Classifier o2) {
                return o1.getName().compareTo(o2.getName());
              }
            });

    // For derived unions only show tabs for each property that makes up the union.
    if (pWrap.isDerivedUnion()) {
      List<Property> subsettingProperties =
          ModelLoader.INSTANCE.findSubsettingProperties(pWrap.getProperty());
      for (Property subsettingProperty : subsettingProperties) {
        concreteImplementations.addAll(
            UmlgClassOperations.getConcreteImplementations(
                (Classifier) subsettingProperty.getType()));
      }
    } else {
      // For non derived union show all concrete implementations
      concreteImplementations =
          UmlgClassOperations.getConcreteImplementations((Classifier) pWrap.getType());
    }

    Set<Classifier> concreteImplementationsFrom =
        UmlgClassOperations.getConcreteImplementations((Classifier) pWrap.getOwningType());
    if (!concreteImplementationsFrom.isEmpty()) {
      annotatedClass.addToImports(UmlgGenerationUtil.ToJsonUtil);
      // blok get reassigned for the meta data if statement
      OJBlock returnBlock = block;
      block.addToStatements("StringBuilder json = new StringBuilder()");
      block.addToStatements("json.append(\"[\")");

      int count = 1;
      // For meta data, put where one is navigating to first, then where on is
      // navigating from
      // This is consistent with navigating to a entity with a vertex where
      // there is no navigating from.
      // i.e. the first meta data in the array is the entity navigating to.
      for (Classifier concreteClassifierTo : concreteImplementations) {
        annotatedClass.addToImports(UmlgClassOperations.getPathName(concreteClassifierTo));

        for (Classifier concreteClassifierFrom : concreteImplementationsFrom) {

          block.addToStatements("json.append(\"{\")");

          block.addToStatements("json.append(\" \\\"meta\\\" : {\")");
          block.addToStatements(
              "json.append(\"\\\"qualifiedName\\\": \\\"" + pWrap.getQualifiedName() + "\\\"\")");

          // The execute ocl query resource is only required if the below
          // visitor is available
          if (RestletVisitors.containsVisitorForClass(QueryExecuteResourceBuilder.class)
              && (pWrap
                      .getType()
                      .getQualifiedName()
                      .equals(UmlgRestletGenerationUtil.instanceQueryQualifiedName)
                  || pWrap
                      .getType()
                      .getQualifiedName()
                      .equals(UmlgRestletGenerationUtil.classQueryQualifiedName))) {
            block.addToStatements(
                "json.append(\", \\\"oclExecuteUri\\\": \\\"/"
                    + pWrap.getModel().getName()
                    + "/{contextId}/oclExecuteQuery\\\"\")");
          }
          block.addToStatements("json.append(\", \\\"to\\\": \")");
          OJBlock conditionBlockFrom = new OJBlock();
          annotatedClass.addToImports(UmlgClassOperations.getPathName(concreteClassifierFrom));

          conditionBlockFrom.addToStatements(
              "json.append("
                  + UmlgClassOperations.propertyEnumName(concreteClassifierTo)
                  + ".asJson())");
          conditionBlockFrom.addToStatements("json.append(\", \\\"from\\\": \")");
          conditionBlockFrom.addToStatements(
              "json.append("
                  + UmlgClassOperations.propertyEnumName(concreteClassifierFrom)
                  + ".asJson())");
          annotatedClass.addToImports(
              UmlgClassOperations.getPathName(concreteClassifierFrom)
                  .append(UmlgClassOperations.propertyEnumName(concreteClassifierFrom)));

          block.addToStatements(conditionBlockFrom);

          annotatedClass.addToImports(
              UmlgClassOperations.getPathName(pWrap.getOwningType())
                  .append(UmlgClassOperations.propertyEnumName(pWrap.getOwningType())));
          annotatedClass.addToImports(
              UmlgClassOperations.getPathName(concreteClassifierTo)
                  .append(UmlgClassOperations.propertyEnumName(concreteClassifierTo)));

          if (count++ < (concreteImplementations.size() * concreteImplementationsFrom.size())) {
            block.addToStatements("json.append(\"}},\")");
          } else {
            block.addToStatements("json.append(\"}}\")");
          }
        }
        block = returnBlock;
      }
      returnBlock.addToStatements("json.append(\"]\")");
      returnBlock.addToStatements(
          "return new "
              + UmlgRestletGenerationUtil.JsonRepresentation.getLast()
              + "(json.toString())");
    } else {
      // TODO not thought through
      block.addToStatements("return null");
    }
  }