private void checkBackTrace(
      ArtifactReadable subsystemRequirement,
      String current,
      IRelationTypeSide relType,
      IAttributeType attrType)
      throws IOException {
    /**
     * when the parent criticality is lower than the child, we check to see if the child traces to
     * any parent with /* the higher criticality (thus justifying the criticality of the child)
     */
    List<ArtifactReadable> tracedToRequirements =
        Lists.newArrayList(subsystemRequirement.getRelated(relType));
    String maxCriticality = "E";
    String parentCriticality = "E";

    for (ArtifactReadable parent : tracedToRequirements) {
      parentCriticality = parent.getSoleAttributeAsString(attrType, "V");
      if (attrType.equals(CoreAttributeTypes.SafetyCriticality)) {
        parentCriticality = convertSafetyCriticalityToDAL(parentCriticality);
      }

      maxCriticality = maxCriticality(maxCriticality, parentCriticality);
    }
    if (current.compareTo(maxCriticality) != 0) {
      writer.writeCell(String.format("%s [Error:<%s]", current, maxCriticality));
    } else {
      writer.writeCell(current);
    }
  }
  private void processSubsystemFunction(ArtifactReadable subsystemFunction) throws IOException {
    writer.writeCell(subsystemFunction.getName(), SafetyReportGenerator.SUBSYSTEM_FUNCTION_INDEX);
    String criticality =
        subsystemFunction.getSoleAttributeAsString(CoreAttributeTypes.SafetyCriticality, "V");
    writer.writeCell(criticality);

    for (ArtifactReadable subsystemRequirement : subsystemRequirements.get(subsystemFunction)) {
      processSubsystemRequirement(subsystemRequirement, convertSafetyCriticalityToDAL(criticality));
    }
    writer.endRow();
  }
  private void processSoftwareRequirement(ArtifactReadable softwareRequirement, String criticality)
      throws IOException {
    writer.writeCell(
        softwareRequirement.getName(), SafetyReportGenerator.SOFTWARE_REQUIREMENT_INDEX);
    String softwareRequirementDAL =
        writeCriticalityWithDesignCheck(
            softwareRequirement,
            criticality,
            CoreRelationTypes.Requirement_Trace__Higher_Level,
            CoreAttributeTypes.DevelopmentAssuranceLevel);

    writer.writeCell(
        calculateBoeingEquivalentSWQualLevel(
            softwareRequirementDAL,
            softwareRequirement.getAttributeCount(CoreAttributeTypes.Partition)));
    writer.writeCell(functionalCategory);

    writer.writeCell(
        Collections.toString(
            ",", getAttributesToStringList(softwareRequirement, CoreAttributeTypes.Partition)));

    writer.writeCell(
        safetyReport.getComponentUtil().getQualifiedComponentNames(softwareRequirement));
    Collection<String> codeUnits =
        safetyReport.getRequirementToCodeUnitsValues(softwareRequirement);

    if (Conditions.hasValues(codeUnits)) {
      for (String codeUnit : codeUnits) {
        writer.writeCell(codeUnit, SafetyReportGenerator.CODE_UNIT_INDEX);
        writer.endRow();
      }
    } else {
      writer.endRow();
    }
  }
  private void processSubsystemRequirement(
      ArtifactReadable subsystemRequirement, String criticality) throws IOException {
    writer.writeCell(
        subsystemRequirement.getSoleAttributeAsString(CoreAttributeTypes.Subsystem, ""),
        SafetyReportGenerator.SUBSYSTEM_INDEX);
    writer.writeCell(
        subsystemRequirement.getSoleAttributeAsString(CoreAttributeTypes.ParagraphNumber, ""));
    writer.writeCell(subsystemRequirement.getName());

    String currentCriticality =
        writeCriticalityWithDesignCheck(
            subsystemRequirement,
            criticality,
            CoreRelationTypes.Design__Design,
            CoreAttributeTypes.SafetyCriticality);

    for (ArtifactReadable softwareRequirement : softwareRequirements.get(subsystemRequirement)) {
      processSoftwareRequirement(softwareRequirement, currentCriticality);
    }
    writer.endRow();
  }
  private String writeCriticalityWithDesignCheck(
      ArtifactReadable art, String criticality, IRelationTypeSide relType, IAttributeType attrType)
      throws IOException {
    String current = art.getSoleAttributeAsString(CoreAttributeTypes.DevelopmentAssuranceLevel, "");
    /**
     * check to see if the safety criticality of the child at least equal to the parent /* since the
     * test below tests according to lexical order, > 0 result means parent has lower criticality
     */
    int comp = criticality.compareTo(current);

    if (comp < 0) {
      writer.writeCell(String.format("%s [Error:<%s]", current, criticality));
    } else {
      checkBackTrace(art, current, relType, attrType);
    }
    return current;
  }
 public void output() throws IOException {
   for (ArtifactReadable subsystemFunction : subsystemFunctions) {
     processSubsystemFunction(subsystemFunction);
     writer.endRow();
   }
 }