Risk.java

package gov.nist.secauto.oscal.lib.model;

import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
import gov.nist.secauto.metaschema.binding.model.annotations.Matches;
import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.DateTimeWithTZAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.IntegerAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
import java.lang.Override;
import java.lang.String;
import java.time.ZonedDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

/**
 * An identified risk.
 */
@MetaschemaAssembly(
    formalName = "Identified Risk",
    description = "An identified risk.",
    name = "risk",
    metaschema = OscalAssessmentCommonMetaschema.class
)
@ValueConstraints(
    allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "false-positive", description = "The risk has been confirmed to be a false positive."), @AllowedValue(value = "accepted", description = "The risk has been accepted. No further action will be taken."), @AllowedValue(value = "risk-adjusted", description = "The risk has been adjusted."), @AllowedValue(value = "priority", description = "A numeric value indicating the sequence in which risks should be addressed. (Lower numbers are higher priority)")}),
    matches = @Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='priority']/@value", typeAdapter = IntegerAdapter.class)
)
public class Risk {
  @BoundFlag(
      formalName = "Risk Universally Unique Identifier",
      description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this risk elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#scope). The locally defined *UUID* of the `risk` can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
      useName = "uuid",
      required = true,
      typeAdapter = UuidAdapter.class
  )
  private UUID _uuid;

  /**
   * "The title for this risk."
   */
  @BoundField(
      formalName = "Risk Title",
      description = "The title for this risk.",
      useName = "title",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = MarkupLineAdapter.class
  )
  private MarkupLine _title;

  /**
   * "A human-readable summary of the identified risk, to include a statement of how the risk impacts the system."
   */
  @BoundField(
      formalName = "Risk Description",
      description = "A human-readable summary of the identified risk, to include a statement of how the risk impacts the system.",
      useName = "description",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = MarkupMultilineAdapter.class
  )
  private MarkupMultiline _description;

  /**
   * "An summary of impact for how the risk affects the system."
   */
  @BoundField(
      formalName = "Risk Statement",
      description = "An summary of impact for how the risk affects the system.",
      useName = "statement",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = MarkupMultilineAdapter.class
  )
  private MarkupMultiline _statement;

  @BoundAssembly(
      formalName = "Property",
      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
      useName = "prop",
      maxOccurs = -1
  )
  @GroupAs(
      name = "props",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Property> _props;

  @BoundAssembly(
      formalName = "Link",
      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
      useName = "link",
      maxOccurs = -1
  )
  @GroupAs(
      name = "links",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Link> _links;

  @BoundField(
      formalName = "Risk Status",
      description = "Describes the status of the associated risk.",
      useName = "status",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = TokenAdapter.class
  )
  @ValueConstraints(
      allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = {@AllowedValue(value = "open", description = "The risk has been identified."), @AllowedValue(value = "investigating", description = "The identified risk is being investigated. (Open risk)"), @AllowedValue(value = "remediating", description = "Remediation activities are underway, but are not yet complete. (Open risk)"), @AllowedValue(value = "deviation-requested", description = "A risk deviation, such as false positive, risk reduction, or operational requirement has been submitted for approval. (Open risk)"), @AllowedValue(value = "deviation-approved", description = "A risk deviation, such as false positive, risk reduction, or operational requirement has been approved. (Open risk)"), @AllowedValue(value = "closed", description = "The risk has been resolved.")})
  )
  private String _status;

  @BoundAssembly(
      formalName = "Origin",
      description = "Identifies the source of the finding, such as a tool, interviewed person, or activity.",
      useName = "origin",
      maxOccurs = -1,
      remarks = "Used to identify the individual and/or tool that identified this risk."
  )
  @GroupAs(
      name = "origins",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Origin> _origins;

  @BoundField(
      formalName = "Threat ID",
      description = "A pointer, by ID, to an externally-defined threat.",
      useName = "threat-id",
      maxOccurs = -1
  )
  @GroupAs(
      name = "threat-ids",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<ThreatId> _threatIds;

  @BoundAssembly(
      formalName = "Characterization",
      description = "A collection of descriptive data about the containing object from a specific origin.",
      useName = "characterization",
      maxOccurs = -1
  )
  @GroupAs(
      name = "characterizations",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Characterization> _characterizations;

  /**
   * "Describes an existing mitigating factor that may affect the overall determination of the risk, with an optional link to an implementation statement in the SSP."
   */
  @BoundAssembly(
      formalName = "Mitigating Factor",
      description = "Describes an existing mitigating factor that may affect the overall determination of the risk, with an optional link to an implementation statement in the SSP.",
      useName = "mitigating-factor",
      maxOccurs = -1
  )
  @GroupAs(
      name = "mitigating-factors",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<MitigatingFactor> _mitigatingFactors;

  /**
   * "The date/time by which the risk must be resolved."
   */
  @BoundField(
      formalName = "Risk Resolution Deadline",
      description = "The date/time by which the risk must be resolved.",
      useName = "deadline"
  )
  @BoundFieldValue(
      typeAdapter = DateTimeWithTZAdapter.class
  )
  private ZonedDateTime _deadline;

  @BoundAssembly(
      formalName = "Risk Response",
      description = "Describes either recommended or an actual plan for addressing the risk.",
      useName = "response",
      maxOccurs = -1
  )
  @GroupAs(
      name = "remediations",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Response> _remediations;

  /**
   * "A log of all risk-related tasks taken."
   */
  @BoundAssembly(
      formalName = "Risk Log",
      description = "A log of all risk-related tasks taken.",
      useName = "risk-log"
  )
  private RiskLog _riskLog;

  /**
   * "Relates the finding to a set of referenced observations that were used to determine the finding."
   */
  @BoundAssembly(
      formalName = "Related Observation",
      description = "Relates the finding to a set of referenced observations that were used to determine the finding.",
      useName = "related-observation",
      maxOccurs = -1
  )
  @GroupAs(
      name = "related-observations",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<RelatedObservation> _relatedObservations;

  public Risk() {
  }

  public UUID getUuid() {
    return _uuid;
  }

  public void setUuid(UUID value) {
    _uuid = value;
  }

  public MarkupLine getTitle() {
    return _title;
  }

  public void setTitle(MarkupLine value) {
    _title = value;
  }

  public MarkupMultiline getDescription() {
    return _description;
  }

  public void setDescription(MarkupMultiline value) {
    _description = value;
  }

  public MarkupMultiline getStatement() {
    return _statement;
  }

  public void setStatement(MarkupMultiline value) {
    _statement = value;
  }

  public List<Property> getProps() {
    return _props;
  }

  public void setProps(List<Property> value) {
    _props = value;
  }

  /**
   * Add a new {@link Property} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_props == null) {
      _props = new LinkedList<>();
    }
    return _props.add(value);
  }

  /**
   * Remove the first matching {@link Property} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _props == null ? false : _props.remove(value);
  }

  public List<Link> getLinks() {
    return _links;
  }

  public void setLinks(List<Link> value) {
    _links = value;
  }

  /**
   * Add a new {@link Link} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_links == null) {
      _links = new LinkedList<>();
    }
    return _links.add(value);
  }

  /**
   * Remove the first matching {@link Link} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _links == null ? false : _links.remove(value);
  }

  public String getStatus() {
    return _status;
  }

  public void setStatus(String value) {
    _status = value;
  }

  public List<Origin> getOrigins() {
    return _origins;
  }

  public void setOrigins(List<Origin> value) {
    _origins = value;
  }

  /**
   * Add a new {@link Origin} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addOrigin(Origin item) {
    Origin value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_origins == null) {
      _origins = new LinkedList<>();
    }
    return _origins.add(value);
  }

  /**
   * Remove the first matching {@link Origin} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeOrigin(Origin item) {
    Origin value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _origins == null ? false : _origins.remove(value);
  }

  public List<ThreatId> getThreatIds() {
    return _threatIds;
  }

  public void setThreatIds(List<ThreatId> value) {
    _threatIds = value;
  }

  /**
   * Add a new {@link ThreatId} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addThreatId(ThreatId item) {
    ThreatId value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_threatIds == null) {
      _threatIds = new LinkedList<>();
    }
    return _threatIds.add(value);
  }

  /**
   * Remove the first matching {@link ThreatId} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeThreatId(ThreatId item) {
    ThreatId value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _threatIds == null ? false : _threatIds.remove(value);
  }

  public List<Characterization> getCharacterizations() {
    return _characterizations;
  }

  public void setCharacterizations(List<Characterization> value) {
    _characterizations = value;
  }

  /**
   * Add a new {@link Characterization} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addCharacterization(Characterization item) {
    Characterization value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_characterizations == null) {
      _characterizations = new LinkedList<>();
    }
    return _characterizations.add(value);
  }

  /**
   * Remove the first matching {@link Characterization} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeCharacterization(Characterization item) {
    Characterization value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _characterizations == null ? false : _characterizations.remove(value);
  }

  public List<MitigatingFactor> getMitigatingFactors() {
    return _mitigatingFactors;
  }

  public void setMitigatingFactors(List<MitigatingFactor> value) {
    _mitigatingFactors = value;
  }

  /**
   * Add a new {@link MitigatingFactor} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addMitigatingFactor(MitigatingFactor item) {
    MitigatingFactor value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_mitigatingFactors == null) {
      _mitigatingFactors = new LinkedList<>();
    }
    return _mitigatingFactors.add(value);
  }

  /**
   * Remove the first matching {@link MitigatingFactor} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeMitigatingFactor(MitigatingFactor item) {
    MitigatingFactor value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _mitigatingFactors == null ? false : _mitigatingFactors.remove(value);
  }

  public ZonedDateTime getDeadline() {
    return _deadline;
  }

  public void setDeadline(ZonedDateTime value) {
    _deadline = value;
  }

  public List<Response> getRemediations() {
    return _remediations;
  }

  public void setRemediations(List<Response> value) {
    _remediations = value;
  }

  /**
   * Add a new {@link Response} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addResponse(Response item) {
    Response value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_remediations == null) {
      _remediations = new LinkedList<>();
    }
    return _remediations.add(value);
  }

  /**
   * Remove the first matching {@link Response} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeResponse(Response item) {
    Response value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _remediations == null ? false : _remediations.remove(value);
  }

  public RiskLog getRiskLog() {
    return _riskLog;
  }

  public void setRiskLog(RiskLog value) {
    _riskLog = value;
  }

  public List<RelatedObservation> getRelatedObservations() {
    return _relatedObservations;
  }

  public void setRelatedObservations(List<RelatedObservation> value) {
    _relatedObservations = value;
  }

  /**
   * Add a new {@link RelatedObservation} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addRelatedObservation(RelatedObservation item) {
    RelatedObservation value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_relatedObservations == null) {
      _relatedObservations = new LinkedList<>();
    }
    return _relatedObservations.add(value);
  }

  /**
   * Remove the first matching {@link RelatedObservation} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeRelatedObservation(RelatedObservation item) {
    RelatedObservation value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _relatedObservations == null ? false : _relatedObservations.remove(value);
  }

  @Override
  public String toString() {
    return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
  }

  /**
   * Relates the finding to a set of referenced observations that were used to determine the finding.
   */
  @MetaschemaAssembly(
      formalName = "Related Observation",
      description = "Relates the finding to a set of referenced observations that were used to determine the finding.",
      name = "related-observation",
      metaschema = OscalAssessmentCommonMetaschema.class
  )
  public static class RelatedObservation {
    @BoundFlag(
        formalName = "Observation Universally Unique Identifier Reference",
        description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier reference to an observation defined in the list of observations.",
        useName = "observation-uuid",
        required = true,
        typeAdapter = UuidAdapter.class
    )
    private UUID _observationUuid;

    public RelatedObservation() {
    }

    public UUID getObservationUuid() {
      return _observationUuid;
    }

    public void setObservationUuid(UUID value) {
      _observationUuid = value;
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }
  }

  /**
   * A log of all risk-related tasks taken.
   */
  @MetaschemaAssembly(
      formalName = "Risk Log",
      description = "A log of all risk-related tasks taken.",
      name = "risk-log",
      metaschema = OscalAssessmentCommonMetaschema.class
  )
  public static class RiskLog {
    /**
     * "Identifies an individual risk response that occurred as part of managing an identified risk."
     */
    @BoundAssembly(
        formalName = "Risk Log Entry",
        description = "Identifies an individual risk response that occurred as part of managing an identified risk.",
        useName = "entry",
        minOccurs = 1,
        maxOccurs = -1
    )
    @GroupAs(
        name = "entries",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Entry> _entries;

    public RiskLog() {
    }

    public List<Entry> getEntries() {
      return _entries;
    }

    public void setEntries(List<Entry> value) {
      _entries = value;
    }

    /**
     * Add a new {@link Entry} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addEntry(Entry item) {
      Entry value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_entries == null) {
        _entries = new LinkedList<>();
      }
      return _entries.add(value);
    }

    /**
     * Remove the first matching {@link Entry} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeEntry(Entry item) {
      Entry value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _entries == null ? false : _entries.remove(value);
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }

    /**
     * Identifies an individual risk response that occurred as part of managing an identified risk.
     */
    @MetaschemaAssembly(
        formalName = "Risk Log Entry",
        description = "Identifies an individual risk response that occurred as part of managing an identified risk.",
        name = "entry",
        metaschema = OscalAssessmentCommonMetaschema.class
    )
    @ValueConstraints(
        allowedValues = {
            @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "type", description = "The type of remediation tracking entry. Can be multi-valued.")),
            @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='type']/@value", allowOthers = true, values = {@AllowedValue(value = "vendor-check-in", description = "Contacted vendor to determine the status of a pending fix to a known vulnerability."), @AllowedValue(value = "status-update", description = "Information related to the current state of response to this risk."), @AllowedValue(value = "milestone-complete", description = "A significant step in the response plan has been achieved."), @AllowedValue(value = "mitigation", description = "An activity was completed that reduces the likelihood or impact of this risk."), @AllowedValue(value = "remediated", description = "An activity was completed that eliminates the likelihood or impact of this risk."), @AllowedValue(value = "closed", description = "The risk is no longer applicable to the system."), @AllowedValue(value = "dr-submission", description = "A deviation request was made to the authorizing official."), @AllowedValue(value = "dr-updated", description = "A previously submitted deviation request has been modified."), @AllowedValue(value = "dr-approved", description = "The authorizing official approved the deviation."), @AllowedValue(value = "dr-rejected", description = "The authorizing official rejected the deviation.")})
        }
    )
    public static class Entry {
      @BoundFlag(
          formalName = "Risk Log Entry Universally Unique Identifier",
          description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this risk log entry elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#scope). The locally defined *UUID* of the `risk log entry` can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
          useName = "uuid",
          required = true,
          typeAdapter = UuidAdapter.class
      )
      private UUID _uuid;

      /**
       * "The title for this risk log entry."
       */
      @BoundField(
          formalName = "Title",
          description = "The title for this risk log entry.",
          useName = "title"
      )
      @BoundFieldValue(
          typeAdapter = MarkupLineAdapter.class
      )
      private MarkupLine _title;

      /**
       * "A human-readable description of what was done regarding the risk."
       */
      @BoundField(
          formalName = "Risk Task Description",
          description = "A human-readable description of what was done regarding the risk.",
          useName = "description"
      )
      @BoundFieldValue(
          typeAdapter = MarkupMultilineAdapter.class
      )
      private MarkupMultiline _description;

      /**
       * "Identifies the start date and time of the event."
       */
      @BoundField(
          formalName = "Start",
          description = "Identifies the start date and time of the event.",
          useName = "start",
          minOccurs = 1
      )
      @BoundFieldValue(
          typeAdapter = DateTimeWithTZAdapter.class
      )
      private ZonedDateTime _start;

      /**
       * "Identifies the end date and time of the event. If the event is a point in time, the start and end will be the same date and time."
       */
      @BoundField(
          formalName = "End",
          description = "Identifies the end date and time of the event. If the event is a point in time, the start and end will be the same date and time.",
          useName = "end"
      )
      @BoundFieldValue(
          typeAdapter = DateTimeWithTZAdapter.class
      )
      private ZonedDateTime _end;

      @BoundAssembly(
          formalName = "Property",
          description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
          useName = "prop",
          maxOccurs = -1
      )
      @GroupAs(
          name = "props",
          inJson = JsonGroupAsBehavior.LIST
      )
      private List<Property> _props;

      @BoundAssembly(
          formalName = "Link",
          description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
          useName = "link",
          maxOccurs = -1
      )
      @GroupAs(
          name = "links",
          inJson = JsonGroupAsBehavior.LIST
      )
      private List<Link> _links;

      @BoundAssembly(
          formalName = "Logged By",
          description = "Used to indicate who created a log entry in what role.",
          useName = "logged-by",
          maxOccurs = -1
      )
      @GroupAs(
          name = "logged-by",
          inJson = JsonGroupAsBehavior.LIST
      )
      private List<LoggedBy> _loggedBy;

      @BoundField(
          formalName = "Risk Status",
          description = "Describes the status of the associated risk.",
          useName = "status-change",
          remarks = "Identifies a change in risk status made resulting from the task described by this risk log entry. This allows the risk's status history to be captured as a sequence of risk log entries."
      )
      @BoundFieldValue(
          typeAdapter = TokenAdapter.class
      )
      @ValueConstraints(
          allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = {@AllowedValue(value = "open", description = "The risk has been identified."), @AllowedValue(value = "investigating", description = "The identified risk is being investigated. (Open risk)"), @AllowedValue(value = "remediating", description = "Remediation activities are underway, but are not yet complete. (Open risk)"), @AllowedValue(value = "deviation-requested", description = "A risk deviation, such as false positive, risk reduction, or operational requirement has been submitted for approval. (Open risk)"), @AllowedValue(value = "deviation-approved", description = "A risk deviation, such as false positive, risk reduction, or operational requirement has been approved. (Open risk)"), @AllowedValue(value = "closed", description = "The risk has been resolved.")})
      )
      private String _statusChange;

      /**
       * "Identifies an individual risk response that this log entry is for."
       */
      @BoundAssembly(
          formalName = "Risk Response Reference",
          description = "Identifies an individual risk response that this log entry is for.",
          useName = "related-response",
          maxOccurs = -1
      )
      @GroupAs(
          name = "related-responses",
          inJson = JsonGroupAsBehavior.LIST
      )
      private List<RelatedResponse> _relatedResponses;

      @BoundField(
          formalName = "Remarks",
          description = "Additional commentary about the containing object.",
          useName = "remarks"
      )
      @BoundFieldValue(
          typeAdapter = MarkupMultilineAdapter.class
      )
      private MarkupMultiline _remarks;

      public Entry() {
      }

      public UUID getUuid() {
        return _uuid;
      }

      public void setUuid(UUID value) {
        _uuid = value;
      }

      public MarkupLine getTitle() {
        return _title;
      }

      public void setTitle(MarkupLine value) {
        _title = value;
      }

      public MarkupMultiline getDescription() {
        return _description;
      }

      public void setDescription(MarkupMultiline value) {
        _description = value;
      }

      public ZonedDateTime getStart() {
        return _start;
      }

      public void setStart(ZonedDateTime value) {
        _start = value;
      }

      public ZonedDateTime getEnd() {
        return _end;
      }

      public void setEnd(ZonedDateTime value) {
        _end = value;
      }

      public List<Property> getProps() {
        return _props;
      }

      public void setProps(List<Property> value) {
        _props = value;
      }

      /**
       * Add a new {@link Property} item to the underlying collection.
       * @param item the item to add
       * @return {@code true}
       */
      public boolean addProp(Property item) {
        Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
        if (_props == null) {
          _props = new LinkedList<>();
        }
        return _props.add(value);
      }

      /**
       * Remove the first matching {@link Property} item from the underlying collection.
       * @param item the item to remove
       * @return {@code true} if the item was removed or {@code false} otherwise
       */
      public boolean removeProp(Property item) {
        Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
        return _props == null ? false : _props.remove(value);
      }

      public List<Link> getLinks() {
        return _links;
      }

      public void setLinks(List<Link> value) {
        _links = value;
      }

      /**
       * Add a new {@link Link} item to the underlying collection.
       * @param item the item to add
       * @return {@code true}
       */
      public boolean addLink(Link item) {
        Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
        if (_links == null) {
          _links = new LinkedList<>();
        }
        return _links.add(value);
      }

      /**
       * Remove the first matching {@link Link} item from the underlying collection.
       * @param item the item to remove
       * @return {@code true} if the item was removed or {@code false} otherwise
       */
      public boolean removeLink(Link item) {
        Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
        return _links == null ? false : _links.remove(value);
      }

      public List<LoggedBy> getLoggedBy() {
        return _loggedBy;
      }

      public void setLoggedBy(List<LoggedBy> value) {
        _loggedBy = value;
      }

      /**
       * Add a new {@link LoggedBy} item to the underlying collection.
       * @param item the item to add
       * @return {@code true}
       */
      public boolean addLoggedBy(LoggedBy item) {
        LoggedBy value = ObjectUtils.requireNonNull(item,"item cannot be null");
        if (_loggedBy == null) {
          _loggedBy = new LinkedList<>();
        }
        return _loggedBy.add(value);
      }

      /**
       * Remove the first matching {@link LoggedBy} item from the underlying collection.
       * @param item the item to remove
       * @return {@code true} if the item was removed or {@code false} otherwise
       */
      public boolean removeLoggedBy(LoggedBy item) {
        LoggedBy value = ObjectUtils.requireNonNull(item,"item cannot be null");
        return _loggedBy == null ? false : _loggedBy.remove(value);
      }

      public String getStatusChange() {
        return _statusChange;
      }

      public void setStatusChange(String value) {
        _statusChange = value;
      }

      public List<RelatedResponse> getRelatedResponses() {
        return _relatedResponses;
      }

      public void setRelatedResponses(List<RelatedResponse> value) {
        _relatedResponses = value;
      }

      /**
       * Add a new {@link RelatedResponse} item to the underlying collection.
       * @param item the item to add
       * @return {@code true}
       */
      public boolean addRelatedResponse(RelatedResponse item) {
        RelatedResponse value = ObjectUtils.requireNonNull(item,"item cannot be null");
        if (_relatedResponses == null) {
          _relatedResponses = new LinkedList<>();
        }
        return _relatedResponses.add(value);
      }

      /**
       * Remove the first matching {@link RelatedResponse} item from the underlying collection.
       * @param item the item to remove
       * @return {@code true} if the item was removed or {@code false} otherwise
       */
      public boolean removeRelatedResponse(RelatedResponse item) {
        RelatedResponse value = ObjectUtils.requireNonNull(item,"item cannot be null");
        return _relatedResponses == null ? false : _relatedResponses.remove(value);
      }

      public MarkupMultiline getRemarks() {
        return _remarks;
      }

      public void setRemarks(MarkupMultiline value) {
        _remarks = value;
      }

      @Override
      public String toString() {
        return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
      }

      /**
       * Identifies an individual risk response that this log entry is for.
       */
      @MetaschemaAssembly(
          formalName = "Risk Response Reference",
          description = "Identifies an individual risk response that this log entry is for.",
          name = "related-response",
          metaschema = OscalAssessmentCommonMetaschema.class
      )
      public static class RelatedResponse {
        @BoundFlag(
            formalName = "Response Universally Unique Identifier Reference",
            description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier reference to a unique risk response.",
            useName = "response-uuid",
            required = true,
            typeAdapter = UuidAdapter.class
        )
        private UUID _responseUuid;

        @BoundAssembly(
            formalName = "Property",
            description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
            useName = "prop",
            maxOccurs = -1
        )
        @GroupAs(
            name = "props",
            inJson = JsonGroupAsBehavior.LIST
        )
        private List<Property> _props;

        @BoundAssembly(
            formalName = "Link",
            description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
            useName = "link",
            maxOccurs = -1
        )
        @GroupAs(
            name = "links",
            inJson = JsonGroupAsBehavior.LIST
        )
        private List<Link> _links;

        @BoundAssembly(
            formalName = "Task Reference",
            description = "Identifies an individual task for which the containing object is a consequence of.",
            useName = "related-task",
            maxOccurs = -1,
            remarks = "This is used to identify the task(s) that this log entry was generated for."
        )
        @GroupAs(
            name = "related-tasks",
            inJson = JsonGroupAsBehavior.LIST
        )
        private List<RelatedTask> _relatedTasks;

        @BoundField(
            formalName = "Remarks",
            description = "Additional commentary about the containing object.",
            useName = "remarks"
        )
        @BoundFieldValue(
            typeAdapter = MarkupMultilineAdapter.class
        )
        private MarkupMultiline _remarks;

        public RelatedResponse() {
        }

        public UUID getResponseUuid() {
          return _responseUuid;
        }

        public void setResponseUuid(UUID value) {
          _responseUuid = value;
        }

        public List<Property> getProps() {
          return _props;
        }

        public void setProps(List<Property> value) {
          _props = value;
        }

        /**
         * Add a new {@link Property} item to the underlying collection.
         * @param item the item to add
         * @return {@code true}
         */
        public boolean addProp(Property item) {
          Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
          if (_props == null) {
            _props = new LinkedList<>();
          }
          return _props.add(value);
        }

        /**
         * Remove the first matching {@link Property} item from the underlying collection.
         * @param item the item to remove
         * @return {@code true} if the item was removed or {@code false} otherwise
         */
        public boolean removeProp(Property item) {
          Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
          return _props == null ? false : _props.remove(value);
        }

        public List<Link> getLinks() {
          return _links;
        }

        public void setLinks(List<Link> value) {
          _links = value;
        }

        /**
         * Add a new {@link Link} item to the underlying collection.
         * @param item the item to add
         * @return {@code true}
         */
        public boolean addLink(Link item) {
          Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
          if (_links == null) {
            _links = new LinkedList<>();
          }
          return _links.add(value);
        }

        /**
         * Remove the first matching {@link Link} item from the underlying collection.
         * @param item the item to remove
         * @return {@code true} if the item was removed or {@code false} otherwise
         */
        public boolean removeLink(Link item) {
          Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
          return _links == null ? false : _links.remove(value);
        }

        public List<RelatedTask> getRelatedTasks() {
          return _relatedTasks;
        }

        public void setRelatedTasks(List<RelatedTask> value) {
          _relatedTasks = value;
        }

        /**
         * Add a new {@link RelatedTask} item to the underlying collection.
         * @param item the item to add
         * @return {@code true}
         */
        public boolean addRelatedTask(RelatedTask item) {
          RelatedTask value = ObjectUtils.requireNonNull(item,"item cannot be null");
          if (_relatedTasks == null) {
            _relatedTasks = new LinkedList<>();
          }
          return _relatedTasks.add(value);
        }

        /**
         * Remove the first matching {@link RelatedTask} item from the underlying collection.
         * @param item the item to remove
         * @return {@code true} if the item was removed or {@code false} otherwise
         */
        public boolean removeRelatedTask(RelatedTask item) {
          RelatedTask value = ObjectUtils.requireNonNull(item,"item cannot be null");
          return _relatedTasks == null ? false : _relatedTasks.remove(value);
        }

        public MarkupMultiline getRemarks() {
          return _remarks;
        }

        public void setRemarks(MarkupMultiline value) {
          _remarks = value;
        }

        @Override
        public String toString() {
          return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
        }
      }
    }
  }

  /**
   * Describes an existing mitigating factor that may affect the overall determination of the risk, with an optional link to an implementation statement in the SSP.
   */
  @MetaschemaAssembly(
      formalName = "Mitigating Factor",
      description = "Describes an existing mitigating factor that may affect the overall determination of the risk, with an optional link to an implementation statement in the SSP.",
      name = "mitigating-factor",
      metaschema = OscalAssessmentCommonMetaschema.class
  )
  public static class MitigatingFactor {
    @BoundFlag(
        formalName = "Mitigating Factor Universally Unique Identifier",
        description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this mitigating factor elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#scope). The locally defined *UUID* of the `mitigating factor` can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
        useName = "uuid",
        required = true,
        typeAdapter = UuidAdapter.class
    )
    private UUID _uuid;

    @BoundFlag(
        formalName = "Implementation UUID",
        description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this implementation statement elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#scope)s. The locally defined *UUID* of the `implementation statement` can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
        useName = "implementation-uuid",
        typeAdapter = UuidAdapter.class
    )
    private UUID _implementationUuid;

    /**
     * "A human-readable description of this mitigating factor."
     */
    @BoundField(
        formalName = "Mitigating Factor Description",
        description = "A human-readable description of this mitigating factor.",
        useName = "description",
        minOccurs = 1
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _description;

    @BoundAssembly(
        formalName = "Property",
        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
        useName = "prop",
        maxOccurs = -1
    )
    @GroupAs(
        name = "props",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Property> _props;

    @BoundAssembly(
        formalName = "Link",
        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
        useName = "link",
        maxOccurs = -1
    )
    @GroupAs(
        name = "links",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Link> _links;

    @BoundAssembly(
        formalName = "Identifies the Subject",
        description = "A [human-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#human-oriented) identifier reference to a resource. Use type to indicate whether the identified resource is a component, inventory item, location, user, or something else.",
        useName = "subject",
        maxOccurs = -1,
        remarks = "Links identifiable elements of the system to this mitigating factor, such as an inventory-item or component."
    )
    @GroupAs(
        name = "subjects",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<SubjectReference> _subjects;

    public MitigatingFactor() {
    }

    public UUID getUuid() {
      return _uuid;
    }

    public void setUuid(UUID value) {
      _uuid = value;
    }

    public UUID getImplementationUuid() {
      return _implementationUuid;
    }

    public void setImplementationUuid(UUID value) {
      _implementationUuid = value;
    }

    public MarkupMultiline getDescription() {
      return _description;
    }

    public void setDescription(MarkupMultiline value) {
      _description = value;
    }

    public List<Property> getProps() {
      return _props;
    }

    public void setProps(List<Property> value) {
      _props = value;
    }

    /**
     * Add a new {@link Property} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_props == null) {
        _props = new LinkedList<>();
      }
      return _props.add(value);
    }

    /**
     * Remove the first matching {@link Property} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _props == null ? false : _props.remove(value);
    }

    public List<Link> getLinks() {
      return _links;
    }

    public void setLinks(List<Link> value) {
      _links = value;
    }

    /**
     * Add a new {@link Link} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_links == null) {
        _links = new LinkedList<>();
      }
      return _links.add(value);
    }

    /**
     * Remove the first matching {@link Link} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _links == null ? false : _links.remove(value);
    }

    public List<SubjectReference> getSubjects() {
      return _subjects;
    }

    public void setSubjects(List<SubjectReference> value) {
      _subjects = value;
    }

    /**
     * Add a new {@link SubjectReference} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addSubject(SubjectReference item) {
      SubjectReference value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_subjects == null) {
        _subjects = new LinkedList<>();
      }
      return _subjects.add(value);
    }

    /**
     * Remove the first matching {@link SubjectReference} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeSubject(SubjectReference item) {
      SubjectReference value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _subjects == null ? false : _subjects.remove(value);
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }
  }
}