/**
   * Creates the loop characteristics for multiple instances loops.
   *
   * @param shape
   * @param loopType
   */
  private MultiInstanceLoopCharacteristics createMultiInstanceLoopCharacteristics(
      GenericShape shape, String loopType) {
    MultiInstanceLoopCharacteristics miLoop = new MultiInstanceLoopCharacteristics();

    /* Determine whether it is parallel or sequential */
    if (loopType.equalsIgnoreCase("Parallel")) miLoop.setIsSequential(false);
    else miLoop.setIsSequential(true);

    /* Set loop cardinality */
    String loopCardinalityString = shape.getProperty("loopcardinality");
    if (loopCardinalityString != null && !(loopCardinalityString.length() == 0)) {
      FormalExpression loopCardinality = new FormalExpression(loopCardinalityString);
      miLoop.setLoopCardinality(loopCardinality);
    }

    /* Reference required DataInput */
    // miLoop.setLoopDataInput(value)
    // Task t = null;
    // t.get

    /* Completion condition */
    String completionCondition = shape.getProperty("completioncondition");
    if (completionCondition != null && !(completionCondition.length() == 0)) {
      FormalExpression completionConditionExpr = new FormalExpression(completionCondition);
      miLoop.setCompletionCondition(completionConditionExpr);
    }

    /* Handle loop behavior */
    handleLoopBehaviorAttributes(shape, miLoop);

    return miLoop;
  }
  /**
   * Processes the attributes that are related to the loop behavior.
   *
   * @param shape
   * @param miLoop
   */
  private void handleLoopBehaviorAttributes(
      GenericShape shape, MultiInstanceLoopCharacteristics miLoop) {
    String behavior = shape.getProperty("behavior");
    if (behavior != null && !(behavior.length() == 0)) {
      miLoop.setBehavior(MultiInstanceFlowCondition.fromValue(behavior));
    }

    /* Complex behavior */
    if (miLoop.getBehavior().equals(MultiInstanceFlowCondition.COMPLEX)) {
      try {
        String comBehavDefString = shape.getProperty("complexbehaviordefinition");
        JSONObject complexDef = new JSONObject(comBehavDefString);
        JSONArray complexDefItems = complexDef.getJSONArray("items");

        /*
         * Retrieve complex behavior definitions and process
         * them.
         */
        for (int i = 0; i < complexDefItems.length(); i++) {
          JSONObject complexDefItem = complexDefItems.getJSONObject(i);

          ComplexBehaviorDefinition comBehavDef = new ComplexBehaviorDefinition();

          /* Condition */
          String condition = complexDefItem.getString("cexpression");
          if (condition != null && !(condition.length() == 0))
            comBehavDef.setCondition(new FormalExpression(condition));

          /* Event */
          ImplicitThrowEvent event =
              new ImplicitThrowEvent(complexDefItem.getString("ceventdefinition"));
          comBehavDef.setEvent(event);

          miLoop.getComplexBehaviorDefinition().add(comBehavDef);
        }

      } catch (Exception e) {
        e.printStackTrace();
      }

      /* Handle none behavior choice */
    } else if (miLoop.getBehavior().equals(MultiInstanceFlowCondition.NONE)) {
      String noneBehavString = shape.getProperty("nonebehavioreventref");
      if (noneBehavString != null && !(noneBehavString.length() == 0)) {
        miLoop.setNoneBehaviorEventRef(EventDefinition.createEventDefinition(noneBehavString));
      }
      /* Handle one behavior choice */
    } else if (miLoop.getBehavior().equals(MultiInstanceFlowCondition.ONE)) {
      String oneBehavString = shape.getProperty("onebehavioreventref");
      if (oneBehavString != null && !(oneBehavString.length() == 0)) {
        miLoop.setOneBehaviorEventRef(EventDefinition.createEventDefinition(oneBehavString));
      }
    }
  }