#ifndef SAMPLE_HPP_INCLUDED
#define SAMPLE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/CoverGlass.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/Description.h>
#include <NBO/NBO/FacingTheObjectiveChoice_Type.h>
#include <NBO/NBO/LSID_Type.h>
#include <NBO/NBO/MountingMedium.h>
#include <NBO/NBO/SampleHolder.h>
#include <NBO/NBO/SampleType_Type.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML element Sample.
*
* This field captures a description of the sample that was imaged in this experiment.
*/
class NBO_EXPORT Sample : public NBOBaseClass {

public:
	
	Sample();
	~Sample();

	/*!
	* \brief Cast a NBOBaseClass to a Sample.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Sample> fromBase(NBOBaseClassPtr base);

	/*!
	* \brief Returns the class type name.
	*
	* \return The class type name
	*/
	std::string getTypeName() const override;

	/*!
	* \brief Returns the XML element name corresponding to this class.
	*
	* \return The XML element name
	*/
	std::string getXMLName() const override;

	/*!
	* \brief Returns the NBO Type corresponding to this class.
	*
	* \return The NBO Type value
	*/
	ENBOType getNBOType() const override;

	/*!
	* \brief Returns a list of all classes derived from this class.
	*
	* \return The list of derived classes
	*/
	std::vector<NBOBaseClassPtr> getChildren() const override;

	/*!
	* \brief Returns a list of all child elements contained in this class.
	*
	* \return The list of child classes
	*/
	std::vector<NBOBaseClassPtr> getSubElements() const override;

	/*!
	* \brief Populates this object from a JSON file.
	*
	* \param path The path to the JSON file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a JSON string.
	*
	* \param json_string The JSON content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonString(const std::string& json_string, bool validate = true);

	/*!
	* \brief Populates this object from a XML file.
	*
	* \param path The path to the XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a XML string.
	*
	* \param xml_string The XML content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlString(const std::string& xml_string, bool validate = true);

	/*!
	* \brief Serializes this object to an XML file.
	*
	* \param filename The path to the output XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void toXmlFile(const std::string& filename, bool validate = true) const;

	/*!
	* \brief Serializes this object to an XML string.
	*
	* \param validate If true, validates constraints on value. Default is true.
	* \return A string containing the XML representation of this object
	*/
	std::string toXmlString(bool validate = true) const;

	/*!
	* \brief Sets the value of the ID attribute.
	*
	* A unique identifier for this Sample.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setID(const Inscoper::NBO::LSID_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* A unique identifier for this Sample.
	*
	* \return The value of the attribute
	*/
	LSID_TypePtr getID() const;

	/*!
	* \brief Resets the ID attribute to an unset state.
	*
	* A unique identifier for this Sample.
	*/
	void resetID();

	/*!
	* \brief Checks whether the optional ID attribute is present.
	*
	* A unique identifier for this Sample.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasID() const;

	/*!
	* \brief Sets the value of the Name attribute.
	*
	* A user assigned Name for this Sample.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setName(const Inscoper::NBO::Denomination_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Name attribute.
	*
	* A user assigned Name for this Sample.
	*
	* \return The value of the attribute
	*/
	Denomination_TypePtr getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* A user assigned Name for this Sample.
	*/
	void resetName();

	/*!
	* \brief Checks whether the optional Name attribute is present.
	*
	* A user assigned Name for this Sample.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasName() const;

	/*!
	* \brief Sets the value of the BiologicalOrigin attribute.
	*
	* This field captures whether (True) or not (False) this Sample is of Biological Origin.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setBiologicalOrigin(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the BiologicalOrigin attribute.
	*
	* This field captures whether (True) or not (False) this Sample is of Biological Origin.
	*
	* \return The value of the attribute
	*/
	bool getBiologicalOrigin() const;

	/*!
	* \brief Resets the BiologicalOrigin attribute to an unset state.
	*
	* This field captures whether (True) or not (False) this Sample is of Biological Origin.
	*/
	void resetBiologicalOrigin();

	/*!
	* \brief Checks whether the BiologicalOrigin attribute is present.
	*
	* This field captures whether (True) or not (False) this Sample is of Biological Origin.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasBiologicalOrigin() const;

	/*!
	* \brief Sets the value of the SampleType attribute.
	*
	* If of Biological Origin, this field records a term that describes the general category of this Sample.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSampleType(const Inscoper::NBO::SampleType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SampleType attribute.
	*
	* If of Biological Origin, this field records a term that describes the general category of this Sample.
	*
	* \return The value of the attribute
	*/
	SampleType_TypePtr getSampleType() const;

	/*!
	* \brief Resets the SampleType attribute to an unset state.
	*
	* If of Biological Origin, this field records a term that describes the general category of this Sample.
	*/
	void resetSampleType();

	/*!
	* \brief Checks whether the optional SampleType attribute is present.
	*
	* If of Biological Origin, this field records a term that describes the general category of this Sample.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSampleType() const;

	/*!
	* \brief Sets the value of the LiveSample attribute.
	*
	* This field captures whether (True) or not (False) this Sample was living during Image Acquisition.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLiveSample(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the LiveSample attribute.
	*
	* This field captures whether (True) or not (False) this Sample was living during Image Acquisition.
	*
	* \return The value of the attribute
	*/
	bool getLiveSample() const;

	/*!
	* \brief Resets the LiveSample attribute to an unset state.
	*
	* This field captures whether (True) or not (False) this Sample was living during Image Acquisition.
	*/
	void resetLiveSample();

	/*!
	* \brief Checks whether the LiveSample attribute is present.
	*
	* This field captures whether (True) or not (False) this Sample was living during Image Acquisition.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasLiveSample() const;

	/*!
	* \brief Sets the value of the Organism attribute.
	*
	* If this sample is of biological origin, this field records the biological organisn this sample derives from. A biological is a biological entity that consists of one or more cells and is capable of genomic replication (independently or not). The use terms from NCBITaxon (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended. Note: if the sample is not of biological origin please enter none.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOrganism(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Organism attribute.
	*
	* If this sample is of biological origin, this field records the biological organisn this sample derives from. A biological is a biological entity that consists of one or more cells and is capable of genomic replication (independently or not). The use terms from NCBITaxon (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended. Note: if the sample is not of biological origin please enter none.
	*
	* \return The value of the attribute
	*/
	std::string getOrganism() const;

	/*!
	* \brief Resets the Organism attribute to an unset state.
	*
	* If this sample is of biological origin, this field records the biological organisn this sample derives from. A biological is a biological entity that consists of one or more cells and is capable of genomic replication (independently or not). The use terms from NCBITaxon (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended. Note: if the sample is not of biological origin please enter none.
	*/
	void resetOrganism();

	/*!
	* \brief Checks whether the Organism attribute is present.
	*
	* If this sample is of biological origin, this field records the biological organisn this sample derives from. A biological is a biological entity that consists of one or more cells and is capable of genomic replication (independently or not). The use terms from NCBITaxon (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended. Note: if the sample is not of biological origin please enter none.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOrganism() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* If this sample is of biological origin, this field records the biological organisn this sample derives from. A biological is a biological entity that consists of one or more cells and is capable of genomic replication (independently or not). The use terms from NCBITaxon (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended. Note: if the sample is not of biological origin please enter none.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getOrganismAllowedValues();

	/*!
	* \brief Sets the value of the OrganismTermAccession attribute.
	*
	* This field records the Accession ID for the term used to describe the Organism. The use of the NCBITaxon ontology (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOrganismTermAccession(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the OrganismTermAccession attribute.
	*
	* This field records the Accession ID for the term used to describe the Organism. The use of the NCBITaxon ontology (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended.
	*
	* \return The value of the attribute
	*/
	std::string getOrganismTermAccession() const;

	/*!
	* \brief Resets the OrganismTermAccession attribute to an unset state.
	*
	* This field records the Accession ID for the term used to describe the Organism. The use of the NCBITaxon ontology (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended.
	*/
	void resetOrganismTermAccession();

	/*!
	* \brief Checks whether the OrganismTermAccession attribute is present.
	*
	* This field records the Accession ID for the term used to describe the Organism. The use of the NCBITaxon ontology (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOrganismTermAccession() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Accession ID for the term used to describe the Organism. The use of the NCBITaxon ontology (http://purl.obolibrary.org/obo/NCBITaxon_1) is recommended.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getOrganismTermAccessionAllowedValues();

	/*!
	* \brief Sets the value of the OrganismPart attribute.
	*
	* If applicable, this field records the part of organism's anatomy or substance arising from an organism from which the biomaterial was derived, excludes cells. E.g. tissue, organ, system, sperm, blood or body location (arm). The use of a sub-class of the 'Organism Part' (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOrganismPart(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the OrganismPart attribute.
	*
	* If applicable, this field records the part of organism's anatomy or substance arising from an organism from which the biomaterial was derived, excludes cells. E.g. tissue, organ, system, sperm, blood or body location (arm). The use of a sub-class of the 'Organism Part' (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return The value of the attribute
	*/
	std::string getOrganismPart() const;

	/*!
	* \brief Resets the OrganismPart attribute to an unset state.
	*
	* If applicable, this field records the part of organism's anatomy or substance arising from an organism from which the biomaterial was derived, excludes cells. E.g. tissue, organ, system, sperm, blood or body location (arm). The use of a sub-class of the 'Organism Part' (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*/
	void resetOrganismPart();

	/*!
	* \brief Checks whether the OrganismPart attribute is present.
	*
	* If applicable, this field records the part of organism's anatomy or substance arising from an organism from which the biomaterial was derived, excludes cells. E.g. tissue, organ, system, sperm, blood or body location (arm). The use of a sub-class of the 'Organism Part' (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOrganismPart() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* If applicable, this field records the part of organism's anatomy or substance arising from an organism from which the biomaterial was derived, excludes cells. E.g. tissue, organ, system, sperm, blood or body location (arm). The use of a sub-class of the 'Organism Part' (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getOrganismPartAllowedValues();

	/*!
	* \brief Sets the value of the OrganismPartTermAccession attribute.
	*
	* This field records the Accession ID for the term used to describe the Organism. A sub-classe of the EFO:0000635 (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOrganismPartTermAccession(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the OrganismPartTermAccession attribute.
	*
	* This field records the Accession ID for the term used to describe the Organism. A sub-classe of the EFO:0000635 (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return The value of the attribute
	*/
	std::string getOrganismPartTermAccession() const;

	/*!
	* \brief Resets the OrganismPartTermAccession attribute to an unset state.
	*
	* This field records the Accession ID for the term used to describe the Organism. A sub-classe of the EFO:0000635 (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*/
	void resetOrganismPartTermAccession();

	/*!
	* \brief Checks whether the OrganismPartTermAccession attribute is present.
	*
	* This field records the Accession ID for the term used to describe the Organism. A sub-classe of the EFO:0000635 (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOrganismPartTermAccession() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Accession ID for the term used to describe the Organism. A sub-classe of the EFO:0000635 (http://www.ebi.ac.uk/efo/EFO_0000635) term from the Experimental Factor Ontology (EFO; http://www.ebi.ac.uk/efo/) is recommended.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getOrganismPartTermAccessionAllowedValues();

	/*!
	* \brief Sets the value of the SamplePreparationMethod attribute.
	*
	* This field records the method that was used to prepare this sample. The use of a sub-class of the 'Sample Preparation Method' (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSamplePreparationMethod(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the SamplePreparationMethod attribute.
	*
	* This field records the method that was used to prepare this sample. The use of a sub-class of the 'Sample Preparation Method' (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended. 
	*
	* \return The value of the attribute
	*/
	std::string getSamplePreparationMethod() const;

	/*!
	* \brief Resets the SamplePreparationMethod attribute to an unset state.
	*
	* This field records the method that was used to prepare this sample. The use of a sub-class of the 'Sample Preparation Method' (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended. 
	*/
	void resetSamplePreparationMethod();

	/*!
	* \brief Checks whether the SamplePreparationMethod attribute is present.
	*
	* This field records the method that was used to prepare this sample. The use of a sub-class of the 'Sample Preparation Method' (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasSamplePreparationMethod() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the method that was used to prepare this sample. The use of a sub-class of the 'Sample Preparation Method' (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended. 
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getSamplePreparationMethodAllowedValues();

	/*!
	* \brief Sets the value of the SamplePreparationMethodTermAccession attribute.
	*
	* This field records the the Accession ID for the term used to describe method that was used to prepare this sample. A subclass of the Fbbi:00000001 (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSamplePreparationMethodTermAccession(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the SamplePreparationMethodTermAccession attribute.
	*
	* This field records the the Accession ID for the term used to describe method that was used to prepare this sample. A subclass of the Fbbi:00000001 (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended.
	*
	* \return The value of the attribute
	*/
	std::string getSamplePreparationMethodTermAccession() const;

	/*!
	* \brief Resets the SamplePreparationMethodTermAccession attribute to an unset state.
	*
	* This field records the the Accession ID for the term used to describe method that was used to prepare this sample. A subclass of the Fbbi:00000001 (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended.
	*/
	void resetSamplePreparationMethodTermAccession();

	/*!
	* \brief Checks whether the SamplePreparationMethodTermAccession attribute is present.
	*
	* This field records the the Accession ID for the term used to describe method that was used to prepare this sample. A subclass of the Fbbi:00000001 (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasSamplePreparationMethodTermAccession() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the the Accession ID for the term used to describe method that was used to prepare this sample. A subclass of the Fbbi:00000001 (http://purl.obolibrary.org/obo/FBbi_00000001) term from the Biological Imaging Methods Ontology (FBbi; https://www.ebi.ac.uk/ols/ontologies/fbbi) is recommended.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getSamplePreparationMethodTermAccessionAllowedValues();

	/*!
	* \brief Sets the value of the MetrologySample attribute.
	*
	* This field captures whether (True) or not (False) this is a Metrology Sample (i.e., a Sample that is used specifcially to calibrate and assess the performance of the Instrument utilized for this experimental Image Acquisition.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMetrologySample(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the MetrologySample attribute.
	*
	* This field captures whether (True) or not (False) this is a Metrology Sample (i.e., a Sample that is used specifcially to calibrate and assess the performance of the Instrument utilized for this experimental Image Acquisition.
	*
	* \return The value of the attribute
	*/
	bool getMetrologySample() const;

	/*!
	* \brief Resets the MetrologySample attribute to an unset state.
	*
	* This field captures whether (True) or not (False) this is a Metrology Sample (i.e., a Sample that is used specifcially to calibrate and assess the performance of the Instrument utilized for this experimental Image Acquisition.
	*/
	void resetMetrologySample();

	/*!
	* \brief Checks whether the MetrologySample attribute is present.
	*
	* This field captures whether (True) or not (False) this is a Metrology Sample (i.e., a Sample that is used specifcially to calibrate and assess the performance of the Instrument utilized for this experimental Image Acquisition.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasMetrologySample() const;

	/*!
	* \brief Sets the value of the FacingTheObjective attribute.
	*
	* This field captures whether the CoverGlass, the SampleHolder, or neither (None), faced the Objective during Acquisition of this Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setFacingTheObjective(const Inscoper::NBO::FacingTheObjectiveChoice_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the FacingTheObjective attribute.
	*
	* This field captures whether the CoverGlass, the SampleHolder, or neither (None), faced the Objective during Acquisition of this Image.
	*
	* \return The value of the attribute
	*/
	FacingTheObjectiveChoice_TypePtr getFacingTheObjective() const;

	/*!
	* \brief Resets the FacingTheObjective attribute to an unset state.
	*
	* This field captures whether the CoverGlass, the SampleHolder, or neither (None), faced the Objective during Acquisition of this Image.
	*/
	void resetFacingTheObjective();

	/*!
	* \brief Checks whether the optional FacingTheObjective attribute is present.
	*
	* This field captures whether the CoverGlass, the SampleHolder, or neither (None), faced the Objective during Acquisition of this Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasFacingTheObjective() const;

	/*!
	* \brief Sets the list of MountingMedium elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of MountingMedium elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMountingMedium_List(const std::vector<Inscoper::NBO::MountingMediumPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of MountingMedium elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of MountingMedium elements
	*/
	std::vector<Inscoper::NBO::MountingMediumPtr> getMountingMedium_List() const;

	/*!
	* \brief Adds a new MountingMedium element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToMountingMedium_List(const Inscoper::NBO::MountingMediumPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of MountingMedium.
	*
	* No description available in the XSD standard.
	*/
	void clearMountingMedium_List();

	/*!
	* \brief Sets the list of CoverGlass elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of CoverGlass elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCoverGlass_List(const std::vector<Inscoper::NBO::CoverGlassPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of CoverGlass elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of CoverGlass elements
	*/
	std::vector<Inscoper::NBO::CoverGlassPtr> getCoverGlass_List() const;

	/*!
	* \brief Adds a new CoverGlass element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToCoverGlass_List(const Inscoper::NBO::CoverGlassPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of CoverGlass.
	*
	* No description available in the XSD standard.
	*/
	void clearCoverGlass_List();

	/*!
	* \brief Sets the list of SampleHolder elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of SampleHolder elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSampleHolder_List(const std::vector<Inscoper::NBO::SampleHolderPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of SampleHolder elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of SampleHolder elements
	*/
	std::vector<Inscoper::NBO::SampleHolderPtr> getSampleHolder_List() const;

	/*!
	* \brief Adds a new SampleHolder element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToSampleHolder_List(const Inscoper::NBO::SampleHolderPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of SampleHolder.
	*
	* No description available in the XSD standard.
	*/
	void clearSampleHolder_List();

	/*!
	* \brief Sets the value of the Description element.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDescription(const Inscoper::NBO::DescriptionPtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Description element.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::DescriptionPtr getDescription() const;

	/*!
	* \brief Resets the Description element to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetDescription();

	/*!
	* \brief Checks whether the optional Description element is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDescription() const;

	/*!
	* \brief Sets the list of AnnotationRef elements.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \param value The new list of AnnotationRef elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAnnotationRef_List(const std::vector<Inscoper::NBO::AnnotationRefPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of AnnotationRef elements.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return The list of AnnotationRef elements
	*/
	std::vector<Inscoper::NBO::AnnotationRefPtr> getAnnotationRef_List() const;

	/*!
	* \brief Adds a new AnnotationRef element to this object.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToAnnotationRef_List(const Inscoper::NBO::AnnotationRefPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of AnnotationRef.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*/
	void clearAnnotationRef_List();


private:
	class Impl;
	std::unique_ptr<Impl> pImpl;

	LSID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Required attribute
    std::optional<bool> BiologicalOrigin; // Required attribute
	SampleType_TypePtr SampleType = nullptr; // Required attribute
    std::optional<bool> LiveSample; // Required attribute
    std::optional<std::string> Organism; // Required attribute
    static const std::set<std::string> OrganismAllowedValues;
    std::optional<std::string> OrganismTermAccession; // Optional attribute
    static const std::set<std::string> OrganismTermAccessionAllowedValues;
    std::optional<std::string> OrganismPart; // Optional attribute
    static const std::set<std::string> OrganismPartAllowedValues;
    std::optional<std::string> OrganismPartTermAccession; // Optional attribute
    static const std::set<std::string> OrganismPartTermAccessionAllowedValues;
    std::optional<std::string> SamplePreparationMethod; // Optional attribute
    static const std::set<std::string> SamplePreparationMethodAllowedValues;
    std::optional<std::string> SamplePreparationMethodTermAccession; // Optional attribute
    static const std::set<std::string> SamplePreparationMethodTermAccessionAllowedValues;
    std::optional<bool> MetrologySample; // Required attribute
	FacingTheObjectiveChoice_TypePtr FacingTheObjective = nullptr; // Optional attribute
    std::vector<Inscoper::NBO::MountingMediumPtr> MountingMedium_List;
    std::vector<Inscoper::NBO::CoverGlassPtr> CoverGlass_List;
    std::vector<Inscoper::NBO::SampleHolderPtr> SampleHolder_List;
    Inscoper::NBO::DescriptionPtr Description = nullptr;
    std::vector<Inscoper::NBO::AnnotationRefPtr> AnnotationRef_List;
};

/*! Shared pointer for Sample*/
typedef std::shared_ptr<Sample> SamplePtr;

} // namespace Inscoper::NBO

#endif // SAMPLE_HPP_INCLUDED