#ifndef INSTRUMENT_HPP_INCLUDED
#define INSTRUMENT_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AcoustoOpticalDevice_Type.h>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/ConfocalScanner_Type.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/Detector_Type.h>
#include <NBO/NBO/ElectroOpticalDevice_Type.h>
#include <NBO/NBO/EnvironmentalControlDevice.h>
#include <NBO/NBO/Filter_Type.h>
#include <NBO/NBO/FocusStabilizationDevice.h>
#include <NBO/NBO/InstrumentID_Type.h>
#include <NBO/NBO/IntensityCalibrationTool.h>
#include <NBO/NBO/Lens_Type.h>
#include <NBO/NBO/LightSourceCoupling_Type.h>
#include <NBO/NBO/LightSource_Type.h>
#include <NBO/NBO/MicrolensArray.h>
#include <NBO/NBO/MicroscopeStand_Type.h>
#include <NBO/NBO/MicroscopeTable.h>
#include <NBO/NBO/MirroringDevice_Type.h>
#include <NBO/NBO/Objective.h>
#include <NBO/NBO/OpticalAperture_Type.h>
#include <NBO/NBO/OpticalAssembly_Type.h>
#include <NBO/NBO/OpticsHolder_Type.h>
#include <NBO/NBO/PolarizationOptics.h>
#include <NBO/NBO/Prism.h>
#include <NBO/NBO/SamplePositioning_Type.h>
#include <NBO/NBO/Software_Type.h>
#include <NBO/NBO/StageInsert.h>
#include <NBO/NBO/TIRFHardwareModule.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML element Instrument.
*
* This element describes the Instrument used to capture the Image. It is primarily a container referring to the list of hardware components included in a given Microscope. The list consists of the Microscope Stand, Microscope Table, Light Source, Light Source Coupling, Sample Holder, Focusing, Objective, Filter, Dichroic, Additional Lens (including a commonly used Magnification Changer, also known as Optovar), Additional Mirroring Device, Polarization Optics, Prism, Optical Aperture, Optical Device, Detector and Calibration Tool. The Filter element can be either composed of separate Excitation, Emission filters, and Dichroic mirrors or a single Filter Set. An Instrument might have multiple Light Sources, Detectors, Objectives, and Filters, etc. Each of these has its own ID attribute, which can be referred to from the Image, Plane or more commonly Channel elements associated with a given Image Acquisition session. It is understood that the Light Path configuration can be different for each Channel, but cannot be different for each timepoint or each Plane of an XYZ stack.
*/
class NBO_EXPORT Instrument : public NBOBaseClass {

public:
	
	Instrument();
	~Instrument();

	/*!
	* \brief Cast a NBOBaseClass to a Instrument.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Instrument> 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 file generated by MicroMeta App.
	*
	* \param path The path to the JSON file
	*/
	void fromMicroMetaAppJsonFile(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 component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setID(const Inscoper::NBO::InstrumentID_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* A Unique Identifier for this component.
	*
	* \return The value of the attribute
	*/
	InstrumentID_TypePtr getID() const;

	/*!
	* \brief Resets the ID attribute to an unset state.
	*
	* A Unique Identifier for this component.
	*/
	void resetID();

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

	/*!
	* \brief Sets the value of the Name attribute.
	*
	* A User-defined Name for this component.
	*
	* \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-defined Name for this component.
	*
	* \return The value of the attribute
	*/
	Denomination_TypePtr getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* A User-defined Name for this component.
	*/
	void resetName();

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

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

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

	/*!
	* \brief Adds a new MicroscopeStandGroup 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 addToMicroscopeStandGroup_List(const Inscoper::NBO::MicroscopeStand_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new MicroscopeTable 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 addToMicroscopeTable_List(const Inscoper::NBO::MicroscopeTablePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new SoftwareGroup 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 addToSoftwareGroup_List(const Inscoper::NBO::Software_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new EnvironmentalControlDevice 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 addToEnvironmentalControlDevice_List(const Inscoper::NBO::EnvironmentalControlDevicePtr& value, bool validate = true);

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

	/*!
	* \brief Sets the list of LightSourceGroup elements.
	*
	* This element describes the light source(s) available in this microscope
	*
	* \param value The new list of LightSourceGroup elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLightSourceGroup_List(const std::vector<Inscoper::NBO::LightSource_TypePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of LightSourceGroup elements.
	*
	* This element describes the light source(s) available in this microscope
	*
	* \return The list of LightSourceGroup elements
	*/
	std::vector<Inscoper::NBO::LightSource_TypePtr> getLightSourceGroup_List() const;

	/*!
	* \brief Adds a new LightSourceGroup element to this object.
	*
	* This element describes the light source(s) available in this microscope
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToLightSourceGroup_List(const Inscoper::NBO::LightSource_TypePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of LightSourceGroup.
	*
	* This element describes the light source(s) available in this microscope
	*/
	void clearLightSourceGroup_List();

	/*!
	* \brief Sets the list of LightSourceCouplingGroup elements.
	*
	* This element describes the method(s) used to couple the light source with the light path moving through speciment to the detector
	*
	* \param value The new list of LightSourceCouplingGroup elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLightSourceCouplingGroup_List(const std::vector<Inscoper::NBO::LightSourceCoupling_TypePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of LightSourceCouplingGroup elements.
	*
	* This element describes the method(s) used to couple the light source with the light path moving through speciment to the detector
	*
	* \return The list of LightSourceCouplingGroup elements
	*/
	std::vector<Inscoper::NBO::LightSourceCoupling_TypePtr> getLightSourceCouplingGroup_List() const;

	/*!
	* \brief Adds a new LightSourceCouplingGroup element to this object.
	*
	* This element describes the method(s) used to couple the light source with the light path moving through speciment to the detector
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToLightSourceCouplingGroup_List(const Inscoper::NBO::LightSourceCoupling_TypePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of LightSourceCouplingGroup.
	*
	* This element describes the method(s) used to couple the light source with the light path moving through speciment to the detector
	*/
	void clearLightSourceCouplingGroup_List();

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

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

	/*!
	* \brief Adds a new Objective 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 addToObjective_List(const Inscoper::NBO::ObjectivePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new OpticalAssemblyGroup 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 addToOpticalAssemblyGroup_List(const Inscoper::NBO::OpticalAssembly_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new OpticalApertureGroup 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 addToOpticalApertureGroup_List(const Inscoper::NBO::OpticalAperture_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new StageInsert 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 addToStageInsert_List(const Inscoper::NBO::StageInsertPtr& value, bool validate = true);

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

	/*!
	* \brief Sets the list of SamplePositioningGroup elements.
	*
	* This element describes the objective lens and stage positioning device(s) available in this microscope. An Instrument may have more than one of these devices. The type of Focusing Device is specified by one of the child-element which are 'MechanicalStage', 'PiezoElectricSate', or 'PiezoElectricObjective'
	*
	* \param value The new list of SamplePositioningGroup elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSamplePositioningGroup_List(const std::vector<Inscoper::NBO::SamplePositioning_TypePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of SamplePositioningGroup elements.
	*
	* This element describes the objective lens and stage positioning device(s) available in this microscope. An Instrument may have more than one of these devices. The type of Focusing Device is specified by one of the child-element which are 'MechanicalStage', 'PiezoElectricSate', or 'PiezoElectricObjective'
	*
	* \return The list of SamplePositioningGroup elements
	*/
	std::vector<Inscoper::NBO::SamplePositioning_TypePtr> getSamplePositioningGroup_List() const;

	/*!
	* \brief Adds a new SamplePositioningGroup element to this object.
	*
	* This element describes the objective lens and stage positioning device(s) available in this microscope. An Instrument may have more than one of these devices. The type of Focusing Device is specified by one of the child-element which are 'MechanicalStage', 'PiezoElectricSate', or 'PiezoElectricObjective'
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToSamplePositioningGroup_List(const Inscoper::NBO::SamplePositioning_TypePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of SamplePositioningGroup.
	*
	* This element describes the objective lens and stage positioning device(s) available in this microscope. An Instrument may have more than one of these devices. The type of Focusing Device is specified by one of the child-element which are 'MechanicalStage', 'PiezoElectricSate', or 'PiezoElectricObjective'
	*/
	void clearSamplePositioningGroup_List();

	/*!
	* \brief Sets the list of FocusStabilizationDevice elements.
	*
	* This element describes the focus stabilization device(s) available for this microscope
	*
	* \param value The new list of FocusStabilizationDevice elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setFocusStabilizationDevice_List(const std::vector<Inscoper::NBO::FocusStabilizationDevicePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of FocusStabilizationDevice elements.
	*
	* This element describes the focus stabilization device(s) available for this microscope
	*
	* \return The list of FocusStabilizationDevice elements
	*/
	std::vector<Inscoper::NBO::FocusStabilizationDevicePtr> getFocusStabilizationDevice_List() const;

	/*!
	* \brief Adds a new FocusStabilizationDevice element to this object.
	*
	* This element describes the focus stabilization device(s) available for this microscope
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToFocusStabilizationDevice_List(const Inscoper::NBO::FocusStabilizationDevicePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of FocusStabilizationDevice.
	*
	* This element describes the focus stabilization device(s) available for this microscope
	*/
	void clearFocusStabilizationDevice_List();

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

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

	/*!
	* \brief Adds a new OpticsHolderGroup 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 addToOpticsHolderGroup_List(const Inscoper::NBO::OpticsHolder_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new FilterGroup 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 addToFilterGroup_List(const Inscoper::NBO::Filter_TypePtr& value, bool validate = true);

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

	/*!
	* \brief Sets the list of MirroringDeviceGroup elements.
	*
	* This element describes mirror component(s) available in this microscope
	*
	* \param value The new list of MirroringDeviceGroup elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMirroringDeviceGroup_List(const std::vector<Inscoper::NBO::MirroringDevice_TypePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of MirroringDeviceGroup elements.
	*
	* This element describes mirror component(s) available in this microscope
	*
	* \return The list of MirroringDeviceGroup elements
	*/
	std::vector<Inscoper::NBO::MirroringDevice_TypePtr> getMirroringDeviceGroup_List() const;

	/*!
	* \brief Adds a new MirroringDeviceGroup element to this object.
	*
	* This element describes mirror component(s) available in this microscope
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToMirroringDeviceGroup_List(const Inscoper::NBO::MirroringDevice_TypePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of MirroringDeviceGroup.
	*
	* This element describes mirror component(s) available in this microscope
	*/
	void clearMirroringDeviceGroup_List();

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

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

	/*!
	* \brief Adds a new LensGroup 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 addToLensGroup_List(const Inscoper::NBO::Lens_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new Prism 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 addToPrism_List(const Inscoper::NBO::PrismPtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new PolarizationOptics 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 addToPolarizationOptics_List(const Inscoper::NBO::PolarizationOpticsPtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new DetectorGroup 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 addToDetectorGroup_List(const Inscoper::NBO::Detector_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new TIRFHardwareModule 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 addToTIRFHardwareModule_List(const Inscoper::NBO::TIRFHardwareModulePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new ConfocalScannerGroup 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 addToConfocalScannerGroup_List(const Inscoper::NBO::ConfocalScanner_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new AcoustoOpticalDeviceGroup 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 addToAcoustoOpticalDeviceGroup_List(const Inscoper::NBO::AcoustoOpticalDevice_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new ElectroOpticalDeviceGroup 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 addToElectroOpticalDeviceGroup_List(const Inscoper::NBO::ElectroOpticalDevice_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new MicrolensArray 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 addToMicrolensArray_List(const Inscoper::NBO::MicrolensArrayPtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new IntensityCalibrationTool 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 addToIntensityCalibrationTool_List(const Inscoper::NBO::IntensityCalibrationToolPtr& value, bool validate = true);

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

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

	/*!
	* \brief Returns the value of the AnnotationRef element.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::AnnotationRefPtr getAnnotationRef() const;

	/*!
	* \brief Resets the AnnotationRef element to an unset state.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*/
	void resetAnnotationRef();

	/*!
	* \brief Checks whether the optional AnnotationRef element is present.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAnnotationRef() const;


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

	InstrumentID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Required attribute
    std::vector<Inscoper::NBO::MicroscopeStand_TypePtr> MicroscopeStandGroup_List;
    std::vector<Inscoper::NBO::MicroscopeTablePtr> MicroscopeTable_List;
    std::vector<Inscoper::NBO::Software_TypePtr> SoftwareGroup_List;
    std::vector<Inscoper::NBO::EnvironmentalControlDevicePtr> EnvironmentalControlDevice_List;
    std::vector<Inscoper::NBO::LightSource_TypePtr> LightSourceGroup_List;
    std::vector<Inscoper::NBO::LightSourceCoupling_TypePtr> LightSourceCouplingGroup_List;
    std::vector<Inscoper::NBO::ObjectivePtr> Objective_List;
    std::vector<Inscoper::NBO::OpticalAssembly_TypePtr> OpticalAssemblyGroup_List;
    std::vector<Inscoper::NBO::OpticalAperture_TypePtr> OpticalApertureGroup_List;
    std::vector<Inscoper::NBO::StageInsertPtr> StageInsert_List;
    std::vector<Inscoper::NBO::SamplePositioning_TypePtr> SamplePositioningGroup_List;
    std::vector<Inscoper::NBO::FocusStabilizationDevicePtr> FocusStabilizationDevice_List;
    std::vector<Inscoper::NBO::OpticsHolder_TypePtr> OpticsHolderGroup_List;
    std::vector<Inscoper::NBO::Filter_TypePtr> FilterGroup_List;
    std::vector<Inscoper::NBO::MirroringDevice_TypePtr> MirroringDeviceGroup_List;
    std::vector<Inscoper::NBO::Lens_TypePtr> LensGroup_List;
    std::vector<Inscoper::NBO::PrismPtr> Prism_List;
    std::vector<Inscoper::NBO::PolarizationOpticsPtr> PolarizationOptics_List;
    std::vector<Inscoper::NBO::Detector_TypePtr> DetectorGroup_List;
    std::vector<Inscoper::NBO::TIRFHardwareModulePtr> TIRFHardwareModule_List;
    std::vector<Inscoper::NBO::ConfocalScanner_TypePtr> ConfocalScannerGroup_List;
    std::vector<Inscoper::NBO::AcoustoOpticalDevice_TypePtr> AcoustoOpticalDeviceGroup_List;
    std::vector<Inscoper::NBO::ElectroOpticalDevice_TypePtr> ElectroOpticalDeviceGroup_List;
    std::vector<Inscoper::NBO::MicrolensArrayPtr> MicrolensArray_List;
    std::vector<Inscoper::NBO::IntensityCalibrationToolPtr> IntensityCalibrationTool_List;
    Inscoper::NBO::AnnotationRefPtr AnnotationRef = nullptr;
};

/*! Shared pointer for Instrument*/
typedef std::shared_ptr<Instrument> InstrumentPtr;

} // namespace Inscoper::NBO

#endif // INSTRUMENT_HPP_INCLUDED