protected void processDocument(
      String jsonDocument,
      PrintWriter writer,
      List<Class<? extends AbstractBpmnFactory>> factoryClasses)
      throws JSONException, BpmnConverterException {
    Diagram diagram = DiagramBuilder.parseJson(jsonDocument);

    // TODO: validate edges that are not in the java object model
    //		ArrayList<Shape> edges =
    this.getEdgesFromDiagram(diagram.getChildShapes());

    String type = diagram.getStencilset().getNamespace();
    SyntaxChecker checker = null;

    if (type != null
        && (type.equals("http://b3mn.org/stencilset/bpmn2.0#")
            || type.equals("http://b3mn.org/stencilset/bpmn2.0choreography#")
            || type.equals("http://b3mn.org/stencilset/bpmn2.0conversation#"))) {
      checker = getCheckerBPMN2(diagram, factoryClasses);
    }

    if (checker == null) {
      writer.print("{}");
    } else {
      checker.checkSyntax();
      writer.print(checker.getErrorsAsJson().toString());
    }
  }
  private void expandSubProcesses(Diagram diagram) {
    List<Shape> shapes = diagram.getShapes();
    for (Shape shape : shapes) {
      if (STENCIL_COLLAPSED_SUBPROCESS.equals(shape.getStencilId())
          && !"true".equals(shape.getProperty(PROPERTY_IS_CALL_ACTIVITY))) {
        String subProcessUrl = shape.getProperty(PROPERTY_ENTRY);
        if (subProcessUrl != null && subProcessUrl.length() > 0) {
          String subProcessName = shape.getProperty(PROPERTY_NAME);
          try {
            String subProcessId = getModelIdFromSignavioUrl(subProcessUrl);

            //            RepositoryArtifact artifact =
            // connector.getRepositoryArtifact(subProcessId);
            String subProcessJson = connector.getContent(subProcessId).asString();

            Diagram subProcess = DiagramBuilder.parseJson(subProcessJson);

            // FIXME subProcess = new ExtractProcessOfParticipant("Process
            // Engine").transform(subProcess);

            expandSubProcesses(subProcess);

            shape.setStencil(new StencilType(STENCIL_SUBPROCESS));
            ArrayList<Shape> childShapes = shape.getChildShapes();
            childShapes.addAll(subProcess.getChildShapes());
          } catch (Exception e) {
            throw new JsonTransformationException(
                "Error while retrieving Sub-Process"
                    + " '"
                    + subProcessName
                    + "'"
                    + " (URL: "
                    + subProcessUrl
                    + ").",
                e);
          }
        }
      }
    }
  }