@Override
  public VulnerabilityDefectConsistencyState determineVulnerabilityDefectConsistencyState(
      Vulnerability vulnerability) {
    VulnerabilityDefectConsistencyState vulnerabilityDefectConsistencyState = null;

    Defect defect = vulnerability.getDefect();
    if (defect != null) {
      if (vulnerability.isActive() == defect.isOpen()) {
        vulnerabilityDefectConsistencyState = VulnerabilityDefectConsistencyState.CONSISTENT;
      } else if (defect.isOpen()) {
        vulnerabilityDefectConsistencyState =
            VulnerabilityDefectConsistencyState.VULN_CLOSED_DEFECT_OPEN_NEEDS_SCAN;
      } else {
        Calendar latestScanDate = null;
        for (Finding finding : vulnerability.getFindings()) {
          Calendar scanDate = finding.getScan().getImportTime();
          if ((latestScanDate == null) || scanDate.after(latestScanDate)) {
            latestScanDate = scanDate;
          }
          if (finding.getScanRepeatFindingMaps() != null) {
            for (ScanRepeatFindingMap scanRepeatFindingMap : finding.getScanRepeatFindingMaps()) {
              Scan scan = scanRepeatFindingMap.getScan();
              if (scan != null) {
                scanDate = scan.getImportTime();
                if ((latestScanDate == null) || scanDate.after(latestScanDate)) {
                  latestScanDate = scanDate;
                }
              }
            }
          }
        }
        Calendar defectStatusUpdatedDate = defect.getStatusUpdatedDate();
        if (defectStatusUpdatedDate == null) {
          defectStatusUpdatedDate = Calendar.getInstance();
          defectStatusUpdatedDate.setTime(defect.getModifiedDate());
        }
        if ((latestScanDate != null) && latestScanDate.after(defectStatusUpdatedDate)) {
          vulnerabilityDefectConsistencyState =
              VulnerabilityDefectConsistencyState.VULN_OPEN_DEFECT_CLOSED_STILL_IN_SCAN;
        } else {
          vulnerabilityDefectConsistencyState =
              VulnerabilityDefectConsistencyState.VULN_OPEN_DEFECT_CLOSED_NEEDS_SCAN;
        }
      }
    }

    vulnerability.setVulnerabilityDefectConsistencyState(vulnerabilityDefectConsistencyState);
    return vulnerabilityDefectConsistencyState;
  }
  /** Marshall the given parameter object, and output to a SdkJsonGenerator */
  public void marshall(Finding finding, StructuredJsonGenerator jsonGenerator) {

    if (finding == null) {
      throw new AmazonClientException("Invalid argument passed to marshall(...)");
    }

    try {
      jsonGenerator.writeStartObject();

      if (finding.getArn() != null) {
        jsonGenerator.writeFieldName("arn").writeValue(finding.getArn());
      }
      if (finding.getSchemaVersion() != null) {
        jsonGenerator.writeFieldName("schemaVersion").writeValue(finding.getSchemaVersion());
      }
      if (finding.getService() != null) {
        jsonGenerator.writeFieldName("service").writeValue(finding.getService());
      }
      if (finding.getServiceAttributes() != null) {
        jsonGenerator.writeFieldName("serviceAttributes");
        InspectorServiceAttributesJsonMarshaller.getInstance()
            .marshall(finding.getServiceAttributes(), jsonGenerator);
      }
      if (finding.getAssetType() != null) {
        jsonGenerator.writeFieldName("assetType").writeValue(finding.getAssetType());
      }
      if (finding.getAssetAttributes() != null) {
        jsonGenerator.writeFieldName("assetAttributes");
        AssetAttributesJsonMarshaller.getInstance()
            .marshall(finding.getAssetAttributes(), jsonGenerator);
      }
      if (finding.getId() != null) {
        jsonGenerator.writeFieldName("id").writeValue(finding.getId());
      }
      if (finding.getTitle() != null) {
        jsonGenerator.writeFieldName("title").writeValue(finding.getTitle());
      }
      if (finding.getDescription() != null) {
        jsonGenerator.writeFieldName("description").writeValue(finding.getDescription());
      }
      if (finding.getRecommendation() != null) {
        jsonGenerator.writeFieldName("recommendation").writeValue(finding.getRecommendation());
      }
      if (finding.getSeverity() != null) {
        jsonGenerator.writeFieldName("severity").writeValue(finding.getSeverity());
      }
      if (finding.getNumericSeverity() != null) {
        jsonGenerator.writeFieldName("numericSeverity").writeValue(finding.getNumericSeverity());
      }
      if (finding.getConfidence() != null) {
        jsonGenerator.writeFieldName("confidence").writeValue(finding.getConfidence());
      }
      if (finding.getIndicatorOfCompromise() != null) {
        jsonGenerator
            .writeFieldName("indicatorOfCompromise")
            .writeValue(finding.getIndicatorOfCompromise());
      }

      java.util.List<Attribute> attributesList = finding.getAttributes();
      if (attributesList != null) {
        jsonGenerator.writeFieldName("attributes");
        jsonGenerator.writeStartArray();
        for (Attribute attributesListValue : attributesList) {
          if (attributesListValue != null) {

            AttributeJsonMarshaller.getInstance().marshall(attributesListValue, jsonGenerator);
          }
        }
        jsonGenerator.writeEndArray();
      }

      java.util.List<Attribute> userAttributesList = finding.getUserAttributes();
      if (userAttributesList != null) {
        jsonGenerator.writeFieldName("userAttributes");
        jsonGenerator.writeStartArray();
        for (Attribute userAttributesListValue : userAttributesList) {
          if (userAttributesListValue != null) {

            AttributeJsonMarshaller.getInstance().marshall(userAttributesListValue, jsonGenerator);
          }
        }
        jsonGenerator.writeEndArray();
      }
      if (finding.getCreatedAt() != null) {
        jsonGenerator.writeFieldName("createdAt").writeValue(finding.getCreatedAt());
      }
      if (finding.getUpdatedAt() != null) {
        jsonGenerator.writeFieldName("updatedAt").writeValue(finding.getUpdatedAt());
      }

      jsonGenerator.writeEndObject();
    } catch (Throwable t) {
      throw new AmazonClientException("Unable to marshall request to JSON: " + t.getMessage(), t);
    }
  }
  public static Vulnerabilities.Vulnerability.Finding convertTFFindingToSSVLFinding(
      Finding tfFinding) {

    Vulnerabilities.Vulnerability.Finding ssvlFinding =
        factory.createVulnerabilitiesVulnerabilityFinding();

    ssvlFinding.setFindingDescription(tfFinding.getChannelVulnerability().getName());
    ssvlFinding.setLongDescription(tfFinding.getLongDescription());
    ssvlFinding.setNativeID(tfFinding.getNativeId());
    ssvlFinding.setAttackString(tfFinding.getAttackString());
    ssvlFinding.setScanner(tfFinding.getChannelNameOrNull());
    ssvlFinding.setSeverity(tfFinding.getChannelSeverity().getName());
    ssvlFinding.setIdentifiedTimestamp(getTimestamp(tfFinding.getScan().getImportTime()));
    if (!tfFinding.getIsStatic())
      ssvlFinding.setSurfaceLocation(
          convertTFSurfaceLocationToSSVL(tfFinding.getSurfaceLocation()));

    if (tfFinding.getDataFlowElements() != null)
      for (DataFlowElement tfDataFlow : tfFinding.getDataFlowElements()) {
        ssvlFinding.getDataFlowElement().add(convertTFDataFlowElementToSSVL(tfDataFlow));
      }

    ssvlFinding.setDependency(convertTFDependencyToSSVL(tfFinding.getDependency()));

    return ssvlFinding;
  }