//-----------------------------------------------------------------------------
#ifndef	MVIMPACT_ACQUIRE_H_
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
#	define MVIMPACT_ACQUIRE_H_ MVIMPACT_ACQUIRE_H_
#endif // DOXYGEN_SHOULD_SKIP_THIS && WRAP_ANY
//-----------------------------------------------------------------------------
#ifdef SWIG
#	define WRAP_PYTHON
#endif // ifdef SWIG

#ifdef WRAP_PYTHON
#	define PYTHON_ONLY(X) X
#	define PYTHON_CPP_SWITCH(PYTHON_WRAPPER_CODE,CPP_WRAPPER_CODE) PYTHON_WRAPPER_CODE
#	ifndef WRAP_ANY
#		define WRAP_ANY
#	endif // #ifndef WRAP_ANY
#else // #ifdef WRAP_PYTHON
#	define PYTHON_ONLY(X)
#	define PYTHON_CPP_SWITCH(PYTHON_WRAPPER_CODE,CPP_WRAPPER_CODE) CPP_WRAPPER_CODE
#endif // #ifdef WRAP_PYTHON

#ifdef WRAP_DOTNET
#	define DOTNET_ONLY(X) X
#	define DOTNET_CPP_SWITCH(DOTNET_WRAPPER_CODE,CPP_WRAPPER_CODE) DOTNET_WRAPPER_CODE
#	ifndef WRAP_ANY
#		define WRAP_ANY
#	endif // #ifndef WRAP_ANY
#else // #ifdef WRAP_DOTNET
#	define DOTNET_ONLY(X)
#	define DOTNET_CPP_SWITCH(DOTNET_WRAPPER_CODE,CPP_WRAPPER_CODE) CPP_WRAPPER_CODE
#endif // #ifdef WRAP_DOTNET

#ifdef _MSC_VER	// is Microsoft compiler?
#	pragma warning( push )
#	if _MSC_VER < 1300	// is 'old' VC 6 compiler?
#		pragma warning( disable : 4786 ) // 'identifier was truncated to '255' characters in the debug information'
#		define __FUNCTION__ "Not supported by this(Microsoft) compiler"
#	endif // #if _MSC_VER < 1300
#	if _MSC_VER >= 1400 // is at least VC 2005 compiler?
#		pragma warning( disable : 4996 ) // '<function> was declared deprecated'
#	endif // #if _MSC_VER >= 1400
#	pragma warning( disable : 4512 ) // 'assignment operator could not be generated' (reason: assignment operators declard 'private' but not implemented)
#endif // #ifdef _MSC_VER

#ifndef WRAP_ANY
	// STL includes
#	include <map>
#	include <stdexcept>
#	include <sstream>
#	include <string>
#	include <vector>
#	include <string.h>
#	include <stdlib.h>
#	include <memory.h>
#endif // #ifdef WRAP_ANY

#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
#	ifdef _WIN32
#		if defined(__BORLANDC__)
#			pragma option push -b // force enums to the size of integer
#			define __FUNCTION__ "Not supported by this(Borland) compiler"
#		endif
#	endif // _WIN32
#endif // DOXYGEN_SHOULD_SKIP_THIS && WRAP_ANY

#ifndef WRAP_PYTHON
	namespace mvIMPACT {
		namespace acquire {
#endif // #ifdef WRAP_PYTHON

#ifndef WRAP_ANY
#	ifdef MVIMPACT_H_
		// needed to keep the C-header working
		using mvIMPACT_C::IPL_BUFHANDLE;
		// needed as otherwise the .NET wrapper generator gets confused
		using mvIMPACT::Image;
#	endif // #ifdef MVIMPACT_H_
#endif // #ifndef WRAP_ANY

#ifdef DOXYGEN_SHOULD_SKIP_THIS
#	define MVIMPACT_H_ // force doxygen to include mvIMPACT related functions
#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS

// import C-API header into the namespace
#include <mvDeviceManager/Include/mvDeviceManager.h>

// predeclares
#ifndef DOXYGEN_SHOULD_SKIP_THIS
	class CameraDescriptionManager;
	class CameraSettingsBlueFOX;
	class ComponentList;
	class ComponentLocator;
	class Device;
	class DigitalInput;
	class DigitalOutput;
	class IOSubSystem;
	class ImageProcessingBase;
	class ImageRequestControl;
	class Request;
	class RTCtrProgram;
	class RTCtrProgramStep;
	class WhiteBalanceSettings;
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS

#ifndef WRAP_DOTNET
#	ifdef MVIMPACT_H_
		//-----------------------------------------------------------------------------
		/// \brief An exception base class for this module.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// If \a mvIMPACT.h has been included before including this interface, this class will
		/// be derived from <b>mvIMPACT::ImpactException</b>, which is derived from <b>std::runtime_error</b>.
		/// If this interface is used without the rest of the <b>mvIMPACT</b> library, this class
		/// will be derived directly from <b>std::runtime_error</b>, but apart from that will provide the
		/// same interface and class layout.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		class ImpactAcquireException : public mvIMPACT::ImpactException
		//-----------------------------------------------------------------------------
		{
		public:
			/// \brief Constructs a new <b>mvIMPACT::acquire::ImpactAcquireException</b> object.
			explicit ImpactAcquireException(	/// The string representation of the error.
												const std::string& errorString,
												/// The origin of the error (function name and line)
												const std::string& errorOrigin,
												/// The numerical representation of the error.
												int errorCode ) : ImpactException(errorString, errorOrigin, errorCode) {}
			virtual ~ImpactAcquireException() throw() {}
#ifndef WRAP_PYTHON	// To date, no customer uses Python, so we don't need backward compatibility here.
			// Python users are encouraged to use the properties errorString, errorOrigin, errorCode and errorCodeAsString.

			// backward compatible functions
			/// \brief Returns an error string containing information about the reason for the error.
			///
			/// \note
			/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
			/// <b>mvIMPACT::acquire::ImpactAcquireException::getErrorString</b> instead. However it exactly behaves like
			/// the new function, which was introduced to achieved unified function names across the complete mvIMPACT
			/// library.
			std::string errString( void ) const { return getErrorString(); }
			/// \brief Returns a unique numerical representation for this error.
			///
			/// \note
			/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
			/// <b>mvIMPACT::acquire::ImpactAcquireException::getError</b> instead. However it exactly behaves like
			/// the new function, which was introduced to achieved unified function names across the complete mvIMPACT
			/// library.
			int errCode( void ) const { return getErrorCode(); }
#endif // !WRAP_PYTHON
			/// \brief Returns a string representation of the numerical error string.
			///
			/// This function will return the name of the enum of the error code. 
			///
			/// <b>EXAMPLE:</b>
			///
			/// In case of error <b>-2102</b> this function would return <b>DMR_DRV_ALREADY_IN_USE</b>, which
			/// is the error codes corresponding enum name.
			std::string getErrorCodeAsString( void ) const { return DMR_ErrorCodeToString( getErrorCode() ); }
			/// \brief Returns a string representation of a numerical error string.
			///
			/// This function will return the name of the enum of the error code. 
			///
			/// <b>EXAMPLE:</b>
			///
			/// In case of error <b>-2102</b> this function would return <b>DMR_DRV_ALREADY_IN_USE</b>, which
			/// is the error codes corresponding enum name.
			static std::string getErrorCodeAsString( int errorCode ) { return DMR_ErrorCodeToString( errorCode ); }
	};
#	else
		//-----------------------------------------------------------------------------
		/// \brief An exception base class for this module.
		class ImpactAcquireException : public std::runtime_error
		//-----------------------------------------------------------------------------
		{
			const int m_errorCode;
			const std::string m_errorOrigin;
		public:
			/// \brief Constructs a new <b>mvIMPACT::acquire::ImpactAcquireException</b> object.
			explicit ImpactAcquireException(	/// The string representation of the error.
												const std::string& errorString,
												/// The origin of the error (function name and line)
												const std::string& errorOrigin,
												/// The numerical representation of the error.
												int errorCode ) : std::runtime_error(errorString), m_errorCode(errorCode), m_errorOrigin(errorOrigin) {}
			virtual ~ImpactAcquireException() throw() {}
			/// \brief Returns an error string containing information about the reason for the error.
			///
			/// \note
			/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
			/// <b>mvIMPACT::acquire::ImpactAcquireException::getErrorString</b> instead. However it exactly behaves like
			/// the new function, which was introduced to achieved unified function names across the complete mvIMPACT
			/// library.
			std::string	errString( void ) const { return what(); }
			/// \brief Returns an error string containing information about the reason for the error.
			std::string	getErrorString( void ) const { return what(); }
			/// \brief Returns a unique numerical representation for this error.
			///
			/// \note
			/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
			/// <b>mvIMPACT::acquire::ImpactAcquireException::getError</b> instead. However it exactly behaves like
			/// the new function, which was introduced to achieved unified function names across the complete mvIMPACT
			/// library.
			int	errCode( void ) const { return m_errorCode; }
			/// \brief Returns a unique numerical representation for this error.
			int	getErrorCode( void ) const { return m_errorCode; }
			/// \brief Returns a string representation of the numerical error string.
			///
			/// This function will return the name of the enum of the error code. 
			///
			/// <b>EXAMPLE:</b>
			///
			/// In case of error <b>-2102</b> this function would return <b>DMR_DRV_ALREADY_IN_USE</b>, which
			/// is the error codes corresponding enum name.
			std::string getErrorCodeAsString( void ) const { return DMR_ErrorCodeToString( m_errorCode ); }
			/// \brief Returns a string representation of a numerical error string.
			///
			/// This function will return the name of the enum of the error code. 
			///
			/// <b>EXAMPLE:</b>
			///
			/// In case of error <b>-2102</b> this function would return <b>DMR_DRV_ALREADY_IN_USE</b>, which
			/// is the error codes corresponding enum name.
			static std::string getErrorCodeAsString( int errorCode ) { return DMR_ErrorCodeToString( errorCode ); }
			/// \brief Returns information about the origin of the error.
			///
			/// The string returned by this function will contain the name of the function
			/// and the line number where the exception was raised.
			std::string getErrorOrigin( void ) const { return m_errorOrigin; }
		};
#	endif // #ifdef MVIMPACT_H_

	//-----------------------------------------------------------------------------
	/// \brief A base class for device manager related exceptions.
	class EDeviceManager : public ImpactAcquireException
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EDeviceManager(	/// \brief The error string.
									const std::string& errorString,
									/// \brief The error origin 
									const std::string& errorOrigin,
									/// \brief The error code.
									TDMR_ERROR errorCode ) : ImpactAcquireException(errorString, errorOrigin, errorCode ) {}
		virtual ~EDeviceManager() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief A base class for exceptions related to the property module.
	///
	/// This exception object will only be raised if an unknown error occurred.
	/// To check for errors related to the property module a catch block for
	/// <b>EPropertyHandling</b> objects can be written to catch all property module related
	/// exceptions.
	class EPropertyHandling : public ImpactAcquireException
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Creates a new <b>EPropertyHandling</b> object.
		explicit EPropertyHandling( /// \brief The error string.
									const std::string& errorString,
									/// \brief The error origin 
									const std::string& errorOrigin,
									/// \brief The error code.
									TPROPHANDLING_ERROR errorCode ) : ImpactAcquireException(errorString, errorOrigin, errorCode) {}
		virtual ~EPropertyHandling() throw() {}
	};

	//-----------------------------------------------------------------------------
	// COMPONENT EXCEPTION CLASSES :
	//-----------------------------------------------------------------------------
	//-----------------------------------------------------------------------------
	/// \brief A base class for component related errors from the property module.
	///
	/// This exception object will never be raised in the code. It can't be constructed
	/// directly but to check for <b>mvIMPACT::acquire::Component</b> related errors a catch block for
	/// <b>mvIMPACT::acquire::EComponent</b> objects can be written to catch all <b>mvIMPACT::acquire::Component</b> related
	/// exceptions.
	class EComponent : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	protected:
		/// \brief Creates a new <b>EComponent</b> object.
		explicit EComponent(	/// \brief The error string.
								const std::string& errorString,
								/// \brief The error origin 
								const std::string& errorOrigin,
								/// \brief The error code.
								TPROPHANDLING_ERROR errorCode ) : EPropertyHandling(errorString, errorOrigin, errorCode) {}
		virtual ~EComponent() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NOT_A_LIST</b> error.
	class ENotAList : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENotAList( const std::string& componentname, const std::string& errorOrigin ) : EComponent("Component " + componentname + " is not a list. Unable to perform list operation", errorOrigin, PROPHANDLING_NOT_A_LIST) {}
		virtual ~ENotAList() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NOT_A_PROPERTY</b> error.
	class ENotAProperty : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENotAProperty( const std::string& componentname, const std::string& errorOrigin ) : EComponent("Component " + componentname + " is not a property. Unable to perform property operation", errorOrigin, PROPHANDLING_NOT_A_PROPERTY) {}
		virtual ~ENotAProperty() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NOT_A_METHOD</b> error.
	class ENotAMethod : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENotAMethod( const std::string& componentname, const std::string& errorOrigin ) : EComponent("Component " + componentname + " is not a method. Unable to perform function call operation", errorOrigin, PROPHANDLING_NOT_A_METHOD) {}
		virtual ~ENotAMethod() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NO_READ_RIGHTS</b> error.
	class ENoReadRights : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENoReadRights( const std::string& compname, const std::string& errorOrigin ) : EComponent("No read rights for component " + compname, errorOrigin, PROPHANDLING_NO_READ_RIGHTS) {}
		virtual ~ENoReadRights() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NO_WRITE_RIGHTS</b> error.
	class ENoWriteRights : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENoWriteRights( const std::string& compname, const std::string& errorOrigin ) : EComponent("No write rights for component " + compname, errorOrigin, PROPHANDLING_NO_WRITE_RIGHTS) {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NO_MODIFY_SIZE_RIGHTS</b> error.
	class ENoModifySizeRights : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENoModifySizeRights( const std::string& compname, const std::string& errorOrigin ) : EComponent("Component " + compname + "s size is fixed and therefore cannot be modified", errorOrigin, PROPHANDLING_NO_MODIFY_SIZE_RIGHTS) {}
		virtual ~ENoModifySizeRights() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INCOMPATIBLE_COMPONENTS</b> error.
	class EIncompatibleComponents : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EIncompatibleComponents( const std::string& name, const std::string& errorOrigin ) : EComponent("Component " + name + " has been compared with an incompatible type (might differ in components, size, etc.)" , errorOrigin, PROPHANDLING_INCOMPATIBLE_COMPONENTS) {}
		virtual ~EIncompatibleComponents() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_NO_USER_ALLOCATED_MEMORY</b> error.
	class ENoUserAllocatedMemory : public EComponent
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ENoUserAllocatedMemory( const std::string& name, const std::string& errorOrigin ) : EComponent("Component " + name + " is missing the cfUserAllocatedMemory flag for this operation" , errorOrigin, PROPHANDLING_NO_USER_ALLOCATED_MEMORY) {}
		virtual ~ENoUserAllocatedMemory() throw() {}
	};

	//-----------------------------------------------------------------------------
	// PROPERTY EXCEPTION CLASSES :
	//-----------------------------------------------------------------------------
	//-----------------------------------------------------------------------------
	/// \brief A base class for <b>mvIMPACT::acquire::Property</b> related exceptions from the property module
	///
	/// This exception object will never be raised in the code. It can't be constructed
	/// directly but to check for <b>mvIMPACT::acquire::Property</b> related errors a catch block for
	/// <b>mvIMPACT::acquire::EProperty</b> objects can be written to catch all <b>mvIMPACT::acquire::Property</b> related
	/// exceptions.
	class EProperty : public EComponent
	//-----------------------------------------------------------------------------
	{
	protected:
		/// \brief Creates a new <b>mvIMPACT::acquire::EProperty</b> object.
		explicit EProperty( /// \brief The error string.
							const std::string& errorString,
							/// \brief The error origin 
							const std::string& errorOrigin,
							/// \brief The error code.
							TPROPHANDLING_ERROR errorCode ) : EComponent(errorString, errorOrigin, errorCode) {}
		virtual ~EProperty() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INVALID_PROP_VALUE</b> error.
	class EInvalidValue : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EInvalidValue( const std::string& propname, const std::string& errorOrigin ) : EProperty("Invalid value for property " + propname, errorOrigin, PROPHANDLING_INVALID_PROP_VALUE) {}
		virtual ~EInvalidValue() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_PROP_VAL_ID_OUT_OF_BOUNDS</b> error.
	class EValIDOutOfBounds : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EValIDOutOfBounds( const std::string& propname, const std::string& errorOrigin ) : EProperty("Value ID out of bounds for " + propname, errorOrigin, PROPHANDLING_PROP_VAL_ID_OUT_OF_BOUNDS ) {}
		virtual ~EValIDOutOfBounds() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_PROP_TRANSLATION_TABLE_CORRUPTED</b> error.
	class ETranslationTableCorrupted : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ETranslationTableCorrupted( const std::string& propname, const std::string& errorOrigin ) : EProperty("The translation dictionary of " + propname + " is corrupted", errorOrigin, PROPHANDLING_PROP_TRANSLATION_TABLE_CORRUPTED ) {}
		virtual ~ETranslationTableCorrupted() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_PROP_TRANSLATION_TABLE_NOT_DEFINED</b> error.
	class ETranslationTableNotDefined : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ETranslationTableNotDefined( const std::string& propname, const std::string& errorOrigin ) : EProperty("Translation dictionary has not been defined for property " + propname, errorOrigin, PROPHANDLING_PROP_TRANSLATION_TABLE_NOT_DEFINED) {}
		virtual ~ETranslationTableNotDefined() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INVALID_PROP_VALUE_TYPE</b> error.
	class EInvalidValueType : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EInvalidValueType( const std::string& propname, const std::string& errorOrigin ) : EProperty("Property " + propname + " does not support this value type", errorOrigin, PROPHANDLING_INVALID_PROP_VALUE_TYPE) {}
		virtual ~EInvalidValueType() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_PROP_VAL_TOO_LARGE</b> error.
	class EValTooLarge : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EValTooLarge( const std::string& value, const std::string& maxValue, const std::string& propname, const std::string& errorOrigin ) : EProperty("The value " + value + " is higher then the maximum value(" + maxValue + ") for property " + propname, errorOrigin, PROPHANDLING_PROP_VAL_TOO_LARGE) {}
		virtual ~EValTooLarge() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_PROP_VAL_TOO_SMALL</b> error.
	class EValTooSmall : public EProperty
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EValTooSmall( const std::string& value, const std::string& minValue, const std::string& propname, const std::string& errorOrigin ) : EProperty("The value(" + value + ") is smaller then the minimum value(" + minValue + ") for property " + propname, errorOrigin, PROPHANDLING_PROP_VAL_TOO_SMALL) {}
		virtual ~EValTooSmall() throw() {}
	};

	//-----------------------------------------------------------------------------
	// PROPERTYLIST EXCEPTION CLASSES :
	//-----------------------------------------------------------------------------
	//-----------------------------------------------------------------------------
	/// \brief A base class for component list related exceptions from the property module.
	///
	/// This exception object will never be raised in the code. It can't be constructed
	/// directly but to check for component list related errors a catch block for
	/// <b>mvIMPACT::acquire::EPropertyList</b> objects can be written to catch all exceptions related
	/// to lists and list operations.
	class EPropertyList : public EComponent
	//-----------------------------------------------------------------------------
	{
	protected:
		/// \brief Creates a new <b>mvIMPACT::acquire::EPropertyList</b> object.
		explicit EPropertyList( /// \brief The error string.
								const std::string& errorString,
								/// \brief The error origin 
								const std::string& errorOrigin,
								/// \brief The error code.
								TPROPHANDLING_ERROR errorCode ) : EComponent(errorString, errorOrigin, errorCode) {}
		virtual ~EPropertyList() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_COMPONENT_NOT_FOUND</b> error.
	class EComponentNotFound : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EComponentNotFound( const std::string& compname, const std::string& listname, const std::string& errorOrigin ) : EPropertyList("Component " + compname + " is no member of list " + listname, errorOrigin, PROPHANDLING_COMPONENT_NOT_FOUND) {}
		virtual ~EComponentNotFound() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_LIST_ENTRY_OCCUPIED</b> error.
	class EListEntryOccupied : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EListEntryOccupied( const std::string& errorOrigin) : EPropertyList("List entry occupied already", errorOrigin, PROPHANDLING_LIST_ENTRY_OCCUPIED) {}
		virtual ~EListEntryOccupied() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_COMPONENT_ID_INVALID</b> error.
	class EComponentIDInvalid : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EComponentIDInvalid( const std::string& errorOrigin) : EPropertyList("Invalid component ID", errorOrigin, PROPHANDLING_COMPONENT_ID_INVALID) {}
		virtual ~EComponentIDInvalid() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_COMPONENT_ALREADY_REGISTERED</b> error.
	class EComponentAlreadyRegistered : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EComponentAlreadyRegistered( const std::string componentName, const std::string& errorOrigin ) : EPropertyList("A component with name " + componentName + " is already registered in this list", errorOrigin, PROPHANDLING_COMPONENT_ALREADY_REGISTERED) {}
		virtual ~EComponentAlreadyRegistered() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_LIST_ID_INVALID</b> error.
	class EInvalidListID : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EInvalidListID( const std::string& errorOrigin ) : EPropertyList("Invalid proplist ID", errorOrigin, PROPHANDLING_LIST_ID_INVALID) {}
		virtual ~EInvalidListID() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_LIST_CANT_ACCESS_DATA</b> error.
	class ECantAccessData : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ECantAccessData( const std::string& path, const std::string& errorOrigin ) : EPropertyList("Cannot access data from " + path, errorOrigin, PROPHANDLING_LIST_CANT_ACCESS_DATA) {}
		virtual ~ECantAccessData() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_CANT_REGISTER_COMPONENT</b> error.
	class ECantRegisterComponent : public EPropertyList
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ECantRegisterComponent( const std::string& errorOrigin ) : EPropertyList("Cannot register component in the current list.", errorOrigin, PROPHANDLING_CANT_REGISTER_COMPONENT) {}
		virtual ~ECantRegisterComponent() throw() {}
	};

	//-----------------------------------------------------------------------------
	// METHOD EXCEPTION CLASSES :
	//-----------------------------------------------------------------------------
	//-----------------------------------------------------------------------------
	/// \brief A base class for <b>mvIMPACT::acquire::Method</b> object related exceptions from the property module.
	///
	/// This exception object will never be raised in the code. It can't be constructed
	/// directly but to check for <b>mvIMPACT::acquire::Method</b> object related errors a catch block for
	/// <b>mvIMPACT::acquire::EMethod</b> objects can be written to catch only <b>Method</b> related exceptions.
	class EMethod : public EComponent
	//-----------------------------------------------------------------------------
	{
	protected:
		/// \brief Creates a new <b>mvIMPACT::acquire::EMethod</b> object.
		explicit EMethod(	/// \brief The error string.
							const std::string& errorString,
							/// \brief The error origin 
							const std::string& errorOrigin,
							/// \brief The error code.
							TPROPHANDLING_ERROR errorCode ) : EComponent(errorString, errorOrigin, errorCode) {}
		virtual ~EMethod() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_METHOD_PTR_INVALID</b> error.
	class EMethodPtrInvalid : public EMethod
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EMethodPtrInvalid( const std::string& methodname, const std::string& errorOrigin ) : EMethod("The function pointer for Method " + methodname + " is invalid", errorOrigin, PROPHANDLING_METHOD_PTR_INVALID) {}
		virtual ~EMethodPtrInvalid() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_METHOD_INVALID_PARAM_LIST</b> error.
	class EInvalidParameterList : public EMethod
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EInvalidParameterList( const std::string& errorOrigin ) : EMethod("The functions parameter list is invalid", errorOrigin, PROPHANDLING_METHOD_INVALID_PARAM_LIST) {}
		virtual ~EInvalidParameterList() throw() {}
	};

	//-----------------------------------------------------------------------------
	// PROPERTYHANDLING EXCEPTION CLASSES :
	//-----------------------------------------------------------------------------
	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_UNSUPPORTED_PARAMETER</b> error.
	class EUnsupportedParameter : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EUnsupportedParameter( const std::string& errorOrigin ) : EPropertyHandling("Unsupported parameter", errorOrigin, PROPHANDLING_UNSUPPORTED_PARAMETER) {}
		virtual ~EUnsupportedParameter() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_SIZE_MISMATCH</b> error.
	class ESizeMismatch : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		explicit ESizeMismatch( const std::string& errorString, const std::string& errorOrigin ) : EPropertyHandling(errorString, errorOrigin, PROPHANDLING_SIZE_MISMATCH) {}
		virtual ~ESizeMismatch() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_IMPLEMENTATION_MISSING</b> error.
	class EImplementationMissing : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		explicit EImplementationMissing( const std::string& errorOrigin ) : EPropertyHandling("This feature has not been implemented so far", errorOrigin, PROPHANDLING_IMPLEMENTATION_MISSING) {}
		virtual ~EImplementationMissing() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INVALID_INPUT_PARAMETER</b> error.
	class EInvalidInputParameter : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		EInvalidInputParameter( const std::string& errorOrigin ) : EPropertyHandling("One or more of the input parameters are invalid ( unassigned pointers? )", errorOrigin, PROPHANDLING_INVALID_INPUT_PARAMETER) {}
		virtual ~EInvalidInputParameter() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INPUT_BUFFER_TOO_SMALL</b> error.
	class EInputBufferTooSmall : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		EInputBufferTooSmall( const std::string& errorOrigin ) : EPropertyHandling("The user supplied input buffer was too small for the result", errorOrigin, PROPHANDLING_INPUT_BUFFER_TOO_SMALL) {}
		virtual ~EInputBufferTooSmall() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_WRONG_PARAM_COUNT</b> error.
	class EWrongParamCount : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		EWrongParamCount( const std::string& errorOrigin ) : EPropertyHandling("Wrong parameter count", errorOrigin, PROPHANDLING_WRONG_PARAM_COUNT) {}
		virtual ~EWrongParamCount() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_UNSUPPORTED_OPERATION</b> error.
	class EUnsupportedOperation : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		EUnsupportedOperation( const std::string& errorOrigin ) : EPropertyHandling("This component does not support this operation", errorOrigin, PROPHANDLING_UNSUPPORTED_OPERATION) {}
		virtual ~EUnsupportedOperation() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_CANT_SERIALIZE_DATA</b> error.
	class ECantSerializeData : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		ECantSerializeData( const std::string& listname, const std::string& errorOrigin ) : EPropertyHandling("No serialize rights for list " + listname, errorOrigin, PROPHANDLING_CANT_SERIALIZE_DATA) {}
		virtual ~ECantSerializeData() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_INVALID_FILE_CONTENT</b> error.
	class EInvalidFileContent : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		EInvalidFileContent( const std::string& path, const std::string& errorOrigin ) : EPropertyHandling("The file " + path + " does not contain valid data for this operation", errorOrigin, PROPHANDLING_INVALID_FILE_CONTENT) {}
		virtual ~EInvalidFileContent() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief An exception thrown in case of a <b>mvIMPACT::acquire::TPROPHANDLING_ERROR::PROPHANDLING_CANT_ALLOCATE_LIST</b> error.
	class ECantAllocateNewList : public EPropertyHandling
	//-----------------------------------------------------------------------------
	{
	public:
		ECantAllocateNewList( const std::string& errorOrigin ) : EPropertyHandling("Cannot allocate a new list until an old one has been deleted.", errorOrigin, PROPHANDLING_CANT_ALLOCATE_LIST) {}
		virtual ~ECantAllocateNewList() throw() {}
	};

	//-----------------------------------------------------------------------------
	/// \brief A factory class to raise mvIMPACT acquire related exceptions
	///
	/// This class contains a collection of static member functions that are used inside the
	/// interface to raise the appropriate exception in case of an error
	class ExceptionFactory
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Raises and exception from an error code, it's origin, a string with additional information and an
		/// optional component handle
		static void raiseException(	/// The name of the function this exception was raised from
									const char* pFunctionName, 
									/// The line number in the source this exception was raised from
									int lineNumber, 
									/// The error code
									int errorCode, 
									/// A handle to an object
									HOBJ objectHandle = INVALID_ID,
									/// A string with additional information
									const std::string& additionalInfo = "" );
	};
#endif // #ifndef WRAP_DOTNET

//-----------------------------------------------------------------------------
/// \brief A base class to implement access to internal driver objects.
///
/// Instances of this class can't be constructed directly.
class ComponentAccess
//-----------------------------------------------------------------------------
{
	friend class ComponentLocatorBase;
protected:
	/// \brief An internal constant that defines by which factor dynamic buffers will grow when
	/// the current size is not sufficient.
	enum { BUFFER_INCREMENT_FACTOR = 6 };
	/// \brief A unique identifier for the internal driver object referenced by this instance
	/// of <b>mvIMPACT::acquire::ComponentAccess</b>
	HOBJ m_hObj;
	/// \brief A helper function to query certain component related string parameters.
	///
	/// This function might throw an exception, if an invalid parameter has been queried.
	/// \return A string containing the data to be queried.
	std::string	compGetStringParam(	/// The type of the parameter to read
									TOBJ_StringQuery query,
									/// An additional parameter
									int param1 = 0,
									/// An additional parameter
									int param2 = 0 ) const
	{
		char* pStr = 0;
		TPROPHANDLING_ERROR result;
		std::string resultString;
		result = OBJ_GetSWithInplaceConstruction( m_hObj, query, &pStr, stringAllocator, param1, param2 );
		if( pStr )
		{
			resultString = std::string(pStr);
		}
		delete [] pStr;
		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return resultString;
	}
	/// \brief Constructs a new <b>mvIMPACT::acquire::ComponentAccess</b> object to a driver object.
	explicit ComponentAccess( HOBJ hObj ) : m_hObj(hObj)
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_CheckHandle( m_hObj, hcmOwnerList ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, hObj );
		}
	}
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::ComponentAccess</b> object.
	explicit ComponentAccess( void ) : m_hObj(INVALID_ID) {}
	/// \brief An internal helper function for fast string allocation.
	static char* stringAllocator( const char* pBuf, size_t reqBufSize )
	{
		char* pStr = new char[reqBufSize];
		return strcpy( pStr, pBuf );
	}
public:
	virtual ~ComponentAccess( void ) {}
#ifndef WRAP_PYTHON
	/// \brief Allows implicit conversion to a HOBJ.
	operator HOBJ() const { return m_hObj; }
#endif // #ifndef WRAP_PYTHON  (In Python, be explicit: use method hObj(); Python variables lack a type specifier, so a conversion operator is useless for variable assignment anyhow)
	/// \brief Returns the current changed counter for the component referenced by this object.
	///
	/// This changed counter is incremented internally each time the component is modified.
	/// To check if this component has been modified since the last time, this check has been
	/// performed, keep track of the last return value of this function an compare
	/// it with the new value. This can be helpful e.g. to keep a GUI up to date. The value returned
	/// by this function will always be larger or equal then the value returned by
	/// <b>mvIMPACT::acquire::ComponentAccess::changedCounterAttr</b> (except in case of a 
	/// wrap around) when called at the same time for the same object as it's always incremented
	/// when the component has been modified in
	/// any way while the latter one will only be incremented if the attributes (e.g. the 
	/// flags) but <b>NOT</b> if e.g. the value(s) of a property has been modified.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLE:</b>
	///
	///\code
	/// //-----------------------------------------------------------------------------
	/// struct ComponentRef
	/// //-----------------------------------------------------------------------------
	/// {
	///   mvIMPACT::acquire::Component* m_pc;
	///   unsigned int m_lastChangedCount;
	///   ComponentRef( mvIMPACT::acquire::Component* pc ) : m_pc(pc), m_lastChangedCount(0) {}
	/// };
	/// 
	/// //-----------------------------------------------------------------------------
	/// void fn( ComponentRef& cr )
	/// //-----------------------------------------------------------------------------
	/// {
	///   if( cr.m_pc )
	///   {
	///     unsigned int currentChangedCount = cr.m_pc->changedCounter();
	///     if( currentChangedCount != cr.m_lastChangedCount ) )
	///     {
	///       // something has happened since the last check.
	///       doWhatNeedsToBeDone();
	///       // and remember the current changed counter
	///       cr.m_lastChangedCount = currentChangedCount;
	///     }
	///   }
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	/// \return The current changed counter of this object.
	unsigned int changedCounter( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int changedCounter;
		if( ( result = OBJ_GetChangedCounter( m_hObj, &changedCounter ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return changedCounter;
	}
	/// \brief Returns the current attribute changed counter for the component referenced by this object.
	///
	/// This changed counter is incremented internally each time the components attributes have been modified.
	/// To check if this components attributes have been modified since the last time, this check has been
	/// performed, keep track of the last return value of this function an compare
	/// it with the new value. This can be helpful e.g. to keep a GUI up to date.
	///
	/// \note
	/// Attributes changes are e.g. a modification to a properties translation dictionary,
	/// but <b>NOT</b> a properties value. Because of this the value returned by this function
	/// will always be less or equal then the value returned by the function
	/// <b>mvIMPACT::acquire::ComponentAccess::changedCounter</b> (except in case of a 
	/// wrap around) when called at the same time for the same object.
	/// \sa <b>mvIMPACT::acquire::ComponentAccess::changedCounter</b>
	/// \return The current attributes changed counter of this object.
	unsigned int changedCounterAttr( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int changedCounter;
		if( ( result = OBJ_GetChangedCounterAttr( m_hObj, &changedCounter ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return changedCounter;
	}
	/// \brief Returns a unique identifier for the component referenced by this object.
	/// \return A unique identifier for the component referenced by this object.
	HOBJ hObj( void ) const { return m_hObj; }
	/// \brief Returns the name of the component referenced by this object.
	/// \return The name of the component referenced by this object.
	std::string name( void ) const { return compGetStringParam( sqObjName ); }
};

//-----------------------------------------------------------------------------
/// \brief A base class to implement access to internal driver components.
///
/// Objects of this class can be constructed directly even if nothing is known about the type
/// of driver object we are referring to. This class acts as a base class to provide
/// access to internal properties, methods and component lists offered by the driver.
class Component : public ComponentAccess
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new access object to a driver object.
	explicit Component( HOBJ hObj ) : ComponentAccess(hObj) {}
	/// \brief Constructs a new unbound access object.
	explicit Component( void ) {}
	/// \brief Returns a string containing general information about the component referenced by this object.
	/// \return A string containing general information about the component referenced by this object.
	std::string docString( void ) const { return compGetStringParam( sqObjDocString ); }
	/// \brief Returns the flags associated with this component.
	/// \return The flags associated with this component.
	TComponentFlag flags( void ) const
	{
		TPROPHANDLING_ERROR result;
		TComponentFlag flags;
		if( ( result = OBJ_GetFlags( m_hObj, &flags ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return flags;
	}
	/// \brief Returns the flags associated with this component as a string.
	/// \return The flags associated with this component as a string.
	std::string flagsAsString(	/// A user definable string to separate the individual flags.
								/// 
								/// The default value is ' | ' resulting in the string to look e.g.
								/// like this: <b>'cfWriteAccess | cfReadAccess'</b>
								const std::string& separator = " | " ) const
	{
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pBuf = new char[bufSize];
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		while( ( result = OBJ_GetFlagsS( m_hObj, separator.c_str(), pBuf, bufSize ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			delete [] pBuf;
			bufSize *= BUFFER_INCREMENT_FACTOR;
			pBuf = new char[bufSize];
		}
		std::string value(pBuf);
		delete [] pBuf;
		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return value;
	}
	/// \brief Checks if this component is currently referencing the default for this component.
	///
	/// This function will return true for derived components, that have not been modified only.
	/// \return
	/// - true if the component is currently set to its default value
	/// - false otherwise.
	bool isDefault( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int isDefault;
		if( ( result = OBJ_IsDefault( m_hObj, &isDefault ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return isDefault != 0;
	}
	/// \brief Checks if this component is of type <b>mvIMPACT::acquire::ComponentList</b>.
	/// \return
	/// - true if the component references a list
	/// - false otherwise
	bool isList( void ) const { return ( type() & ctList ) != 0; }
	/// \brief Checks if this component is of type <b>mvIMPACT::acquire::Method</b>.
	/// \return
	/// - true if the component references a method
	/// - false otherwise
	bool isMeth( void ) const { return ( type() & ctMeth ) != 0; }
	/// \brief Checks if this component is of type <b>mvIMPACT::acquire::Property</b> or a derived type.
	/// \return
	/// - true if the component references a property
	/// - false otherwise
	bool isProp( void ) const { return ( type() & ctProp ) != 0; }
	/// \brief Checks if the internal component referenced by this object is still valid.
	///
	/// This function can be used to verify whether a referenced component
	/// is still valid or not. When e.g. referencing a driver property after
	/// <b>mvIMPACT::acquire::Device::close</b> has been called this function would return false.
	/// Calling any other function that tries to access the referenced component
	/// in that case would raise an exception.
	/// \return
	/// - true if this object currently references a valid component
	/// - false otherwise.
	bool isValid( void ) const { return OBJ_CheckHandle( m_hObj, hcmFull ) == PROPHANDLING_NO_ERROR; }
	/// \brief Checks if the component is currently shadowed due to a settings made elsewhere
	/// or not.
	///
	/// Settings made components might affect the behaviour of others. For example
	/// an activated automatic gain control might shadow the value written to the
	/// gain property by the user, as the gain is calculated internally. In order to
	/// check if modifying the actual component will affect the behaviour of the
	/// system this function might be used. When is returns \a true, the <b>mvIMPACT::acquire::Component</b>
	/// will have an impact on the system.
	///
	/// This is what is called visibility. The user still might modify or read the
	/// current <b>mvIMPACT::acquire::Component</b> when it's not visible however the actual data will
	/// be used only if the <b>Component</b> is visible (<b>mvIMPACT::acquire::cfInvisible</b>
	/// must <b>NOT</b> be set).
	///
	/// The visibility of a <b>mvIMPACT::acquire::Component</b> object will change only if other
	/// <b>mvIMPACT::acquire::Component</b> objects are modified and <b>NEVER</b> when a program
	/// runs but does not change any <b>mvIMPACT::acquire::Component</b>.
	bool isVisible( void ) const { return ( flags() & cfInvisible ) == 0; }
	/// \brief Checks if the caller has write/modify access to the component.
	/// \return
	/// - true if the caller is allowed to call write/modify operation for this component.
	/// - false otherwise.
	bool isWriteable( void ) const { return ( flags() & cfWriteAccess ) != 0; }
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Restores the default for the referenced component.
	///
	/// Calling this function will restore the default value for the
	/// component referenced by this object.
	///
	/// If this function is called for an object of type <b>mvIMPACT::acquire::ComponentList</b>
	/// every component in that list is restored to the default value.
	///
	/// \note The caller must have the right to modify the component. Otherwise
	/// an exception will be thrown.
	void
#else
	/// \brief Restores the default for the referenced component.
	///
	/// Calling this function will restore the default value for the
	/// component referenced by this object.
	///
	/// If this function is called for an object of type <b>mvIMPACT::acquire::ComponentList</b>
	/// every component in that list is restored to the default value.
	///
	/// \note The caller must have the right to modify the component. Otherwise
	/// an exception will be thrown.
	///
	/// \return A const reference to the component.
	const Component&
#endif
						restoreDefault	( void ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_RestoreDefault( m_hObj ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
	/// \brief Returns the type of the referenced component.
	/// \return The type of the referenced component.
	TComponentType type( void ) const
	{
		TPROPHANDLING_ERROR result;
		TComponentType type;
		if( ( result = OBJ_GetType( m_hObj, &type ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return type;
	}
	/// \brief Returns the type of the referenced component as a string.
	/// \return The type of the referenced component as a string.
	std::string typeAsString( void ) const
	{
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pBuf = new char[bufSize];
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		while( ( result = OBJ_GetTypeS( m_hObj, pBuf, bufSize ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			delete [] pBuf;
			bufSize *= BUFFER_INCREMENT_FACTOR;
			pBuf = new char[bufSize];
		}
		std::string value(pBuf);
		delete [] pBuf;
		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return value;
	}
};

//-----------------------------------------------------------------------------
/// \brief A base class to locate components within the driver.
/// 
/// Every driver will offer a set of properties, methods and component lists.
/// <b>mvIMPACT::acquire::Property</b> objects contain data such as the current gain in dB, the state of a
/// digital input, etc.. <b>mvIMPACT::acquire::Method</b> objects can be executed like a normal function and
/// <b>mvIMPACT::acquire::ComponentList</b> objects are used to group certain
/// objects together to form a logical unit.
///
/// When it's neccessary to locate one or more of these objects without knowing
/// exactly where to look for them this locator class can be used to look for the component.
class ComponentLocatorBase : public ComponentAccess
//-----------------------------------------------------------------------------
{
	HLIST m_searchbase;
public:
	/// \brief Constructs a new unbound locator.
	explicit ComponentLocatorBase() {}
	/// \brief Constructs a new bound to the specified base list locator.
	explicit ComponentLocatorBase(	/// A unique identifier to the base list from where to start to search for
										/// the search base.
										HLIST baselist ) : ComponentAccess(baselist), m_searchbase(baselist) {}
	/// \brief Constructs a new locator and searches the search base list.
	explicit ComponentLocatorBase(	/// A unique identifier to the base list from where to start to search for
									/// the search base.
									HLIST baselist,
									/// The name or path ('/' separated) to the search base.
									const std::string& pathToSearchBase ) : ComponentAccess(baselist)
	{
		bindSearchBase( baselist, pathToSearchBase );
	}
	/// \brief Binds an access object to an internal driver object.
	///
	/// \return
	/// - true if successful
	/// - false otherwise. In case false is returned by this function the component could not
	/// be bound, which means subsequent calls using \a access will fail or throw an exception.
	bool bindComponent(	/// The access object to bind to the driver object.
						Component& access,
						/// The name of the driver object to locate.
						const std::string& name,
						/// Flags defining how to search for the component.
						int searchmode = 0,
						/// The maximum number of sub list levels to search for the component.
						int maxSearchDepth = INT_MAX ) const
	{
		access.m_hObj = findComponent( name, searchmode, maxSearchDepth );
		return access.isValid();
	}
	/// \brief Assign a new search base to the locator.
	///
	/// This new search base will be search starting from the base list specified.
	/// \return The unique identifier of the new search base.
	HLIST bindSearchBase(	/// A unique identifier for the base list used to start searching the search base.
							HLIST baselist,
							/// The name or path to the search base.
							const std::string& pathToSearchBase = "" )
	{
		if( pathToSearchBase.empty() )
		{
			m_hObj = m_searchbase = baselist;
		}
		else
		{
			TPROPHANDLING_ERROR result;
			HLIST hList;
			if( ( result = OBJ_GetHandleEx( baselist, pathToSearchBase.c_str(), &hList, smIgnoreProperties | smIgnoreMethods, 0 ) ) != PROPHANDLING_NO_ERROR )
			{
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
			}
			m_hObj = baselist;
			m_searchbase = hList;
		}
		return m_searchbase;
	}
	/// \brief Tries to locate a certain component in a hierarchy of components
	/// \return A unique identifier to the component if found or <b>mvIMPACT::acquire::INVALID_ID</b> if the component couldn't
	/// be found.
	HOBJ findComponent(	/// The name of the component to search for.
						const std::string& name,
						/// Flags defining how to search for the component.
						int searchmode = 0,
						/// The maximum number of sub list levels to search for the component.
						int maxSearchDepth = INT_MAX ) const
	{
		TPROPHANDLING_ERROR result;
		HOBJ hObj;
		if( ( result = OBJ_GetHandleEx( m_searchbase, name.c_str(), &hObj, searchmode, maxSearchDepth ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return hObj;
	}
	/// \brief Returns the unique identifier of the base list from where to start searching for a component.
	/// \return The unique identifier of the base list from where searching for a component will start currently.
	HLIST searchbase_id( void ) const { return m_searchbase; }
};

//-----------------------------------------------------------------------------
/// \brief A class to locate components within the driver.
/// 
/// Every driver will offer a set of properties, methods and component lists.
/// <b>mvIMPACT::acquire::Property</b> objects contain data such as the current gain in dB, the state of a
/// digital input, etc.. <b>mvIMPACT::acquire::Method</b> objects can be executed like a normal function and
/// <b>mvIMPACT::acquire::ComponentList</b> objects are used to group certain
/// objects together to form a logical unit.
///
/// When it's neccessary to locate one or more of these objects without knowing
/// exactly where to look for them this locator class can be used to look for the component.
class ComponentLocator : public ComponentLocatorBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new unbound locator.
	explicit ComponentLocator() : ComponentLocatorBase() {}
	/// \brief Constructs a new bound to the specified base list locator.
	explicit ComponentLocator(	/// A unique identifier to the base list from where to start to search for
								/// the search base.
								HLIST baselist ) : ComponentLocatorBase(baselist) {}
	/// \brief Constructs a new locator and searches the search base list.
	explicit ComponentLocator(	/// A unique identifier to the base list from where to start to search for
								/// the search base.
								HLIST baselist,
								/// The name or path ('/' separated) to the search base.
								const std::string& pathToSearchBase ) : ComponentLocatorBase(baselist, pathToSearchBase) {}
};

//-----------------------------------------------------------------------------
/// \brief A class to iterate over component lists.
///
/// This object can be used to navigate through component lists of
/// unknown content.
///
/// Consider the following structure:
///
///\code
/// LA
/// |-LB
/// |-LC
/// |  |-PE
/// |  |-PF
/// |-PD
///\endcode
///
/// Where the prefix 'L' means, that this is a list, 'P' that this is a property.
/// Assuming that we have and iterator referencing list 'C', calling <b>mvIMPACT::acquire::ComponentIterator::firstChild</b>
/// e.g. would return a new iterator referencing object 'PE', while calling <b>mvIMPACT::acquire::ComponentIterator::nextSibling</b>
/// would have returned a reference to 'PD' and <b>mvIMPACT::acquire::ComponentIterator::parent</b> would have
/// returned a reference to object 'LA'.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLE 1:</b>
///
/// A new <b>mvIMPACT::acquire::ComponentIterator</b> is created with the \a ID of list 'C':
///\code
/// ComponentIterator it(ID_of_list_C);
/// it = it.firstChild(); // now we are referencing 'PE'
/// it = it.nextSibling(); // moves to 'PF'
/// it = it.firstSibling(); // moves back to PE'
/// it = it.parent();		// we are referencing 'LC' again
///\endcode
///
/// <b>EXAMPLE 2:</b>
///
/// Iterate over a complete list including sub lists. This will result in a list
/// of all lists and properties that reside in the list the iterator currently
/// is moving through to be written to the standard output. The name of the component
/// and every parent component will be printed into the standard output:
///
///\code
/// //-----------------------------------------------------------------------------
/// void ParseList( ComponentIterator iter, const string& path = "" )
/// //-----------------------------------------------------------------------------
/// {
///   while( iter.isValid() )
///   {
///     if( iter.isVisible() )
///     {
///       if( iter.isList() )
///       {
///         // do some list specific stuff
///         cout << "List     " << path << iter.name() << "/" << endl;
///         // move down into the list and append its name to the path
///         ParseList( iter.firstChild(), path + iter.name() + "/" );
///       }
///       else if( iter.isProp() )
///       {
///         // do property specific stuff e.g. read the value
///         Property prop(iter);
///         cout << "Property " << path << prop.name() << "(value(s): ";
///         unsigned int valCount = prop.valCount();
///         for( unsigned int i=0; i<valCount; i++ )
///         {
///           cout << prop.readS();
///           if( i < valCount - 1 )
///           {
///             cout << ", ";
///           }
///         }
///         cout << ")" << endl;
///       }
///     }
///     ++iter;
///   }
/// }
///
/// //-----------------------------------------------------------------------------
/// int main(int argc, char* argv[])
/// //-----------------------------------------------------------------------------
/// {
///   ComponentList baselist;
///   // ....
///   ComponentIterator it(baselist);
///   ParseList(it);
///   // ....
///   return 0;
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cs.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cs.html
/// <b>EXAMPLE 1:</b>
///
/// A new <b>mvIMPACT::acquire::ComponentIterator</b> is created with the \a ID of list 'C':
///\code
/// ComponentIterator it = new ComponentIterator(ID_of_list_C);
/// it = it.firstChild();   // now we are referencing 'PE'
/// it = it.nextSibling();  // moves to 'PF'
/// it = it.firstSibling(); // moves back to PE'
/// it = it.parent();       // we are referencing 'LC' again
///\endcode
///
/// <b>EXAMPLE 2:</b>
///
/// Iterate over a complete list including sub lists. This will result in a list
/// of all lists and properties that reside in the list the iterator currently
/// is moving through to be written to the standard output. The name of the component
/// and every parent component will be printed into the standard output:
///
///\code
/// static void outputPropData( Property prop )
/// {
///   // do property specific stuff e.g. read the value
///   Console.Write( prop.name() + "(value(s): " );
///   uint valCount = prop.valCount();
///   for( uint i=0; i<valCount; i++ )
///   {
///     Console.Write( prop.readS() );
///     if( i < valCount - 1 )
///     {
///       Console.Write( ", " );
///     }
///   }
///   Console.WriteLine( ")" );
/// }
/// 
/// static void ParseList( ComponentIterator iter, String path )
/// {
///   while( iter.valid )
///   {
///     if( iter.visible )
///     {
///       if( iter.list )
///       {
///         // do some list specific stuff
///         Console.WriteLine( "List     " + path + iter.name() );
///         // move down into the list and append its name to the path
///         ParseList( iter.firstChild(), path + iter.name() + "/" );
///       }
///       else if( iter.prop )
///       {
///         Console.Write( "Property " );
///         Console.Write( path );
///         TComponentType type = iter.type();
///         if( type == TComponentType.ctPropInt )
///         {
///           outputPropData( new PropertyI(iter.hObj()) );
///         }
///         else if( type == TComponentType.ctPropFloat )
///         {
///           outputPropData( new PropertyF(iter.hObj()) );
///         }
///         else if( type == TComponentType.ctPropString )
///         {
///           outputPropData( new PropertyS(iter.hObj()) );
///         }
///         else
///         {
///           Console.WriteLine( "This property(" + iter.name() + ") is currently unsupported under .NET" );
///         }
///       }
///     }
///     iter.nextSibling();
///   }
/// }
///
/// [STAThread]
/// static void Main(string[] args)
/// {
///   try
///   {
///     ComponentList baselist = new ComponentList;
///     // ...
///     ComponentIterator it = new ComponentIterator(baselist);
///     ParseList(it);
///     // ...
///   }
///   catch(ImpactException e)
///   {
///     Console.WriteLine(e.Message);
///   }
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
class ComponentIterator : public Component
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::ComponentIterator</b> object.
	explicit ComponentIterator( HOBJ hObj ) : Component(hObj) {}
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::ComponentIterator</b> object.
	explicit ComponentIterator( void ) {}
#ifndef WRAP_PYTHON
	/// \brief Moves to the next sibling.
	///
	/// \return A new iterator object
	ComponentIterator operator++( void )
	{
		TPROPHANDLING_ERROR result;
		HOBJ nextSibling;
		if( ( result = OBJ_GetNextSibling( m_hObj, &nextSibling ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		m_hObj = nextSibling;
		return *this;
	}
	/// \brief Moves to the next sibling.
	///
	/// \return A new iterator object
	ComponentIterator operator++( int  )
	{
		ComponentIterator temp( *this );
		++*this;
		return temp;
	}
#endif // #ifndef WRAP_PYTHON  (in Pyhton, use nextSibling(); Python has no ++ operator)
	/// \brief Moves to the first sibling.
	///
	/// \return A new iterator object
	ComponentIterator firstSibling( void ) const
	{
		TPROPHANDLING_ERROR result;
		HOBJ firstSibling;
		if( ( result = OBJ_GetFirstSibling( m_hObj, &firstSibling ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return ComponentIterator( firstSibling );
	}
	/// \brief Moves to the next sibling.
	///
	/// \return A new iterator object
	ComponentIterator nextSibling( void ) { return ++*this; }
	/// \brief Moves to the first child (moves down one level).
	///
	/// \return A new iterator object
	ComponentIterator firstChild( void ) const
	{
		TPROPHANDLING_ERROR result;
		HOBJ firstChild;
		if( ( result = OBJ_GetFirstChild( m_hObj, &firstChild ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return ComponentIterator( firstChild );
	}
	/// \brief Moves to the parent component (moves up one level).
	///
	/// \return A new iterator object
	ComponentIterator parent( void ) const
	{
		TPROPHANDLING_ERROR result;
		HOBJ parent;
		if( ( result = OBJ_GetParent( m_hObj, &parent ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return ComponentIterator( parent );
	}
};

//-----------------------------------------------------------------------------
/// \brief A class to provide access to component lists.
///
/// This class provides access to internal component lists of the driver.
class ComponentList : public Component
//-----------------------------------------------------------------------------
{
public:
    /// \brief Constructs a new <b>mvIMPACT::acquire::ComponentList</b> object.
	explicit		ComponentList( HLIST hList ) : Component(hList) {}
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::ComponentList</b> object.
	explicit		ComponentList() {}
	/// brief Returns The number of component entries in the referenced list.
	/// \return The number of component entries in the referenced list.
	unsigned int size( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int size;
		if( ( result = OBJ_GetElementCount( m_hObj, &size ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return size;
	}
	/// \brief Returns a string containing information about what's in this list.
	///
	/// This string might not be defined by every list but in any case this function
	/// will return a valid string. However this string might be empty.
	std::string	contentDescriptor( void ) const { return compGetStringParam( sqListContentDescriptor ); }
};

//-----------------------------------------------------------------------------
/// \brief A class to call arbitrary driver functions.
///
/// Normally all functions needed by the user and offered by the driver will be
/// provided as a normal function somewhere within this interface. In rare cases
/// however it might be necessary to call a function, which hasn't been implemented
/// in this interface. In that case this class will serve as a backdoor.
class Method : public Component
//-----------------------------------------------------------------------------
{
	// do not allow assignments
	Method&			operator=( const Method& );
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::Method</b> object.
	explicit		Method( HOBJ hObj ) : Component(hObj) {}
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::Method</b> object.
	explicit		Method() {}
	/// \brief Calls the underlying driver function.
	///
	/// This function can be used to call any driver function which is registered
	/// for the device it is called for. To call a function successfully the parameters
	/// passed to the function must match the parameters expected by the function.
	///
	/// All parameters are passed as a single string, which is parsed with respect to the
	/// given delimiter characters internally.
	///
	/// To find out which kind of parameters are expected by the function use
	/// the function <b>mvIMPACT::acquire::Method::paramList() const</b>.
	///
	/// floating point values can be passed either with a '.' or a ',' acting as the
	/// decimal point.
	///
	/// 'empty' strings can be passed as a single underline('_').
	///
	/// \note
	/// The characters '.', ',' and '_' can't be used as delimiters.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLES:</b>
	///
	///\code
	/// // call a function expecting a string and a float 
	/// // value parameters separated by spaces
	/// meth.call( "stringParam 3,14" );
	/// // call of a function expecting 2 integers an a string
	/// // where an empty string shall be passed
	/// // parameters are separated by '%'
	/// meth.call( "1000%666%_", "%" );
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	/// \return An integer value.
	int	call(	/// The parameters to be passed to the function as a single string
				const std::string& params,
				/// A string containing valid delimiter characters for the parameter string
				const std::string& delimiters = " " ) const
	{
		TPROPHANDLING_ERROR result;
		int retval;
		if( ( result = OBJ_Execute( m_hObj, params.c_str(), delimiters.c_str(), &retval ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return retval;
	}
	/// \brief Returns the parameter list of the methods as a string.
	///
	/// This function returns a string containing one character for each parameter this <b>mvIMPACT::acquire::Method</b>
	/// object expects and one for the return type of the function call.
	///
	/// The first character is the return type of the function all others are parameters. void functions
	/// don't specify parameters.
	///
	/// The characters have the following meaning:
	/// - i specifies an integer value
	/// - s specifies a pointer to a C-string
	/// - f specifies a float value
	/// - p specifies a pointer value
	/// - v specifies a void return value
	///
	/// <b>EXAMPLES:</b>
	///
	/// - 'v': This is a function returning nothing (void). It expects no parameters.
	/// - 'viis': This is a function returning nothing (void). It expects 2 integer values
	/// and one pointer to a C-string.
	/// - 'if': This function returns an integer value and expects a float value.
	/// \return The parameter list of the method as a string.
	std::string paramList( void ) const { return compGetStringParam( sqMethParamString ); }
};

//-----------------------------------------------------------------------------
/// \brief Defines valid limits which can be queried for a <b>mvIMPACT::acquire::Property</b> object.
enum TPropertyLimits
//-----------------------------------------------------------------------------
{
	/// \brief Set/Get the maximum value for this <b>mvIMPACT::acquire::Property</b>.
	///
	/// Pass this as the index to set or get the maximum number of values this property 
	/// can store with a call to the <b>mvIMPACT::acquire::Property</b>s corresponding 
	/// ::read or ::write.
	plMaxValue = PROP_MAX_VAL,
	/// \brief Set/Get the minimum value for this <b>mvIMPACT::acquire::Property</b>.
	///
	/// Pass this as the index to set or get the maximum number of values this property 
	/// can store with a call to the <b>mvIMPACT::acquire::Property</b>s corresponding 
	/// ::read or ::write.
	plMinValue = PROP_MIN_VAL,
	/// \brief Set/Get the step width value for this <b>mvIMPACT::acquire::Property</b>.
	///
	/// Pass this as the index to set or get the maximum number of values this property 
	/// can store with a call to the <b>mvIMPACT::acquire::Property</b>s corresponding 
	/// ::read or ::write.
	plStepWidth = PROP_STEP_WIDTH
};

//-----------------------------------------------------------------------------
/// \brief A base class for properties.
///
/// A property can be used to represent certain values like e.g. the input channel
/// of a device. Depending on the way the property has been created it is either
/// possible to read and write data to it or ( when the <b>mvIMPACT::acquire::cfWriteAccess</b> flag is <b>NOT</b> set )
/// just to read the data. In rare cases it might also be possible that the user is
/// is not allowed to read the data of a property. To find out what you are allowed
/// to do with a property or any other component the function <b>mvIMPACT::acquire::Component::flags() const</b>
/// can be called.
///
/// A property can contain either a single value or an array of values of the same
/// type (e.g. 4 integer values could be used to represent a property call 'Rectangle'.
/// It can even (if the <b>mvIMPACT::acquire::cfFixedSize</b> flag is not set) contain
/// a different number of values all the time its data is queried. E.g. for a property
/// 'searchresults' each time some function is called which writes its results to this
/// property the property could contain a different number of integer values afterwards.
///
/// Every properties value can be read and written either as string or by it actual value type.
/// So you can either assign the value of an integer property by using the standard 'write' function
/// that accepts the value to be the type of the property or the function <b>mvIMPACT::acquire::Property::writeS</b>
/// can be used to set the property via a string containing the new value.
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
///\code
/// PropertyI prop(hObj);
/// prop.writeS("5"); // string assignment
/// prop.write(5); // integer assignment
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///
/// In addition to that \e float and \e int Properties might define a translation dictionary. This cannot be
/// done by the user, but the user can work with the dictionary afterwards. A translation
/// dictionary is a table which maps strings to certain values (e.g. integers).
///
/// The translation dictionary serves two purposes: Once it has been defined this property can only be
/// assigned values ( which can either be passed as a string or as the actual value )
/// which are contained in the translation table. Thus this makes it very easy to restrict
/// a certain property to a fixed number of values, which can be assigned to it.
/// Properties that have a translation dictionary will typically be defined by declaring
/// a template instance with the type of the enumeration.
///
/// The second benefit from a translation dictionary is, that certain values can be assigned
/// a meaningful description via its translation.
/// When a translation table has been defined either the string translation can be used to
/// assign its value or its actual data type. A float property e.g. might define a translation
/// table like this: 'Auto -> 0', 'auto -> 1', 'OnLowLevel -> 2'. Now to set this property
/// to use the 'on low level' trigger mode this can be done by calling one of the 'write' functions.
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
///\code
/// PropertyICameraTriggerMode& prop = getPropertyFromSomewhere();
/// prop.writeS("OnLowLevel"); // set value via the translation string
/// prop.write(ctmOnLowLevel); // set value via enum type
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///
/// This can also be extremely useful to populate combo boxes for GUI applications.
///
/// Float and int properties can also define certain constants like a max. value or
/// a min. value. If a property does define such values it can't be assigned values
/// which do not lie within the defined range. To find out if constants are defined
/// The user can call the function <b>mvIMPACT::acquire::Property::isConstDefined</b>.
/// To query to actual value of this constant the 'normal' function (e.g. <b>mvIMPACT::acquire::PropertyF::read( int index )</b>)
/// can be used, where \a index must be set to a constant value defined for this specific
/// value. These constants are defined by the enumeration <b>mvIMPACT::acquire::TPropertyLimits</b>.
///
/// When reading the value of a property as a string the user might define a format string
/// telling the property module how to format the returned string. This works pretty much
/// like when working e.g. with the \e printf function.
class Property : public Component
//-----------------------------------------------------------------------------
{
	// do not allow assignments! This makes sure the user can't assign e.g. the
	// gain property to the property for controlling the expose time
	Property&		operator=( const Property& );
public:
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::Property</b> object.
	///
	/// Properties constructed this way can't be used for anything unless they
	/// are bound to a internal driver property with a <b>mvIMPACT::acquire::ComponentLocator</b> object.
	explicit Property( void ) {}
	/// \brief Constructs a new <b>mvIMPACT::acquire::Property</b> object.
	///
	/// Properties successfully constructed this way can be worked with directly.
	/// If \a hObj does not reference an internal driver property a <b>mvIMPACT::acquire::ENotAProperty</b>
	/// exception will be thrown.
	explicit Property( HOBJ hProp ) : Component(hProp)
	{
		if( !isProp() )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, PROPHANDLING_NOT_A_PROPERTY, hProp );
		}
	}
	/// \brief Returns the size of the properties translation dictionary.
	///
	/// If the property does define a translation dictionary this function returns
	/// the number of elements contained in this dictionary.
	/// \return
	/// - The size of the properties translation dictionary.
	/// - 0 If this property does not define a translation dictionary.
	unsigned int dictSize( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int size = 0;
		if( ( result = OBJ_GetDictSize( m_hObj, &size ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return size;
	}
	/// \brief Returns whether this property defines a translation dictionary or not.
	/// \return
	/// - true if this property defines a translation table
	/// - false otherwise
	bool hasDict( void ) const { return ( dictSize() > 0 ); }
	/// \brief Checks if a certain constant is defined for this property
	///
	/// Valid values for \a constant are defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b>.
	/// \return
	/// - true if this property defines this constant
	/// - false otherwise
	bool isConstDefined(	/// The constant whose existance is in question
							int constant ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int isDefined;
		if( ( result = OBJ_IsConstantDefined( m_hObj, constant, &isDefined ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return isDefined != 0;
	}
	/// \brief Reads data from this property as a string.
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \return A string containing the data questioned.
	std::string readS (	/// The index of the desired value(only necessary for properties containing more then one value)
						int index = 0,
						/// The format string telling the function how to format the result. If left empty the property uses its standard way of converting its data into a string
						const std::string& format = "" ) const
	{
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pBuf = new char[bufSize];
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		while( ( result = OBJ_GetSFormatted( m_hObj, pBuf, bufSize, ( ( format != "" ) ? format.c_str() : 0 ), index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			delete [] pBuf;
			bufSize *= BUFFER_INCREMENT_FACTOR;
			pBuf = new char[bufSize];
		}
		std::string value(pBuf);
		delete [] pBuf;
		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return value;
	}
	/// \brief Reads data from this property as a string.
	///
	/// This function can be used to query a set of values if this property stores more
	/// then a single value which might be useful for GUI applications
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLE:</b>
	///
	///\code
	/// PropertyI p = getPropFromSomewhere();
	/// p.write( 1 );
	/// p.write( 2, 1 );
	/// p.write( 666, 2 );
	/// std::string s = p.readSArray( "%d", "&&:", 1 );
	/// // now s should contain '2&&:666'
	/// s = p.readSArray( "%4d", " ", 0, 1 );
	/// // now s should contain '   1,   2'
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \return A string containing the data questioned.
	std::string	 readSArray(	/// The format string telling the function how to format the result. If left empty the property uses its standard way of converting its data into a string
								const std::string& format = "",
								/// This string is used to separate the individual values from one another. If left empty, a single blank will separate
								/// the data.
								const std::string& delimiter = "",
								/// The index of the first of the desired values
								int startIndex = 0,
								/// The index of the last of the desired values. If <b>INT_MAX</b> is passed, every
								/// from \a startIndex to the last value stored by the property will be returned.
								int endIndex = INT_MAX,
								/// Specifies the mode this function operates in. Currently only the LSB affects the behaviour of this function.
								/// When the LSB is set, the translation dictionary (if defined) will be ignored for this call.
								int mode = 0 ) const
	{
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pBuf = new char[bufSize];
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		while ( ( result = OBJ_GetSArrayFormatted(	m_hObj,
														pBuf,
														bufSize,
														( format != "" ) ? format.c_str() : 0,
														( delimiter != "" ) ? delimiter.c_str() : 0,
														startIndex,
														endIndex,
														mode ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			delete [] pBuf;
			bufSize *= BUFFER_INCREMENT_FACTOR;
			pBuf = new char[bufSize];
		}
		std::string value(pBuf);
		delete [] pBuf;
		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return value;
	}
	/// \brief Removes a certain value from the properties data.
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	void
#else
	///
	/// \return A const reference to the calling property.
	const Property&
#endif
					removeValue(	/// The index of the value to be removed
									int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_RemoveVal( m_hObj, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
	#ifndef DOTNET_ONLY_CODE
			return *this;
	#endif
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Resizes the properties data array.
	///
	/// This function resizes the internal data array of this property. The size of
	/// this array represents the number of values, which can be stored within the
	/// property. This function will only succeed, if the <b>mvIMPACT::acquire::cfFixedSize</b>
	/// is <b>NOT</b> set for this property and the user has <b>write rights</b> for this property.
	/// Otherwise an exception will be thrown. Whenever the user successfully writes an
	/// array of values to a property and this array contains more elements then the current
	/// internal data array can accommodate at the desired offset the internal data array
	/// will be increased automatically.
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \note In order to be allowed to modify the number of values a property
	/// can store, the <b>mvIMPACT::acquire::cfFixedSize</b> flag
	/// must <b>NOT</b> be set.
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable</b>
	void
#else
	/// \brief Resizes the properties data array.
	///
	/// This function resizes the internal data array of this property. The size of
	/// this array represents the number of values, which can be stored within the
	/// property. This function will only succeed, if the <b>mvIMPACT::acquire::cfFixedSize</b>
	/// is <b>NOT</b> set for this property and the user has <b>write rights</b> for this property.
	/// Otherwise an exception will be thrown. Whenever the user successfully writes an
	/// array of values to a property and this array contains more elements then the current
	/// internal data array can accommodate at the desired offset the internal data array
	/// will be increased automatically.
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \note In order to be allowed to modify the number of values a property
	/// can store, the <b>mvIMPACT::acquire::cfFixedSize</b> flag
	/// must <b>NOT</b> be set.
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable</b>
	///
	/// \return A const reference to the calling property.
	const Property&
#endif
					resizeValArray(	/// the new number of values this property shall be allowed to store									
									unsigned int newSize ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetValCount( m_hObj, newSize ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
	/// \brief Returns the internal format string this property uses to convert data to strings
	///
	/// \return A string containing the format string internally used by the property
	/// whenever the user reads a value as a string without specifying a format string and
	/// the property is not a string type one.
	std::string stringFormatString( void ) const { return compGetStringParam( sqPropFormatString ); }
	/// \brief Returns the current number of values managed by this property.
	///
	/// For the majority of properties this function will return '1', but as properties
	/// might manage more then a single value, this value might be interesting from time
	/// to time.
	/// \return the current number of values managed by this property.
	unsigned int valCount( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int valCount;
		if( ( result = OBJ_GetValCount( m_hObj, &valCount ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return valCount;
	}
	/// \brief Returns maximum number of values that can be managed by this property.
	///
	/// For the majority of properties this function will return '1', but as properties
	/// might manage more then a single value, this value might be interesting from time
	/// to time.
	/// \return the maximum number of values that can be managed by this property.
	unsigned int maxValCount( void ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int maxValCount;
		if( ( result = OBJ_GetMaxValCount( m_hObj, &maxValCount ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return maxValCount;
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Assigns a new value to this property
	///
	/// The user caller have <b>write rights</b> for this property in order to be able to
	/// modify its value. Also if \a index is greater then the current internal data array
	/// size of this property the user must be allowed to change to size of the properties
	/// internal data array (the <b>mvIMPACT::acquire::cfFixedSize</b> flag must <b>NOT</b> be set).
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable, <br>mvIMPACT::acquire::Component::flags,<br>
	///    mvIMPACT::acquire::Property::writeS</b>
	void
#else
	/// \brief Assigns a new value to this property
	///
	/// The user caller have <b>write rights</b> for this property in order to be able to
	/// modify its value. Also if \a index is greater then the current internal data array
	/// size of this property the user must be allowed to change to size of the properties
	/// internal data array (the <b>mvIMPACT::acquire::cfFixedSize</b> flag must <b>NOT</b> be set).
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable, <br>mvIMPACT::acquire::Component::flags,<br>
	///    mvIMPACT::acquire::Property::writeS</b>
	///
	/// \return A const reference to the calling property.
	const Property&
#endif
					writeS( /// The new value for this property at the given \a index
							const std::string& value,
							/// The index of the value to modify
							int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetS( m_hObj, value.c_str(), index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj, value );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Assigns new values to this property
	///
	/// The user must have <b>write rights</b> for this property in order to be able to
	/// modify its values. Also if \a index is greater then the current internal data array
	/// size of this property the user must be allowed to change to size of the properties
	/// internal data array (the <b>mvIMPACT::acquire::cfFixedSize</b> flag must <b>NOT</b> be set). This
	/// function behaves exactly like <b>mvIMPACT::acquire::Property::writeS</b>
	/// except that is can be used to assign more then one value at the same time. The parameter
	/// \a index here serves as an offset. If for example a property holds 3 values 'one', 'two'
	/// and 'three' before this call and the function is then called with an array containing the
	/// string 'orange' and 'blue' and \a index = 2 then after a successful call to this function
	/// the property will hold the data 'one', 'two', 'orange' and 'blue'.
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable, <br>mvIMPACT::acquire::Component::flags,<br>
	///    mvIMPACT::acquire::Property::writeS</b>
	void
#else
	/// \brief Assigns new values to this property
	///
	/// The user must have <b>write rights</b> for this property in order to be able to
	/// modify its values. Also if \a index is greater then the current internal data array
	/// size of this property the user must be allowed to change to size of the properties
	/// internal data array (the <b>mvIMPACT::acquire::cfFixedSize</b> flag must <b>NOT</b> be set). This
	/// function behaves exactly like <b>mvIMPACT::acquire::Property::writeS</b>
	/// except that is can be used to assign more then one value at the same time. The parameter
	/// \a index here serves as an offset. If for example a property holds 3 values 'one', 'two'
	/// and 'three' before this call and the function is then called with an array containing the
	/// string 'orange' and 'blue' and \a index = 2 then after a successful call to this function
	/// the property will hold the data 'one', 'two', 'orange' and 'blue'.
	///
	/// \note If the caller does not have the needed rights this function might throw an
	/// exception of the type <b>mvIMPACT::acquire::ImpactAcquireException</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Component::isWriteable, <br>mvIMPACT::acquire::Component::flags,<br>
	///    mvIMPACT::acquire::Property::writeS</b>
	///
	/// \return A const reference to the calling property.
	const Property&
#endif
					writeS( /// A constant reference to an array containing the strings to be assigned to the property
							const std::vector<std::string>& sequence,
							/// The offset from where to start to assign the values
							int index = 0  ) const
	{
		unsigned int vSize = static_cast<unsigned int>(sequence.size());
		for( unsigned int i=0; i<vSize; i++ )
		{
			writeS( sequence[i], index + i );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
};

//-----------------------------------------------------------------------------
/// \brief A template class to represent float properties and enumerated float properties
///
/// The template parameter specifies the enum to use as the value type for this
/// enumerated property. The class itself however is restricted for float values.
/// To use a normal float (not enumerated) properties use the <b>mvIMPACT::acquire::PropertyF</b> type.
template<class ZYX>
class EnumPropertyF : public Property
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::EnumPropertyF</b> object.
	explicit EnumPropertyF() {}
	/// \brief Constructs a new <b>mvIMPACT::acquire::EnumPropertyF</b> object.
	explicit EnumPropertyF( HOBJ hObj ) : Property(hObj) {}
#ifndef WRAP_DOTNET
	/// \brief This function queries the properties translation table
	///
	/// If this property defines a translation table the strings and there corresponding
	/// translation values will be written into \a sequence. If the property does <b>NOT</b>
	/// define a translation table \a sequence will be empty after this function call.
	///
	/// \note
	/// This function is much more efficient then calling
	/// <b>EnumPropertyF::getTranslationDictString</b> and
	/// <b>EnumPropertyF::getTranslationDictValue</b> and
	/// therefore this function should be called whenever all entries are required.
	/// \return A const reference to the calling property.
	const EnumPropertyF& getTranslationDict(	/// A reference to a container which will receive the data from the properties trnaslation dictionary.
												std::vector<std::pair<std::string, ZYX> >& sequence ) const
	{
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		unsigned int size = dictSize();

		double* pVal = new double[size];
		char** ppBuf = new char*[size];
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT, i;

		for( i=0; i<size; i++ )
		{
			ppBuf[i] = new char[bufSize];
		}

		while( ( result = OBJ_GetFDictEntries( m_hObj, ppBuf, bufSize, pVal, size ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			bufSize *= BUFFER_INCREMENT_FACTOR;
			for( size_t i=0; i<size; i++ )
			{
				delete [] ppBuf[i];
				ppBuf[i] = new char[bufSize];
			}
		}

		if( result == PROPHANDLING_NO_ERROR )
		{
			sequence.resize(size);
			for( unsigned int i=0; i<size; i++ )
			{
				sequence[i] = std::pair<std::string, ZYX>( ppBuf[i], static_cast<ZYX>(pVal[i]) );
			}
		}

		for( i=0; i<size; i++ )
		{
			delete [] ppBuf[i];
		}
		delete [] ppBuf;
		delete [] pVal;

		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return *this;
	}
#endif // WRAP_DOTNET
	/// \brief This function reads a single translation table string entry from a property.
	///
	/// If this property defines a translation table and \a index specifies a valid entry
	/// the string representation of this entry will be returned.
	/// If the property does <b>NOT</b> define a translation table or \a index specifies
	/// an invalid entry an exception will be thrown.
	std::string	getTranslationDictString(	/// The index of the entry to read from the property.
											int index = 0 ) const
	{
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pTranslationString = new char[bufSize];
		while( ( result = OBJ_GetFDictEntry( m_hObj, pTranslationString, bufSize, 0, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			bufSize *= BUFFER_INCREMENT_FACTOR;
			delete [] pTranslationString;
			pTranslationString = new char[bufSize];
		}

		std::string translationString(pTranslationString);
		delete [] pTranslationString;

		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return translationString;
	}
	/// \brief This function reads a single translation table value entry from a property.
	///
	/// If this property defines a translation table and \a index specifies a valid entry
	/// the value of this entry will be returned.
	/// If the property does <b>NOT</b> define a translation table or \a index specifies
	/// an invalid entry an exception will be thrown.
	ZYX	getTranslationDictValue(	/// The index of the entry to read from the property.
									int index = 0 ) const
	{
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		double value;
		if( ( result = OBJ_GetFDictEntry( m_hObj, 0, 0, &value, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return static_cast<ZYX>(result);
	}
	/// \brief Reads a value from a property.
	///
	/// This function queries a single value stored under index \a index in the property.
	/// \return The value stored at \a index within the property.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	ZYX	read(	/// The index of the value to read from the property.
				int index = 0 ) const
	{
		double val;
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_GetF( m_hObj, &val, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return static_cast<ZYX>(val);
	}
	/// \brief Reads a set of values from a property.
	///
	/// This function queries a set of values from a property and stores these values
	/// into \a sequence.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	/// \return Nothing.
	void read(	/// A reference to a container to store the data read from the property into.
				std::vector<ZYX>& sequence,
				// The index from where to start reading values from the property.
				int start = 0,
				/// The index where to stop reading values from the property.
				int end = END_OF_LIST ) const
	{
		unsigned int valCnt = ( end == END_OF_LIST ) ? valCount() : ( end - start + 1 );
		sequence.resize(valCnt);
		for( unsigned int i=0; i<valCnt; i++ )
		{
			sequence[i] = read( i+start );
		}
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	void
#else
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	///
	/// \return A const 'self' reference.
	const EnumPropertyF&
#endif
								write(	/// The value to write to the property.
										ZYX value,
										/// The index defining at which position to write the value.
										int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetF( m_hObj, static_cast<double>(value), index ) ) != PROPHANDLING_NO_ERROR )
		{
			std::ostringstream oss;
			oss << value;
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj, oss.str() );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	void
#else
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	///
	/// \return A const 'self' reference.
	const EnumPropertyF&
#endif
								write(	/// An array containing the values to write to the property.
										const std::vector<ZYX>& sequence,
										/// The index where to write the first value to the property.
										int index = 0 ) const
	{
		unsigned int vSize = static_cast<unsigned int>(sequence.size());
		for( unsigned int i=0; i<vSize; i++ )
		{
			write( sequence[i], index + i );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
};

/// \brief A type for floating point properties.
///
/// Provided for convenience only. This type represent a standard float property type.
typedef EnumPropertyF<double> PropertyF;
PYTHON_ONLY(ENUM_PROPERTY(PropertyF, EnumPropertyF, double));

//-----------------------------------------------------------------------------
/// \brief A template class to represent integer properties and enumerated integer properties
///
/// The template parameter specifies the enum to use as the value type for this
/// enumerated property. The class itself however is restricted for integer values.
/// To use a normal int (not enumerated) properties use the <b>PropertyI</b> type.
template<class ZYX>
class EnumPropertyI : public Property
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new unbound <b>EnumPropertyI</b> object.
	explicit			EnumPropertyI() {}
	/// \brief Constructs a new <b>EnumPropertyI</b> object.
	explicit			EnumPropertyI( HOBJ hObj ) : Property(hObj) {}
#ifndef WRAP_DOTNET
	/// \brief This function queries the properties translation table
	///
	/// If this property defines a translation table the strings and there corresponding
	/// translation values will be written into \a sequence. If the property does <b>NOT</b>
	/// define a translation table \a sequence will be empty after this function call.
	///
	/// \note
	/// This function is much more efficient then calling
	/// <b>mvIMPACT::acquire::EnumPropertyI::getTranslationDictString</b> and
	/// <b>mvIMPACT::acquire::EnumPropertyI::getTranslationDictValue</b> and
	/// therefore this function should be called whenever all entries are required.

	/// \return A const reference to the calling property.
	const EnumPropertyI& getTranslationDict(	/// A reference to an container which will receive the data from the properties trnaslation dictionary.
												std::vector<std::pair<std::string, ZYX> >& sequence ) const
{
			TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
			unsigned int size = dictSize();

			int* pVal = new int[size];
			char** ppBuf = new char*[size];
			size_t bufSize = DEFAULT_STRING_SIZE_LIMIT, i;
			for( i=0; i<size; i++ )
			{
				ppBuf[i] = new char[bufSize];
			}

			while( ( result = OBJ_GetIDictEntries( m_hObj, ppBuf, bufSize, pVal, size ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
			{
				bufSize *= BUFFER_INCREMENT_FACTOR;
				for( size_t i=0; i<size; i++ )
				{
					delete [] ppBuf[i];
					ppBuf[i] = new char[bufSize];
				}
			}

			if( result == PROPHANDLING_NO_ERROR )
			{
				sequence.resize(size);
				for( unsigned int i=0; i<size; i++ )
				{
					sequence[i] = std::pair<std::string, ZYX>( ppBuf[i], static_cast<ZYX>(pVal[i]) );
				}
			}

			for( i=0; i<size; i++ )
			{
				delete [] ppBuf[i];
			}
			delete [] ppBuf;
			delete [] pVal;

			if( result != PROPHANDLING_NO_ERROR )
			{
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
			}
			return *this;
		}
#endif // WRAP_DOTNET
	/// \brief This function reads a single translation table string entry from a property.
	///
	/// If this property defines a translation table and \a index specifies a valid entry
	/// the string representation of this entry will be returned.
	/// If the property does <b>NOT</b> define a translation table or \a index specifies
	/// an invalid entry an exception will be thrown.
	std::string getTranslationDictString(	/// The index of the entry to read from the property.
											int index = 0 ) const
	{
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pTranslationString = new char[bufSize];
		while( ( result = OBJ_GetIDictEntry( m_hObj, pTranslationString, bufSize, 0, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			bufSize *= BUFFER_INCREMENT_FACTOR;
			delete [] pTranslationString;
			pTranslationString = new char[bufSize];
		}

		std::string translationString(pTranslationString);
		delete [] pTranslationString;

		if( result != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return translationString;
	}
	/// \brief This function reads a single translation table value entry from a property.
	///
	/// If this property defines a translation table and \a index specifies a valid entry
	/// the value of this entry will be returned.
	/// If the property does <b>NOT</b> define a translation table or \a index specifies
	/// an invalid entry an exception will be thrown.
	ZYX getTranslationDictValue(	/// The index of the entry to read from the property.
									int index = 0 ) const
	{
		TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
		int value;
		if( ( result = OBJ_GetIDictEntry( m_hObj, 0, 0, &value, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return static_cast<ZYX>(value);
	}
	/// \brief Reads a value from a property.
	///
	/// This function queries a single value stored under index \a index in the property.
	/// \return The value stored at \a index within the property.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	ZYX read( /// The index of the value to read from the property.
			  int index = 0 ) const
	{
		int val;
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_GetI( m_hObj, &val, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return static_cast<ZYX>(val);
	}
	/// \brief Reads a set of values from a property.
	///
	/// This function queries a set of values from a property and stores these values
	/// into \a sequence.
	/// \return Nothing.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	void read( /// A reference to a container to store the data read from the property into.
			  std::vector<ZYX>& sequence,
			  /// The index from where to start reading values from the property.
			  int start = 0,
			  /// The index where to stop reading values from the property.
			  int end = END_OF_LIST ) const
	{
		unsigned int valCnt = ( end == END_OF_LIST ) ? valCount() : ( end - start + 1 );
		sequence.resize(valCnt);
		for( unsigned int i=0; i<valCnt; i++ )
		{
			sequence[i] = read( i+start );
		}
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	void
#else
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	///
	/// \return A const 'self' reference.
	const EnumPropertyI&
#endif
							write(	/// The value to write to the property.
									ZYX value,
									/// The index defining at which position to write the value.
									int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetI( m_hObj, static_cast<int>(value), index ) ) != PROPHANDLING_NO_ERROR )
		{
			std::ostringstream oss;
			oss << value;
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj, oss.str() );
		}
	#ifndef DOTNET_ONLY_CODE
			return *this;
	#endif
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	void
#else
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	///
	/// \return A const 'self' reference.
	const EnumPropertyI&
#endif
							write(	/// An array containing the values to write to the property.
									const std::vector<ZYX>& sequence,
									/// The index where to write the first value to the property.
									int index = 0 ) const
	{
		int vSize = static_cast<int>(sequence.size());
		for( int i=0; i<vSize; i++ )
		{
			write( sequence[i], index + i );
		}
	#ifndef DOTNET_ONLY_CODE
		return *this;
	#endif
	}
};

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAcquisitionField</b>
typedef EnumPropertyI<TAcquisitionField> PropertyIAcquisitionField;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAcquisitionField, EnumPropertyI, TAcquisitionField ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAoiMode</b>
typedef EnumPropertyI<TAoiMode> PropertyIAoiMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAoiMode, EnumPropertyI, TAoiMode ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAutoControlSpeed</b>
typedef EnumPropertyI<TAutoControlSpeed> PropertyIAutoControlSpeed;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAutoControlSpeed, EnumPropertyI, TAutoControlSpeed ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAutoExposureControl</b>
typedef EnumPropertyI<TAutoExposureControl> PropertyIAutoExposureControl;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAutoExposureControl, EnumPropertyI, TAutoExposureControl ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAutoGainControl</b>
typedef EnumPropertyI<TAutoGainControl> PropertyIAutoGainControl;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAutoGainControl, EnumPropertyI, TAutoGainControl ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TAutoOffsetCalibration</b>
typedef EnumPropertyI<TAutoOffsetCalibration> PropertyIAutoOffsetCalibration;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIAutoOffsetCalibration, EnumPropertyI, TAutoOffsetCalibration));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBayerMosaicParity</b>
typedef EnumPropertyI<TBayerMosaicParity> PropertyIBayerMosaicParity;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIBayerMosaicParity, EnumPropertyI, TBayerMosaicParity ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBayerWhiteBalanceResult</b>
typedef EnumPropertyI<TBayerWhiteBalanceResult> PropertyIBayerWhiteBalanceResult;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIBayerWhiteBalanceResult, EnumPropertyI, TBayerWhiteBalanceResult ));

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBlueFOXDigitalInputThreshold</b>
	typedef EnumPropertyI<TBlueFOXDigitalInputThreshold> PropertyIBlueFOXDigitalInputThreshold;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIBlueFOXDigitalInputThreshold, EnumPropertyI, TBlueFOXDigitalInputThreshold));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBlueFOXFooterMode</b>
	typedef EnumPropertyI<TBlueFOXFooterMode> PropertyIBlueFOXFooterMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIBlueFOXFooterMode, EnumPropertyI, TBlueFOXFooterMode ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBlueFOXSensorTiming</b>
	typedef EnumPropertyI<TBlueFOXSensorTiming> PropertyIBlueFOXSensorTiming;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIBlueFOXSensorTiming, EnumPropertyI, TBlueFOXSensorTiming ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TBlueFOXTransferSize</b>
	typedef EnumPropertyI<TBlueFOXTransferSize> PropertyIBlueFOXTransferSize;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIBlueFOXTransferSize, EnumPropertyI, TBlueFOXTransferSize ));
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVBLUELYNX_SPECIFIC_DOCUMENTATION
	/// \brief Defines a <b>mvBlueLYNX</b> property for values defined by <b>mvIMPACT::acquire::TBlueLYNXCameraPixelClock</b>
	typedef EnumPropertyI<TBlueLYNXCameraPixelClock> PropertyIBlueLYNXCameraPixelClock;
	PYTHON_ONLY( ENUM_PROPERTY( PropertyIBlueLYNXCameraPixelClock, EnumPropertyI, TBlueLYNXCameraPixelClock ));

	/// \brief Defines a <b>mvBlueLYNX</b> property for values defined by <b>mvIMPACT::acquire::TBlueLYNXCameraExposeMode</b>
	typedef EnumPropertyI<TBlueLYNXCameraExposeMode> PropertyIBlueLYNXCameraExposeMode;
	PYTHON_ONLY( ENUM_PROPERTY( PropertyIBlueLYNXCameraExposeMode, EnumPropertyI, TBlueLYNXCameraExposeMode ));

	/// \brief Defines a <b>mvBlueLYNX</b> property for values defined by <b>mvIMPACT::acquire::TBlueLYNXCameraDataClipMode</b>
	typedef EnumPropertyI<TBlueLYNXCameraDataClipMode> PropertyIBlueLYNXCameraDataClipMode;
	PYTHON_ONLY( ENUM_PROPERTY( PropertyIBlueLYNXCameraDataClipMode, EnumPropertyI, TBlueLYNXCameraDataClipMode ));

	/// \brief Defines a <b>mvBlueLYNX</b> property for values defined by <b>mvIMPACT::acquire::TBlueLYNXCameraFlashMode</b>
	typedef EnumPropertyI<TBlueLYNXCameraFlashMode> PropertyIBlueLYNXCameraFlashMode;
	PYTHON_ONLY( ENUM_PROPERTY( PropertyIBlueLYNXCameraFlashMode, EnumPropertyI, TBlueLYNXCameraFlashMode ));

	/// \brief Defines a <b>mvBlueLYNX</b> property for values defined by <b>mvIMPACT::acquire::TBlueLYNXCameraLineTriggerMode</b>
	typedef EnumPropertyI<TBlueLYNXCameraLineTriggerMode> PropertyIBlueLYNXCameraLineTriggerMode;
	PYTHON_ONLY( ENUM_PROPERTY( PropertyIBlueLYNXCameraLineTriggerMode, EnumPropertyI, TBlueLYNXCameraLineTriggerMode ));
#endif // #ifndef IGNORE_MVBLUELYNX_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraAoiMode</b>
typedef EnumPropertyI<TCameraAoiMode> PropertyICameraAoiMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraAoiMode, EnumPropertyI, TCameraAoiMode ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraBinningMode</b>
typedef EnumPropertyI<TCameraBinningMode> PropertyICameraBinningMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraBinningMode, EnumPropertyI, TCameraBinningMode ));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraDataFormat</b>
	typedef EnumPropertyI<TCameraDataFormat> PropertyICameraDataFormat;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraDataFormat, EnumPropertyI, TCameraDataFormat));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraExposeMode</b>
typedef EnumPropertyI<TCameraExposeMode> PropertyICameraExposeMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraExposeMode, EnumPropertyI, TCameraExposeMode));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraExternalSyncEdge</b>
	typedef EnumPropertyI<TCameraExternalSyncEdge> PropertyICameraExternalSyncEdge;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraExternalSyncEdge, EnumPropertyI, TCameraExternalSyncEdge ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraExternalSyncOutput</b>
	typedef EnumPropertyI<TCameraExternalSyncOutput> PropertyICameraExternalSyncOutput;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraExternalSyncOutput, EnumPropertyI, TCameraExternalSyncOutput ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraFlashMode</b>
typedef EnumPropertyI<TCameraFlashMode> PropertyICameraFlashMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraFlashMode, EnumPropertyI, TCameraFlashMode ));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraInterlacedType</b>
	typedef EnumPropertyI<TCameraInterlacedType> PropertyICameraInterlacedType;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraInterlacedType, EnumPropertyI, TCameraInterlacedType ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraLinkDataValidMode</b>
	typedef EnumPropertyI<TCameraLinkDataValidMode> PropertyICameraLinkDataValidMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraLinkDataValidMode, EnumPropertyI, TCameraLinkDataValidMode ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraOutput</b>
	typedef EnumPropertyI<TCameraOutput> PropertyICameraOutput;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraOutput, EnumPropertyI, TCameraOutput ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraPixelClock</b>
typedef EnumPropertyI<TCameraPixelClock> PropertyICameraPixelClock;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraPixelClock, EnumPropertyI, TCameraPixelClock ));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraScanMode</b>
	typedef EnumPropertyI<TCameraScanMode> PropertyICameraScanMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraScanMode, EnumPropertyI, TCameraScanMode ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraTriggerMode</b>
typedef EnumPropertyI<TCameraTriggerMode> PropertyICameraTriggerMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraTriggerMode, EnumPropertyI, TCameraTriggerMode));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraTestMode</b>
typedef EnumPropertyI<TCameraTestMode> PropertyICameraTestMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraTestMode, EnumPropertyI, TCameraTestMode ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraSerialPortBaudRate</b>
typedef EnumPropertyI<TCameraSerialPortBaudRate> PropertyICameraSerialPortBaudRate;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraSerialPortBaudRate, EnumPropertyI, TCameraSerialPortBaudRate ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TCameraTriggerSource</b>
typedef EnumPropertyI<TCameraTriggerSource> PropertyICameraTriggerSource;
PYTHON_ONLY(ENUM_PROPERTY(PropertyICameraTriggerSource, EnumPropertyI, TCameraTriggerSource ));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TClampMode</b>
	typedef EnumPropertyI<TClampMode> PropertyIClampMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIClampMode, EnumPropertyI, TClampMode ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TColorProcessingMode</b>
typedef EnumPropertyI<TColorProcessingMode> PropertyIColorProcessingMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIColorProcessingMode, EnumPropertyI, TColorProcessingMode ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDarkCurrentFilterMode</b>
typedef EnumPropertyI<TDarkCurrentFilterMode> PropertyIDarkCurrentFilterMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIDarkCurrentFilterMode, EnumPropertyI, TDarkCurrentFilterMode));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDefectivePixelsFilterMode</b>
typedef EnumPropertyI<TDefectivePixelsFilterMode> PropertyIDefectivePixelsFilterMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIDefectivePixelsFilterMode, EnumPropertyI, TDefectivePixelsFilterMode));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceDigitalOutputMode</b>
	typedef EnumPropertyI<TDeviceDigitalOutputMode> PropertyIDeviceDigitalOutputMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceDigitalOutputMode, EnumPropertyI, TDeviceDigitalOutputMode));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceImageTrigger</b>
	typedef EnumPropertyI<TDeviceImageTrigger> PropertyIDeviceImageTrigger;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceImageTrigger, EnumPropertyI, TDeviceImageTrigger));
#endif // IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceLoadSettings</b>
typedef EnumPropertyI<TDeviceLoadSettings> PropertyIDeviceLoadSettings;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceLoadSettings, EnumPropertyI, TDeviceLoadSettings));

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDevicePowerMode</b>
	typedef EnumPropertyI<TDevicePowerMode> PropertyIDevicePowerMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDevicePowerMode, EnumPropertyI, TDevicePowerMode));
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceScanRateMode</b>
	typedef EnumPropertyI<TDeviceScanRateMode> PropertyIDeviceScanRateMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceScanRateMode, EnumPropertyI, TDeviceScanRateMode));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent</b>
	typedef EnumPropertyI<TDeviceSignalOutputStartEvent> PropertyIDeviceSignalOutputStartEvent;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceSignalOutputStartEvent, EnumPropertyI, TDeviceSignalOutputStartEvent));
#endif // IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceState</b>
typedef EnumPropertyI<TDeviceState> PropertyIDeviceState;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceState, EnumPropertyI, TDeviceState));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceSyncOutMode</b>
	typedef EnumPropertyI<TDeviceSyncOutMode> PropertyIDeviceSyncOutMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceSyncOutMode, EnumPropertyI, TDeviceSyncOutMode));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDeviceTriggerMode</b>
	typedef EnumPropertyI<TDeviceTriggerMode> PropertyIDeviceTriggerMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDeviceTriggerMode, EnumPropertyI, TDeviceTriggerMode));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDigIOState</b>
typedef EnumPropertyI<TDigIOState> PropertyIDigIOState;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIDigIOState, EnumPropertyI, TDigIOState));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TDigitalOutputControlMode</b>
	typedef EnumPropertyI<TDigitalOutputControlMode> PropertyIDigitalOutputControlMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIDigitalOutputControlMode, EnumPropertyI, TDigitalOutputControlMode));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TFieldGateMode</b>
	typedef EnumPropertyI<TFieldGateMode> PropertyIFieldGateMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIFieldGateMode, EnumPropertyI, TFieldGateMode));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TFlatFieldFilterMode</b>
typedef EnumPropertyI<TFlatFieldFilterMode> PropertyIFlatFieldFilterMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIFlatFieldFilterMode, EnumPropertyI, TFlatFieldFilterMode));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::THWUpdateResult</b>
typedef EnumPropertyI<THWUpdateResult> PropertyIHWUpdateResult;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIHWUpdateResult, EnumPropertyI, THWUpdateResult));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TImageDestinationPixelFormat</b>
typedef EnumPropertyI<TImageDestinationPixelFormat> PropertyIImageDestinationPixelFormat;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIImageDestinationPixelFormat, EnumPropertyI, TImageDestinationPixelFormat ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TImageProcessingFilter</b>
typedef EnumPropertyI<TImageProcessingFilter> PropertyIImageProcessingFilter;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIImageProcessingFilter, EnumPropertyI, TImageProcessingFilter ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TImageRequestControlMode</b>
typedef EnumPropertyI<TImageRequestControlMode>	PropertyIImageRequestControlMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIImageRequestControlMode, EnumPropertyI, TImageRequestControlMode));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TInfoSensorColorMode</b>
typedef EnumPropertyI<TInfoSensorColorMode> PropertyIInfoSensorColorMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIInfoSensorColorMode, EnumPropertyI, TInfoSensorColorMode));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TInfoSensorType</b>
typedef EnumPropertyI<TInfoSensorType> PropertyIInfoSensorType;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIInfoSensorType, EnumPropertyI, TInfoSensorType));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TInterlacedMode</b>
typedef EnumPropertyI<TInterlacedMode> PropertyIInterlacedMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIInterlacedMode, EnumPropertyI, TInterlacedMode));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TLineCounter</b>
	typedef EnumPropertyI<TLineCounter> PropertyILineCounter;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyILineCounter, EnumPropertyI, TLineCounter));
#endif // IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TMirrorMode</b>
typedef EnumPropertyI<TMirrorMode> PropertyIMirrorMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIMirrorMode, EnumPropertyI, TMirrorMode ));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TOnBoardMemoryMode</b>
	typedef EnumPropertyI<TOnBoardMemoryMode> PropertyIOnBoardMemoryMode;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIOnBoardMemoryMode, EnumPropertyI, TOnBoardMemoryMode));
#endif // IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TRTCtrlModes</b>
typedef EnumPropertyI<TRTCtrlModes> PropertyIRTCtrlModes;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIRTCtrlModes, EnumPropertyI, TRTCtrlModes));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TRTProgOpCodes</b>
typedef EnumPropertyI<TRTProgOpCodes> PropertyIRTProgOpCodes;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIRTProgOpCodes, EnumPropertyI, TRTProgOpCodes));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TScanClock</b>
	typedef EnumPropertyI<TScanClock> PropertyIScanClock;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIScanClock, EnumPropertyI, TScanClock ));

	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TScanStandard</b>
	typedef EnumPropertyI<TScanStandard> PropertyIScanStandard;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIScanStandard, EnumPropertyI, TScanStandard ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TThreadPriority</b>
typedef EnumPropertyI<TThreadPriority> PropertyIThreadPriority;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIThreadPriority, EnumPropertyI, TThreadPriority ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TUserDataAccessRight</b>
typedef EnumPropertyI<TUserDataAccessRight> PropertyIUserDataAccessRight;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIUserDataAccessRight, EnumPropertyI, TUserDataAccessRight));

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TVideoStandard</b>
	typedef EnumPropertyI<TVideoStandard> PropertyIVideoStandard;
	PYTHON_ONLY(ENUM_PROPERTY(PropertyIVideoStandard, EnumPropertyI, TVideoStandard ));
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TWhiteBalanceCalibrationMode</b>
typedef EnumPropertyI<TWhiteBalanceCalibrationMode> PropertyIWhiteBalanceCalibrationMode;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIWhiteBalanceCalibrationMode, EnumPropertyI, TWhiteBalanceCalibrationMode ));

/// \brief Defines a property for values defined by <b>mvIMPACT::acquire::TWhiteBalanceParameter</b>
typedef EnumPropertyI<TWhiteBalanceParameter> PropertyIWhiteBalanceParameter;
PYTHON_ONLY(ENUM_PROPERTY(PropertyIWhiteBalanceParameter, EnumPropertyI, TWhiteBalanceParameter ));

/// \brief A type for integer properties.
///
/// Provided for convenience only. This type represent a standard integer property type.
typedef EnumPropertyI<int> PropertyI;
PYTHON_ONLY(ENUM_PROPERTY(PropertyI, EnumPropertyI, int));

#ifndef WRAP_DOTNET // pointer properties currently not supported under .NET

	//-----------------------------------------------------------------------------
	/// \brief A class to represent pointer properties.
	class PropertyPtr : public Property
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new unbound <b>mvIMPACT::acquire::PropertyPtr</b> object.
		explicit			PropertyPtr() {}
		/// \brief Constructs a new <b>mvIMPACT::acquire::PropertyPtr</b> object.
		explicit			PropertyPtr( HOBJ hObj ) : Property(hObj) {}
		/// \brief Reads a value from a property.
		///
		/// This function queries a single value stored under index \a index in the property.
		///
		/// \note
		/// To query certain limits like e.g. the max value for this property one of the values
		/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
		/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
		/// read is defined at all.
		/// \return The value stored at \a index within the property.
		void* read(	/// The index of the value to read from the property.
					int index = 0 ) const
		{
			void* val;
			TPROPHANDLING_ERROR result;
			if( ( result = OBJ_GetP( m_hObj, &val, index ) ) != PROPHANDLING_NO_ERROR )
			{
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
			}
			return val;
		}
		/// \brief Reads a set of values from a property.
		///
		/// This function queries a set of values from a property and stores these values
		/// into \a sequence.
		///
		/// \note
		/// To query certain limits like e.g. the max value for this property one of the values
		/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
		/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
		/// read is defined at all.
		/// \return Nothing.
		void read(	/// A reference to a container to store the data read from the property into.
					std::vector<void*>& sequence,
					/// The index from where to start reading values from the property.
					int start = 0,
					/// The index where to stop reading values from the property.
					int end = END_OF_LIST ) const
		{
			unsigned int valCnt = ( end == END_OF_LIST ) ? valCount() : ( end - start + 1 );
			sequence.resize(valCnt);
			for( unsigned int i=0; i<valCnt; i++ )
			{
				sequence[i] = read( i+start );
			}
		}
		/// \brief Writes one value to the property.
		///
		/// This function writes a single value under index \a index to the property.
		/// \return A const 'self' reference.
		const PropertyPtr& write(	/// The value to write to the property.
									void* value,
									/// The index defining at which position to write the value.
									int index = 0 ) const
		{
			TPROPHANDLING_ERROR result;
			if( ( result = OBJ_SetP( m_hObj, value, index ) ) != PROPHANDLING_NO_ERROR )
			{
				std::ostringstream oss;
				oss.setf( std::ios::hex, std::ios::basefield );
				oss << value;
				oss.unsetf( std::ios::hex );
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj, oss.str() );
				
			}
			return *this;
		}
		/// \brief Writes a set of values to the property.
		///
		/// This function writes a set of values starting at \a index to the property.
		/// \return A const 'self' reference.
		const PropertyPtr& write(	/// An array containing the values to write to the property.
									const std::vector<void*>& sequence,
									/// The index where to write the first value to the property.
									int index = 0 ) const
		{
			unsigned int vSize = static_cast<unsigned int>(sequence.size());
			for( unsigned int i=0; i<vSize; i++ )
			{
				write( sequence[i], static_cast<int>(index + i) );
			}
			return *this;
		}
	};

#endif // #ifndef WRAP_DOTNET

//-----------------------------------------------------------------------------
/// \brief A class to represent pointer properties.
class PropertyS : public Property
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new unbound <b>mvIMPACT::acquire::PropertyS</b> object.
	explicit PropertyS() {}
	/// \brief Constructs a new <b>mvIMPACT::acquire::PropertyS</b> object.
	explicit PropertyS( HOBJ hObj ) : Property(hObj) {}
	/// \brief Returns the size(in bytes) needed for the binary representation of the string buffer.
	///
	/// When binary data has been stored in a string property it has been stored in base64 format
	/// internally. If the user want's to know the length of the binary data in decoded format,
	/// this function can be called.
	///
	/// \return The size(in bytes) needed for the binary representation of the string buffer.
	unsigned int binaryDataBufferSize(	/// The index of the value for which to query the
										/// buffer size(if this property holds more then one value).
										int index = 0 ) const
	{
   		unsigned int val;
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_GetBinaryBufferSize( m_hObj, &val, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return val;
	}
	/// \brief Reads a value from a property.
	///
	/// This function queries a single value stored under index \a index in the property.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	/// \return The value stored at \a index within the property.
	std::string	read(	/// The index of the value to read from the property.
						int index = 0 ) const { return compGetStringParam( sqPropVal, 0, index ); }
	/// \brief Reads a set of values from a property.
	///
	/// This function queries a set of values from a property and stores these values
	/// into \a sequence.
	///
	/// \note
	/// To query certain limits like e.g. the max value for this property one of the values
	/// defined by the enum <b>mvIMPACT::acquire::TPropertyLimits</b> can be passed as \a index.
	/// Use <b>mvIMPACT::acquire::Property::isConstDefined</b> to find out if the constant you want to
	/// read is defined at all.
	/// \return Nothing.
	void read(	/// A reference to a container to store the data read from the property into.
				std::vector<std::string>& sequence,
				/// The index from where to start reading values from the property.
				int start = 0,
				/// The index where to stop reading values from the property.
				int end = END_OF_LIST ) const
	{
		unsigned int valCnt = ( end == END_OF_LIST ) ? valCount() : ( end - start + 1 );
		sequence.resize(valCnt);
		for( unsigned int i=0; i<valCnt; i++ )
		{
			sequence[i] = read( i + start );
		}
	}
#ifndef WRAP_DOTNET
	/// \brief Reads a value stored in the property as binary data.
	///
	/// Binary data can only be stored in string properties. When writing binary data to a string
	/// property it's stored in base64 format internally. The base64 algorithm converts arbitrary data
	/// into a read and printable string representation. As a result of this 3 bytes of arbitrary binary
	/// data will occupy 4 bytes of memory.
	///
	/// Reading binary data with this function obviously only makes sense if the property has been assigned
	/// the value by a previous call to <b>mvIMPACT::acquire::PropertyS::writeBinary</b>.
	/// However it allows to store any kind of data in a string property.
	/// This can e.g. be interesting when certain data shall be stored in the
	/// user accessible part of the devices non-volatile memory.
	///
	/// \note
	/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
	/// <b>mvIMPACT::acquire::PropertyS::readBinary</b> instead.
	/// \return Nothing.
	void readBinary(	/// A pointer to a user supplied buffer that receives the properties binary representation of the value.
						char* pBuf,
						/// The size of the user supplied buffer. To find out how much memory must be allocated to store
						/// the binary representation of the string properties data the function <b>mvIMPACT::acquire::PropertyS::binaryDataBufferSize</b>
						/// should be called.
						unsigned int bufSize,
						/// The index of the value to get(if this property holds more then one value).
						int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_GetBinary( m_hObj, pBuf, bufSize, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
	}
#endif // #ifndef WRAP_DOTNET
	/// \brief Reads a value stored in the property as binary data.
	///
	/// Binary data can only be stored in string properties. When writing binary data to a string
	/// property it's stored in base64 format internally. The base64 algorithm converts arbitrary data
	/// into a read and printable string representation. As a result of this 3 bytes of arbitrary binary
	/// data will occupy 4 bytes of memory.
	///
	/// Reading binary data with this function obviously only makes sense if the property has been assigned
	/// the value by a previous call to <b>mvIMPACT::acquire::PropertyS::writeBinary</b>.
	/// However it allows to store any kind of data in a string property.
	/// This can e.g. be interesting when certain data shall be stored in the
	/// user accessible part of the devices non-volatile memory.
	/// \return The binary data representation of the specified property value as a new std::string object.
	std::string	readBinary(	/// The index of the value to get(if this property holds more then one value).
							int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		unsigned int bufSize = binaryDataBufferSize(index);
		if( bufSize > 0 )
		{
			char* pBuf = new char[bufSize];
			memset( pBuf, 0, bufSize );
			result = OBJ_GetBinary( m_hObj, pBuf, bufSize, index );
			std::string data( pBuf, bufSize );
			delete [] pBuf;
			if( result != PROPHANDLING_NO_ERROR )
			{
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
			}
			return data;
		}
		else
		{
			return std::string("");
		}
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	void
#else
	/// \brief Writes one value to the property.
	///
	/// This function writes a single value under index \a index to the property.
	///
	/// \return A const 'self' reference.
	const PropertyS&
#endif
						write(	/// The value to write to the property.
								const std::string& value,
								/// The index defining at which position to write the value.
								int index = 0 ) const
	{
		writeS(value, index );
		#ifndef DOTNET_ONLY_CODE
			return *this;
		#endif
	}
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	void
#else
	/// \brief Writes a set of values to the property.
	///
	/// This function writes a set of values starting at \a index to the property.
	///
	/// \return A const 'self' reference.
	const PropertyS&
#endif
						write(	/// An array containing the values to write to the property.
								const std::vector<std::string>& sequence,
								/// The index where to write the first value to the property.
								int index = 0 ) const
	{
		writeS(sequence, index );
		#ifndef DOTNET_ONLY_CODE
			return *this;
		#endif
	}
#ifndef WRAP_DOTNET
	/// \brief Writes a block of binary data to one entry of the property.
	///
	/// Binary data can only be stored in string properties. When writing binary data to a string
	/// property it's stored in base64 format internally. The base64 algorithm converts arbitrary data
	/// into a read and printable string representation. As a result of this 3 bytes of arbitrary binary
	/// data will occupy 4 bytes of memory.
	///
	/// Writing binary data with this function allows to store any kind of data in a string property.
	/// This can e.g. be interesting when certain data shall be stored in the
	/// user accessible part of the devices non-volatile memory.
	///
	/// \note
	/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
	/// <b>mvIMPACT::acquire::PropertyS::writeBinary</b> instead.
	/// \return A const 'self' reference.
	const PropertyS& writeBinary(	/// A pointer to the binary block of data that shall be stored by the
									/// this property.
									const char* pBuf,
									/// The size (in bytes) of the block of memory pointed to by \a pBuffer.
									unsigned int bufSize,
									/// The index defining at which position to write the value.
									int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetBinary( m_hObj, pBuf, bufSize, index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		return *this;
	}
#endif // #ifndef WRAP_DOTNET
#if defined(WRAP_DOTNET) || defined(DOTNET_ONLY_CODE)
	/// \brief Writes a block of binary data to one entry of the property.
	///
	/// Binary data can only be stored in string properties. When writing binary data to a string
	/// property it's stored in base64 format internally. The base64 algorithm converts arbitrary data
	/// into a read and printable string representation. As a result of this 3 bytes of arbitrary binary
	/// data will occupy 4 bytes of memory.
	///
	/// Writing binary data with this function allows to store any kind of data in a string property.
	/// This can e.g. be interesting when certain data shall be stored in the
	/// user accessible part of the devices non-volatile memory.
	void
#else
	/// \brief Writes a block of binary data to one entry of the property.
	///
	/// Binary data can only be stored in string properties. When writing binary data to a string
	/// property it's stored in base64 format internally. The base64 algorithm converts arbitrary data
	/// into a read and printable string representation. As a result of this 3 bytes of arbitrary binary
	/// data will occupy 4 bytes of memory.
	///
	/// Writing binary data with this function allows to store any kind of data in a string property.
	/// This can e.g. be interesting when certain data shall be stored in the
	/// user accessible part of the devices non-volatile memory.
	///
	/// \return A const 'self' reference.
	const PropertyS&
#endif
						writeBinary(	/// A const reference to the string holding the binary data that shall
										/// be stored by the this property.
										const std::string& value,
										/// The index defining at which position to write the value.
										int index = 0 ) const
	{
		TPROPHANDLING_ERROR result;
		if( ( result = OBJ_SetBinary( m_hObj, value.c_str(), static_cast<unsigned int>(value.size()), index ) ) != PROPHANDLING_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, m_hObj );
		}
		#ifndef DOTNET_ONLY_CODE
			return *this;
		#endif
	}
};

//-----------------------------------------------------------------------------
/// \brief A helper class that represents one entry in the devices non-volatile memory
/// (if available)
///
/// Each entry of user and device specific data consists of a name, data a property
/// defining the access rights for this entry and an optional password.
///
/// The name can be any string, but currently is limited to 255 characters.
///
/// The <b>mvIMPACT::acquire::UserDataEntry::data</b> property can hold any type of user data, that shall be
/// stored in the devices non-volatile memory. This can either be a string or binary
/// data. To store binary data the function
/// <b>mvIMPACT::acquire::PropertyS::writeBinary</b>
/// can be used. Internally however binary data will be stored as a base64 encoded string.
/// To read binary data from the property again the function
/// <b>mvIMPACT::acquire::PropertyS::readBinary</b>
/// must be called. The theoretical limit for the amount of data per entry is 2^16 (64KB) bytes,
/// however the real limit might be below this value because the device does not offer
/// that much memory.
///
/// The <b>mvIMPACT::acquire::UserDataEntry::access</b> property defines the access rights the user has when
/// working with the entry. After creation but before storing the entry into the device
/// this property can be modified. After storing the entry into the device by calling
/// <b>mvIMPACT::acquire::UserData::writeToHardware</b> this property will become <b>read-only</b>.
///
/// When the user creates a new entry for the user accessible device non-volatile memory
/// he can either create a read/write data set, which means that every user can modify
/// the \a data and the \a name property. In that case the property \a password is ignored.
/// Apart from that an entry that can only be modified when the correct password has been
/// written to the \a password property. To read a value is always allowed.
///
/// The \a password property will hold the user input and <b>NOT</b> the actual password needed
/// to unlock the data set. However when an entry has been created the creator afterwards can
/// write to the password. When the creator then calls the function <b>mvIMPACT::acquire::UserData::writeToHardware</b>
/// the value of the \a password property is used as the 'real' password from that
/// moment onwards.
///
/// The maximum length for the password is 255 characters currently. This does not
/// provide total security of cause, but the idea of the password is to hinder
/// the user from deleting an import entry by accident.
///
/// \note
/// There might be entries, that can't be modified by the user. These entries contain
/// important data that have been written to the memory during production. An attempt
/// to delete this data will fail.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLE:</b>
///
///\code
/// //-----------------------------------------------------------------------------
/// int storeUserData( Device* pDev, char* pData, size_t dataSize, const std::string& entryName )
/// //-----------------------------------------------------------------------------
/// {
///   UserData& userData = pDev->getUserData();
///   if( !userData.isAvailable() )
///   {
///     cout << "This device does not support user data" << endl;
///     return -1;
///   }
///
///   cout << "Available user memory(bytes):" << userData.memoryAvailable_bytes.read() << endl;
///   cout << "Memory consumed already(bytes): " << userData.memoryConsumed_bytes.read() << endl;
///
///   // create a new entry
///   UserDataEntry entry = userData.createEntry();
///   if( !entry.isValid() )
///   {
///     cout << "Failed to create new entry" << endl;
///     return -2;
///   }
///
///   string value( pData, dataSize );
///   entry.data.writeBinary( value );
///   entry.name.write( entryName );
/// 
///   // write to non-volatile memory (therefore the device MUST be closed)
///   if( pDev->isOpen() )
///   {
///     cout << "Can't store data as the device is already in use" << endl;
///     return -3;
///   }
///
///   userData.writeToHardware();
///   if( pDev->HWUpdateResult.read() != urSetUserDataWriteOK )
///   {
///     cout << "Failed to store data in device non-volatile memory" << endl;
///     return -4;
///   }
///
///   // now this data is stored in the devices permanent memory
///   return 0;
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///
/// \note
/// Instances of this class can only be created by the class <b>UserData</b>.
class UserDataEntry
//-----------------------------------------------------------------------------
{
	friend class UserData;
	HLIST m_hList;
	//-----------------------------------------------------------------------------
	explicit UserDataEntry( HLIST hList ) : m_hList(hList)
	//-----------------------------------------------------------------------------
	{
		if( hList != INVALID_ID )
		{
			ComponentLocator locator( hList );
			locator.bindComponent( name, "Name" );
			locator.bindComponent( data, "Data" );
			locator.bindComponent( access, "Access" );
			locator.bindComponent( password, "Password" );
		}
	}
public:
	/// \brief Call this function to check if this object references an
	/// existing entry.
	/// \return
	/// - true if this object references an existing entry
	/// - false otherwise
	bool isValid( void ) const { return ( ( m_hList != INVALID_ID ) && ( OBJ_CheckHandle( m_hList, hcmFull ) == PROPHANDLING_NO_ERROR ) ); }
	PYTHON_ONLY(%immutable;)
	/// \brief The name of the entry.
	///
	/// The maximum length for the name currently is 255 characters.
	PropertyS							name;
	/// \brief The data stored in this entry.
	///
	/// The theoretical limit for the amount of data per entry is 2^16 (64KB) bytes,
	/// however the real limit might be below this value because the device does not offer
	/// that much memory.
	///
	/// This property can either store string or binary data. See <b>mvIMPACT::acquire::PropertyS</b> to find
	/// out how to work with binary data.
	PropertyS							data;
	/// \brief The access rights for this entry.
	///
	/// After this entry has been written to the devices non-volatile memory, this property
	/// will become <b>read-only</b>.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TUserDataAccessRights</b>.
	PropertyIUserDataAccessRight		access;
	/// \brief The password needed to modify this entry.
	///
	/// The maximum length for the password is 255 characters currently. When the
	/// <b>mvIMPACT::acquire::TUserDataAccessRight::udarPassword</b> is not specified
	/// by the \a access property, this property will be ignored. Otherwise this
	/// property must have been assigned the correct password (case sensitive) before
	/// the \a name and \a data properties can be modified.
	PropertyS							password;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyS							getName( void ) const { return name; }
	PropertyS							getData( void ) const { return data; }
	PropertyIUserDataAccessRight		getAccess( void ) const { return access; }
	PropertyS							getPassword( void ) const { return password; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A helper class to work with the device specific non-volatile memory(if available).
///
/// A device might have a certain amount of non-volatile memory which can be accessed and modified by
/// the user. This data can e.g. be used to store certain parameters or custom data permanently into the
/// device. Thus this property e.g. allows to store configuration data in the device before shipping it
/// to the end user.
///
/// In theory the number of entries that can be stored in the device is not limited. However no device
/// will provide an unlimited amount of memory.
///
/// Writing data to any property of a <b>mvIMPACT::acquire::UserDataEntry</b> as well as creating a new entry by calling
/// <b>mvIMPACT::acquire::UserData::createEntry</b> or deleting an entry with the function
/// <b>mvIMPACT::acquire::UserData::deleteEntry</b> will <b>NOT</b> automatically result in
/// the complete data to be updated in the device specific memory. As writing to the device memory takes
/// a long (in terms of ms) time depending on the device architecture the modifications will only become.
/// permanent when calling <b>mvIMPACT::acquire::UserData::writeToHardware</b>.
///
/// If data at the end of the list of entries doesn't fit in the memory it will be discarded and therefore
/// will not be visible the next time the device is enumerated/accessed after the running process has
/// terminated or the device has been disconnected.
///
/// \note
/// Entries that contain no data will not be stored in hardware. If e.g. 5 user data entries have been created,
/// but only entry 0, 1, 2 and 4 contain data the write operation will pack the data in a way that when the user data
/// is read from the device again (when the driver for that device is loaded the next time) the list of entries
/// will contain elements at position 0, 1, 2 and 3 but <b>NOT</b> a index number 4. Deleting an entry from the middle
/// of the list of user data however will <b>NOT</b> move all remaining entries one step towards the front of the
/// list. Therefore during one session the entry indexes will <b>NOT</b> change. They can either become invalid (when
/// the corresponding entry has been deleted), can get valid (newly created entries will always appear at the next
/// free entry, thus deleting and entry and creating a new directly afterwards will create that entry at exactly the
/// same index) or new entries can appear (when a new entry has been created an no free list position in the
/// middle of the list of entries has been available).
///
/// \note
/// The device must be closed in order to write the user data. Check the property <b>mvIMPACT::acquire::Device::HWUpdateResult</b>
/// afterwards in order to make sure the data transfer was successful.
///
/// \note
/// If a device does not offer user accessible data <b>mvIMPACT::acquire::UserDataEntry</b> objects will still be returned by certain
/// functions. To check if this feature is available call <b>mvIMPACT::acquire::UserData::isAvailable</b>.
///
/// \note
/// If the user accessible data currently can't be modified an exception of type <b>mvIMPACT::acquire::ENoWriteRights</b>
/// will be thrown.
///
/// \note
/// Instances of this class cannot be constructed directly. To get access the function <b>mvIMPACT::acquire::Device::getUserData</b>.
/// must be used.
class UserData
//-----------------------------------------------------------------------------
{
	friend class Device;
	bool					m_boAvailable;
	HDEV					m_hDev;
	ComponentLocator		m_userDataEntryLocator;
	//-----------------------------------------------------------------------------
	explicit UserData( HDEV hDev ) : m_hDev(hDev), m_userDataEntryLocator( hDev )
	//-----------------------------------------------------------------------------
	{
		m_boAvailable = false;
		// check if user data is supported
		HOBJ hUserData = m_userDataEntryLocator.findComponent( "UserData" );
		if( hUserData != INVALID_ID )
		{
			Component userData(hUserData);
			// check if the driver supports the new enhanced user data access
			if( userData.isList() )
			{
				m_userDataEntryLocator.bindSearchBase( m_userDataEntryLocator.searchbase_id(), "UserData" );
				m_userDataEntryLocator.bindComponent( memoryAvailable_bytes, "MemoryAvailable_bytes" );
				m_userDataEntryLocator.bindComponent( memoryConsumed_bytes, "MemoryConsumed_bytes" );
				m_userDataEntryLocator.bindSearchBase( m_userDataEntryLocator.searchbase_id(), "Entries" );
				m_boAvailable = true;
			}
		}
	}
public:
	/// \brief Creates and returns a new entry to store user specific data.
	///
	/// \note
	/// The data handled by this object will not be stored permanently in the devices non-volatile
	/// memory until <b>mvIMPACT::acquire::UserData::writeToHardware</b> has been called successfully.
	///
	/// \sa
    /// <b>mvIMPACT::acquire::UserData::deleteEntry,<br>
	///	   mvIMPACT::acquire::UserData::writeToHardware</b>
	/// \return A new <b>mvIMPACT::acquire::UserDataEntry</b> instance, that can be user to store user specific data
	/// in the devices non-volatile memory.
	UserDataEntry createEntry( void )
	{
		HLIST hList;
		TDMR_ERROR result = DMR_CreateUserDataEntry( m_hDev, &hList );
		if( result != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result );
		}
		return UserDataEntry( hList );
	}
	/// \brief Deletes an entry of user specific data.
	///
	/// If the entry has been stored to the non-volatile memory already and has been assigned
	/// the <b>mvIMPACT::acquire::TUserDataAccessRight::udarPassword</b> flag, this call will fail, when
	/// <b>mvIMPACT::acquire::UserDataEntry::password</b> does not contain the correct password.
	/// \note
	/// The data handled by this object will not be removed permanently from the devices non-volatile
	/// memory until <b>mvIMPACT::acquire::UserData::writeToHardware( void ) const</b> has been called successfully.
	/// \sa
	/// <b>	mvIMPACT::acquire::UserData::createEntry,<br>
	///		mvIMPACT::acquire::UserData::writeToHardware</b>
	void deleteEntry(	/// A reference to the entry to delete
						UserDataEntry& userDataEntry )
	{
		TDMR_ERROR result = DMR_DeleteUserDataEntry( m_hDev, userDataEntry.m_hList );
		userDataEntry.m_hList = INVALID_ID;
		if( result != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result );
		}
	}
	/// \brief Returns An object to work with an existing entry of user specific data.
	///
	/// \note
	/// If an invalid number has been passed as \a nr an object will be returned as well. Therefore
	/// always check if the entry is valid by calling <b>mvIMPACT::acquire::UserDataEntry::isValid</b> before
	/// working with the object.
	///
	/// \return An object to work with an existing entry of user specific data.
	UserDataEntry getUserDataEntry(	/// The number of the entry to return
									int nr ) const
	{
		std::ostringstream oss;
		oss << "Entry" << nr;
		return UserDataEntry( m_userDataEntryLocator.findComponent( oss.str() ) );
	}
	/// \brief Fills an array with all currently valid user data entry indexes.
	///
	/// This function can be used to obtain a list of valid parameters for calls to the function <b>mvIMPACT::acquire::UserData::getUserDataEntry</b>.
	/// Every value in the returned array will (when passed to the function <b>mvIMPACT::acquire::UserData::getUserDataEntry</b>) result in a
	/// valid <b>mvIMPACT::acquire::UserDataEntry</b> object.
	void validUserDataEntryIndexes(	/// a reference to the array receiving the list of valid indexes
									std::vector<int>& sequence ) const
	{
		sequence.clear();
		ComponentIterator it(m_userDataEntryLocator.searchbase_id());
		if( !it.isValid() )
		{
			return;
		}
		it = it.firstChild();
		if( !it.isValid() )
		{
			return;
		}
		std::string::size_type indexStart = it.name().find_first_of( "0123456789" );
		while( it.isValid() )
		{
			sequence.push_back( atoi( it.name().substr( indexStart ).c_str() ) );
			++it;
		}
	}
	/// \brief This function should be called to check if this device offers non-volatile memory that can be accessed
	/// by the user.
	/// \return
	/// - true if the device offers non-volatile memory that can be accessed by the user
	/// - false otherwise
	bool isAvailable( void ) const { return m_boAvailable; }
	/// \brief Writes the current set of user data into the devices non-volatile memory.
	///
	/// This function might take a while. Depending on the device architecture and the amount of
	/// memory up to some hundred ms. Therefore make sure this function is not called more often
	/// then necessary to let your application perform efficiently.
	/// \sa
	/// <b> mvIMPACT::acquire::UserData::createEntry,<br>
	///		mvIMPACT::acquire::UserData::deleteEntry</b>
	void writeToHardware( void ) const
	{
		TDMR_ERROR result = DMR_WriteUserDataToHardware( m_hDev );
		if( result != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result );
		}
	}
	PYTHON_ONLY(%immutable;)
	/// \brief Returns the number of bytes of user accessible non-volatile memory this device offers
	///
	/// \return The number of bytes of user accessible non-volatile memory this device offers.
	PropertyI		memoryAvailable_bytes;
	/// \brief Returns the number of bytes of user accessible non-volatile memory currently consumed by the
	/// data stored by the user.
	///
	/// This doesn't indicate, that all the data has already been stored in the non-volatile memory,
	/// but is the number of bytes needed to store the current user data permanently. No check for
	/// overflows will be performed. If the user defined data exceeds the size of the available memory,
	/// this data will be lost when disconnecting or switching of the supply voltage for this device.
	///
	/// To write data permanently into the device call the function <b>mvIMPACT::acquire::UserData::writeToHardware</b>
	/// But even after calling this function data that exceeds the available memory will be lost when the
	/// device looses supply voltage and/or the process terminates.
	PropertyI		memoryConsumed_bytes;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI		getMemoryAvailable_bytes( void ) const { return memoryAvailable_bytes; }
	PropertyI		getMemoryConsumed_bytes( void ) const { return memoryConsumed_bytes; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief This class and its functions represent an actual <b>MATRIX VISION GmbH</b>
/// device detected in the current system.
///
/// Instances of it can only be created by instances of the <b>mvIMPACT::acquire::DeviceManager</b> class
/// as only the <b>mvIMPACT::acquire::DeviceManager</b> has the precise knowledge to do that anyway.
/// As a result from this fact pointers to instances of <b>mvIMPACT::acquire::Device</b> can be obtained
/// via a <b>mvIMPACT::acquire::DeviceManager</b> object only.
///
/// A valid pointer to a <b>mvIMPACT::acquire::Device</b> object is needed to construct most of the
/// other objects available in this interface.
///
/// Almost every object requiering a valid pointer to a <b>mvIMPACT::acquire::Device</b> object will
/// need to device in an initialised state as the properties provided e.g. by the
/// class <b>mvIMPACT::acquire::Settings</b> will be constructed when the device is initialised.
/// To initialise a device this class provides the function <b>Device::open</b>.
/// However every object which needs an initialised device to be constructed
/// successfully will try to open the device when it hasn't been opened before, so
/// the user does not need to call this function explicitly.
///
/// \note
/// <b>IMPORTANT:</b> Whenever a device is closed via a call to <b>mvIMPACT::acquire::Device::close</b>
/// all other objects constructed with a pointer to that device before will become
/// invalid an need to be reconstructed afterwards, so don't close a device needlessly.
///
/// \note
/// <b>IMPORTANT:</b> Whenever the last instance to a <b>DeviceManager</b> object get's
/// destroyed within the program every remaining device will be closed automatically!
/// Thus every instance to <b>mvIMPACT::acquire::Device</b> objects or objects created with a pointer to a
/// <b>mvIMPACT::acquire::Device</b> object will become invalid automatically.
/// Therefore the user has to make sure there is always at least one instance to a
/// <b>mvIMPACT::acquire::DeviceManager</b> object within the current process!
class Device
//-----------------------------------------------------------------------------
{
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	// only the DeviceManager is allowed to create Device objects, as it doesn't make
	// any sense for someone else anyway.
	friend class DeviceManager;	
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		HDEV		m_hDev;
		HDRV		m_hDrv;
		int			m_refCnt;
		ReferenceCountedData( HDEV hDev ) : m_hDev(hDev), m_hDrv(INVALID_ID), m_refCnt(1) {}
	} *m_pRefData;
	#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
	UserData m_userData;
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}
	//-----------------------------------------------------------------------------
	void bindPublicProperties( HDEV hDev )
	//-----------------------------------------------------------------------------
	{
		ComponentLocator locator(hDev);
		locator.bindComponent( allowUnrecommendedFeatures, "AllowUnrecommendedFeatures" );
		locator.bindComponent( deviceID, "DeviceID" );
		locator.bindComponent( family, "Family" );
		locator.bindComponent( firmwareVersion, "FirmwareVersion" );
		locator.bindComponent( loadSettings, "LoadSettings" );
		locator.bindComponent( product, "Product" );
		locator.bindComponent( state, "State" );
		locator.bindComponent( serial, "Serial" );
		locator.bindComponent( HWUpdateResult, "HWUpdateResult" );	
	}
	//-----------------------------------------------------------------------------
	explicit Device( HDEV hDev ) : m_userData(hDev)
	//-----------------------------------------------------------------------------
	{
		m_pRefData = new ReferenceCountedData(hDev);
		bindPublicProperties(hDev);
	}
public:
	/// \brief Copy constructor
	///
	/// Creates a new object from an existing device object. Keep in mind that this new object 
	/// will provide access to the very same hardware and there you might as well use the original
	/// reference returned from the <b>mvIMPACT::acquire::DeviceManager</b>. This constructor
	/// is only provided for internal reference counting to gurantee correct operation of the 
	/// objects of this class under all platforms and languages.
	explicit Device( const Device& src ) : m_pRefData(src.m_pRefData), m_userData(src.m_pRefData->m_hDev)
	{
		++(m_pRefData->m_refCnt);
		bindPublicProperties( m_pRefData->m_hDev );
	}
	/// \brief Class destructor
	///
	/// \note
	/// This destuctor must only be called for objects that have been created directly by
	/// the user on unmanaged heaps. Under most circumstances this means NEVER.
	~Device( void )	{ dealloc(); }
	/// \brief Closes an opened device.
	///
	/// This function closes a device previously opened again.
	///
	/// \sa
	/// <b>Device::open, <br>Device::isOpen</b>
	void close( void )
	{
		if( m_pRefData->m_hDrv != INVALID_ID )
		{
			DMR_CloseDevice( m_pRefData->m_hDrv, m_pRefData->m_hDev );
			m_pRefData->m_hDrv = INVALID_ID;
		}
	}
	/// \brief A unique identifier for this device.
	///
	/// \note
	/// This handle is <b>NOT</b> to be confused with the id stored in the devices EEPROM
	/// The latter one represents a number stored somewhere in the physical devices EEPROM, while
	/// this handle can be assumed as a handle from a software based point of view.
	HDEV hDev( void ) const { return m_pRefData->m_hDev; }
	/// \brief A unique identifier for the functionality offered by this
	/// device.
	///
	/// \note
	/// This identifier is only valid, if the device has been initialised
	/// before by a call to <b>Device::open</b>
	HDRV hDrv( void ) const { return m_pRefData->m_hDrv; }
	/// \brief Returns the current initialisation status
	///
	/// \sa
	/// <b>Device::open, <br>Device::close</b>
	/// \return
	/// - true if the device is currently initialised(opened).
	/// - false otherwise.
	bool isOpen( void ) const { return m_pRefData->m_hDrv != INVALID_ID; }
	/// \brief Opens a <b>MATRIX VISION GmbH</b> device
	///
	/// This function will try to open the device represented by this instance of
	/// <b>mvIMPACT::acquire::Device</b>. If this fails for any reason an exception will be thrown. The exception
	/// object will contain additional information about the reason for the error.
	///
	/// Calling this function is not really necessary, as each object for accessing
	/// other settings of the device or even the function interface need the device to
	/// be opened in order to be constructed. Therefore all the constructors for these
	/// objects check if the device is open by calling <b>mvIMPACT::acquire::Device::isOpen</b> and open
	/// the Device if necessary.
	///
	/// \note
	/// Keep in mind that the first object trying to open the device might therefore
	/// throw an exception as well when opening the devices fails for some reason.
	void open( void )
	{
		TDMR_ERROR result;
		if( ( result = DMR_OpenDevice( m_pRefData->m_hDev, &(m_pRefData->m_hDrv) ) ) != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, INVALID_ID, "Open device failed" );
		}
	}
	/// \brief Assigns a new ID to this device.
	///
	/// To allow any application to distinguish between different devices of the same
	/// type the user can assign an unique ID to each device using this function. This ID
	/// currently is limited to values between 0 and 250 and is stored in the devices
	/// internal memory. This ID is <b>NOT</b> volatile. It will remain stored even if
	/// the device is unplugged.
	///
	/// \note
	/// <b>REMARKS:</b>
	/// \note
	/// - The device must be <b>closed</b> to assign a new ID.
	/// - This ID is not to be confused with the handle returned by the function <b>mvIMPACT::acquire::Device::hDev</b>.
	/// The latter one represents something which can be assumed as a handle from a software based point
	/// of view, while the ID represented by the property <b>mvIMPACT::acquire::Device::deviceID</b> is an ID stored in the physical
	/// devices EEPROM.
	/// - Not every device will offer this feature! When calling this function for a device, that does not
	/// offer this feature the function will return <b>mvIMPACT::acquire::TDMR_ERROR::DMR_FEATURE_NOT_AVAILABLE</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Device::open, <br>mvIMPACT::acquire::Device::close</b>
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	setID( int newID ) const { return DMR_SetDeviceID( m_pRefData->m_hDev, newID ); }
	/// \brief Updates the firmware of the device.
	///
	/// calling this function will cause the driver to download the firmware version compiled
	/// into the driver library into the physical devices EEPROM.
	///
	/// \note
	/// <b>REMARKS:</b>
	/// \note
	/// - Be sure what you are doing <b>before</b> calling this function. Under normal circumstances
	/// it won't be necessary to update a devices firmware.
	/// - The download will take some time (depending on the device up to 30 seconds). During this time
	/// the device and the thread calling this function will <b>NOT</b> respond.
	/// - Do <b>NOT</b> interrupt this download.
	/// - After a successful download a USB device needs to be unplugged and plugged in again.
	/// Otherwise the new firmware version will not be activated.
	/// - To download a new firmware version the device must be <b>closed</b>.
	/// - Not every device will offer this feature! When calling this function for a device, that does not
	/// offer this feature the function will return <b>mvIMPACT::acquire::TDMR_ERROR::DMR_FEATURE_NOT_AVAILABLE</b>.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::Device::open, <br>mvIMPACT::acquire::Device::close</b>
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int updateFirmware( void ) const { return DMR_UpdateFirmware( m_pRefData->m_hDev ); }
	/// \brief Returns a reference to a helper class to handle user specific data stored in the devices
	/// non-volatile memory(if available).
	///
	/// \return A reference to a helper class to handle user specific data stored in the devices
	/// non-volatile memory(if available).
	UserData& getUserData( void ) { return m_userData; }
	PYTHON_ONLY(%immutable;)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
	/// \brief An enumerated integer property which can be used to unlock certain features available
	/// but not recommended by MATRIX VISION.
	///
	/// Valid values for this property are
	///
	/// - \a 1 or \a 0 when using the numerical read/write functions
	/// - \a Yes or \a No when working with strings
	///
	/// This property will be invisible by default. As the name indicates it's use requires special
	/// knowledge that can be provided by MATRIX VISION on request.
	///
	/// \note
	/// Once the device is in use (has been initialized) this property will become <b>(read-only)</b>.
	///
	/// \note
	/// <b>IMPORTANT:</b>
	/// Unlocking certain unrecommended features might result in the appearance of new translation 
	/// dictionary entries for certain properties. Some of these translation strings might contain 
	/// an exclamation mark ('!') in it's name. <b>NEVER</b> rely on that! These exclamation marks
	/// or even the complete entry might disappear with a new driver release without further notice!
	PropertyI allowUnrecommendedFeatures;
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
	/// \brief A string property <b>(read-only)</b> containing the device ID associated with this device.
	///
	/// A device ID can be used to identify a certain device in the system. The ID is an 8 bit unsigned
	/// integer value stored in the devices EEPROM. In order to allow the detection of a device
	/// distinct detection of a device via its device ID the user has to make sure, that two devices
	/// belonging to the same product family never share the same ID.
	///
	/// \note
	/// <b>REMARKS:</b>
	/// \note
	/// - To modify the device ID a separate tool will be provided. To modify the device
	/// ID without that tool the function <b>mvIMPACT::acquire::Device::setID</b> can be called.
	/// - This ID is not to be confused with the handle returned by the function <b>mvIMPACT::acquire::Device::hDev</b>.
	/// The latter one represents something which can be assumed as a handle from a software based point
	/// of view, while the ID represented by the property \a deviceID is an ID stored in the physical
	/// devices EEPROM.
	PropertyI deviceID;
	/// \brief A string property <b>(read-only)</b> containing the family name of this device.
	PropertyS family;
	/// \brief An integer property <b>(read-only)</b> containing the firmware version of this device.
	PropertyI firmwareVersion;
	/// \brief An enumerated integer property which can be used to define which previously stored setting to load when the device is opened.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceLoadSettings</b>.
	///
	/// \note
	/// Once the device is in use (has been initialized) this property will become <b>(read-only)</b>.
	PropertyIDeviceLoadSettings loadSettings;
	/// \brief A string property <b>(read-only)</b> containing the product name of this device.
	PropertyS product;
	/// \brief A string property <b>(read-only)</b> containing the serial number of this device.
	PropertyS serial;
	/// \brief An enumerated integer property <b>(read-only)</b> containing the current state of this device.
	///
	/// The state e.g. tells the user if an USB device is currently unplugged or not.
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceState</b>.
	PropertyIDeviceState state;
	/// \brief An enumerated integer property <b>(read-only)</b> defining user executed hardware update results.
	///
	/// This property e.g. might contain the result of a user executed firmware update.
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::THWUpdateResult</b>.
	PropertyIHWUpdateResult HWUpdateResult;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI							getAllowUnrecommendedFeatures( void ) const { return allowUnrecommendedFeatures; }
	PropertyI							getDeviceID( void ) const { return deviceID; }
	PropertyS							getFamily( void ) const { return family; }
	PropertyI							getFirmwareVersion( void ) const { return firmwareVersion; }
	PropertyIDeviceLoadSettings			getLoadSettings( void ) const { return loadSettings; }
	PropertyS							getProduct( void ) const { return product; }
	PropertyS							getSerial( void ) const { return serial; }
	PropertyIDeviceState				getState( void ) const { return state; }
	PropertyIHWUpdateResult				getHWUpdateResult( void ) const { return HWUpdateResult; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief Grants access to <b>MATRIX VISION GmbH</b> hardware.
///
/// This class will grant access to any <b>MATRIX VISION GmbH</b> hardware installed on the
/// current system. However so far only the <b>mvBlueFOX</b> is supported by this
/// interface. Whenever somewhere in the code a <b>mvIMPACT::acquire::DeviceManager</b> instance is
/// created it can be used to access any <b>MATRIX VISION GmbH</b> device currently
/// supported and available.<br><br> This is the only class, which is allowed to
/// create instances of the class <b>mvIMPACT::acquire::Device</b>, which are needed to access a certain
/// hardware device.
///
/// As a result of this almost every program written by the use of this interface
/// will create an instance of <b>mvIMPACT::acquire::DeviceManager</b> before performing any other
/// operation which uses object or functions from this interface.
///
/// During the construction of a <b>mvIMPACT::acquire::DeviceManager</b> object the system will be scanned
/// for supported devices and once the instance has been created the object will always
/// provide an up to date list of devices whenever the user asks for it.
///
/// This class also provides some functions to find a particular device in the system.
/// Devices can e.g. be found by family or by serial number.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLES:</b>
///
///\code
/// // Create an instance of the device manager to get access
/// // to MATRIX VISION GmbH devices.
/// DeviceManager devMgr;
///
/// // show all devices
/// for( unsigned int i=0; i<devMgr.deviceCount(); i++ )
/// {
///   cout << "Dev " << i << ": " << *(devMgr[i]) << endl;
/// }
///
/// // try to find a device using a special criteria 
/// // ( some of these calls will fail!!! )
/// // will fail as the string is not complete and does
/// // NOT terminate with a wildcard.
/// Device* pDev = devMgr.getDeviceBySerial( "SD0*0" );
/// // might work if there are at least two devices with 
/// // a matching serial number in the system.
/// pDev = devMgr.getDeviceByFamily( "SD0*0*", 1 );
/// // might work if there is at least one device whose type
/// // specifying string starts with 'SampleDevi'.
/// pDev = devMgr.getDeviceByProduct( "SampleDevi*" );
/// // will fail as the string is not complete and does NOT
/// // terminate with the user defined wildcard.
/// pDev = devMgr.getDeviceByProduct( "SampleD*", 0, '$' );
/// // will work if there is a device whose product name 
/// // starts with 'SamplePro' and which has
/// // been assigned the specified device ID.
/// pDev = devMgr.getDeviceByProductAndID( "SamplePro*", 66, '*' );
/// // will work if there is at least one device with a serial
/// // number starting with 'SD00' in the system.
/// pDev = devMgr.getDeviceBySerial( "SD00*" );
///
/// pDev = devMgr.getDeviceBySerial( "*" );
/// if( !pDev )
/// {
///   cout << "Error! No valid device found" << endl;
///   return 0;
/// }
///
/// // from here it will be save to work with the pointer returned
/// // by device manager.
/// FunctionInterface func( pDev );
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
/// \note
/// There always has to be at least one instance of the <b>DeviceManager</b> when
/// the user still works with <b>Device</b> objects, as when the last instance to
/// this object is destroyed all remaining <b>Device</b> objects will be closed
/// automatically!
///
/// \note
/// A <b>mvIMPACT::acquire::DeviceManager</b> object will initially return pointers to <b>mvIMPACT::acquire::Device</b> objects,
/// which all seem to be closed. However one or more of the devices might have been opened
/// by another instance of the device manager already or might even run in a different
/// process. In that case the attempt to open a device, which seems to be closed will raise
/// an exception with the error code <b>mvIMPACT::acquire::TDMR_ERROR::DMR_DRV_ALREADY_IN_USE</b>, which MUST
/// be handled by the user.
class DeviceManager
//-----------------------------------------------------------------------------
{
	typedef std::vector<Device*> DevVector;
	HDMR					m_deviceBaseList;
	mutable DevVector		m_devVector;
	mutable unsigned int	m_lastChangedCounter;
	int*					m_pRefCnt;
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(*m_pRefCnt);
		for( unsigned int i=0; i<m_devVector.size(); i++ )
		{
			if( *m_pRefCnt == 0 )
			{
				if( m_devVector[i]->isOpen() )
				{
					// no other device manager from this group of device managers refers to this opened device -> close it
					m_devVector[i]->close();
				}
			}
			delete m_devVector[i];
		}
		// free reference count memory if no one uses it anymore
		if( *m_pRefCnt == 0 )
		{
			delete m_pRefCnt;
		}
	}
	//-----------------------------------------------------------------------------
	Device*	getDevice( TDMR_DeviceSearchMode mode, const std::string& search_string, unsigned int devNr, char wildcard ) const
	//-----------------------------------------------------------------------------
	{
		updateInfoVector();
		Device* pResult = 0;
		HDEV device;
		if( DMR_GetDevice( &device, mode, search_string.c_str(), devNr, wildcard ) == DMR_NO_ERROR )
		{
			DevVector::size_type vSize = m_devVector.size();
			for( DevVector::size_type i=0; i<vSize; i++ )
			{
				if( m_devVector[i]->hDev() == device )
				{
					pResult = m_devVector[i];
					break;
				}
			}
		}
		return pResult;
	}
	//-----------------------------------------------------------------------------
	bool updateInfoVector( void ) const
	//-----------------------------------------------------------------------------
	{
		ComponentIterator iter(m_deviceBaseList);
		unsigned int changedCount = iter.changedCounter();
		if( m_lastChangedCounter == changedCount )
		{
			return false;
		}

		m_lastChangedCounter = changedCount;

		unsigned int curDevCnt = 0;
		size_t vSize = m_devVector.size();
		DMR_GetDeviceCount( &curDevCnt );
		if( curDevCnt <= static_cast<unsigned int>(vSize) )
		{
			return false;
		}

		HDEV hDev = INVALID_ID;
		for( size_t i=vSize; i<curDevCnt; i++ )
		{
			DMR_GetDevice( &hDev, dmdsmSerial, "*", static_cast<unsigned int>(i), '*' );
			if( hDev != INVALID_ID )
			{
				m_devVector.push_back( new Device(hDev) );
			}
		}
		return true;
	}
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::DeviceManager</b> object.
	///
	/// If the construction of this object fails for some reason this constructor
	/// might throw an exception of type <b>mvIMPACT::acquire::ImpactAcquireException</b> or a type
	/// derived from this class.
	explicit DeviceManager( void ) : m_lastChangedCounter(0)
	{
		TDMR_ERROR result;
		if( ( result = DMR_Init( &m_deviceBaseList ) ) != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, INVALID_ID, "DMR_Init failed" );
		}
		m_pRefCnt = new int();
		*m_pRefCnt = 1;
	}
	/// \brief Constructs a new <b>mvIMPACT::acquire::DeviceManager</b> object from an existing one.
	///
	/// If the construction of this object fails for some reason this constructor
	/// might throw an exception of type <b>mvIMPACT::acquire::ImpactAcquireException</b> or a type
	/// derived from this class.
	explicit DeviceManager( const DeviceManager& src ) : m_lastChangedCounter(0), m_pRefCnt(src.m_pRefCnt)
	{
		// we don't need to copy data as the necessary updates are done anyway.
		// But have call the underlying C-API.
		TDMR_ERROR result;
		if( ( result = DMR_Init( &m_deviceBaseList ) ) != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, INVALID_ID, "DMR_Init failed" );
		}
		++(*m_pRefCnt);
	}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::DeviceManager</b> objects
	DeviceManager& operator=( const DeviceManager& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefCnt = rhs.m_pRefCnt;
			// inc. the NEW reference count
			++(*m_pRefCnt);
			// this will fill the device vector with up to date data the next time someone asks
			// for a device.
			m_lastChangedCounter = 0;
			m_devVector.clear();
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	/// \brief Class destructor.
	///
	/// There always has to be at least one instance of the <b>DeviceManager</b> when
	/// the user still works with <b>mvIMPACT::acquire::Device</b> objects, as when the last instance to
	/// this object is destroyed all remaining <b>mvIMPACT::acquire::Device</b> objects will be closed
	/// automatically!
	virtual ~DeviceManager( void )
	{
		dealloc();
		DMR_Close();
	}
#ifndef WRAP_PYTHON
	/// \brief Returns a pointer to a <b>mvIMPACT::acquire::Device</b> object.
	///
	/// Returns a pointer to a <b>mvIMPACT::acquire::Device</b> object specifying the device found at the given
	/// index in the device managers internal list.
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html	
	/// If the index is either equal or higher then the number of devices detected<br>
	/// a STL out_of_range exception is thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>mvIMPACT::acquire::DeviceManager::deviceCount,<br>
	/// mvIMPACT::acquire::DeviceManager::getDeviceBySerial,<br>
	/// mvIMPACT::acquire::DeviceManager::getDeviceByFamily,<br>
	/// mvIMPACT::acquire::DeviceManager::getDeviceByProduct</b>
	/// \return 
	/// - A pointer to the device if found.
	/// - an invalid pointer or reference otherwise.
	Device* operator[]( /// the index of the device to be returned
						unsigned int index ) const { return getDevice(index); }
#endif // #ifndef WRAP_PYTHON  (In Python, use public method getDevice)
	/// \brief Returns the current changed counter for the device list.
	///
	/// This is a useful function to find out if the device list has been changed in any
	/// way. Such a change might be the appearance of a new USB device or a state change
	/// of any other device (e.g. when an USB device has been unplugged). Thus this function
	/// can be called periodically in order to maintain lists in GUI application for example.
	/// To find out the actual number of devices call <b>mvIMPACT::acquire::DeviceManager::deviceCount</b>.
	/// \return The current changed counter for the device list.
	unsigned int changedCount( void ) const { return Component(m_deviceBaseList).changedCounter(); }
	/// \brief Returns the number of devices currently present in the system.
	///
	/// This function returns the number of devices currently detected in the system. An USB
	/// device once connected to the system while the device manager was running will remain
	/// in its list even if it's unplugged (then only it's state will change). To detect
	/// changes in the <b>mvIMPACT::acquire::DeviceManager</b> objects list call the function
	/// <b>mvIMPACT::acquire::DeviceManager::changedCount</b>.
	/// \return The number of devices detected in the current system.
	unsigned int deviceCount( void ) const
	{
		updateInfoVector();
		return static_cast<unsigned int>( m_devVector.size() );
	}
	/// \brief Returns a pointer to a <b>mvIMPACT::acquire::Device</b> object.
	///
	/// Returns a pointer to a <b>mvIMPACT::acquire::Device</b> object specifying the device found at the given
	/// index in the device managers internal list.
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// If the index is either equal or higher then the number of devices detected
	/// a STL out_of_range exception is thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>DeviceManager::deviceCount,<br>
	/// DeviceManager::getDeviceBySerial,<br>
	/// DeviceManager::getDeviceByFamily,<br>
	/// DeviceManager::getDeviceByProduct</b>
	/// \return<br>
	/// - A pointer to the device if found.<br>
	/// - an invalid pointer or reference otherwise.
	Device*	getDevice(	/// the index of the device to be returned
						unsigned int index ) const
	{
		updateInfoVector();
		return m_devVector.at(index);
	}
	/// \brief Tries to locate a device via the serial number.
	///
	/// This function tries to find a device by its serial number (or parts of this number).
	/// The user can specify only parts of the serial number and a wildcard. The <b>mvIMPACT::acquire::DeviceManager</b>
	/// object will then try to find that matches these parameters in its current list.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLES:</b>
	///
	///\code
	/// // this will return a pointer to the second device with
	/// // a serial number starting with 'SD' device found or 0
	/// // if there are no 2 sample devices in the system
	/// getDeviceBySerial( "SD*******", 1, '*' );
	/// // will return a pointer to the device with the serial 
	/// // number SD000001 if present or 0
	/// getDeviceBySerial( "SD0000001" );
	/// // will return a pointer to the first device in the system
	/// getDeviceBySerial( "*", 0, '*' );
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>DeviceManager::getDeviceByFamily,<br>
	/// DeviceManager::getDeviceByProduct,<br>
	/// DeviceManager::getDeviceByProductAndID</b>
	/// \return<br>
	/// - A pointer to the device if found.<br>
	/// - an invalid pointer or reference otherwise.
	Device*	getDeviceBySerial( /// The full serial number or the known parts of the serial number and wildcard characters
							   const std::string& serial = "",
							   /// The number of the device to return (if there is more then one candidate)
							   unsigned int devNr = 0,
							   /// The character to ignore in \a serial
							   char wildcard = '*' ) const { return getDevice( dmdsmSerial, serial, devNr, wildcard ); }
	/// \brief Tries to locate a device via the family name.
	///
	/// This function tries to find a device by its family (or parts of this family name).
	/// The user can specify only parts of the family name and a wildcard. The <b>mvIMPACT::acquire::DeviceManager</b>
	/// object will then try to find the device that matches these parameters in its current list.
	/// The family is the most general method of searching for a device apart from 'any device'.
	/// E.g. for a device the family name might be 'SampleDevice'
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLES:</b>
	///
	///\code
	/// // this will return a pointer to the second 'SampleDevice'
	/// // device found or 0 if there are no 2 'SampleDevice' 
	/// // devices in the system
	/// getDeviceByFamily( "SampleD*", 1, '*' );
	/// // will return a pointer to the first device belonging 
	/// // to the 'SampleDevice' family if present or 0.
	/// getDeviceByFamily( "SampleDevice" );
	/// // will return the first recognized device in the system
	/// getDeviceByFamily( "*", 0, '*' );
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>mvIMPACT::acquire::DeviceManager::getDeviceBySerial,<br>
	/// mvIMPACT::acquire::DeviceManager::getDeviceByProduct,<br>
	/// mvIMPACT::acquire::DeviceManager::getDeviceByProductAndID</b>
	/// \return<br>
	/// - A pointer to the device if found.<br>
	/// - an invalid pointer or reference otherwise.
	Device*	getDeviceByFamily( /// The full family name of the requested device or known parts of it and wildcard characters
							   const std::string& family = "",
							   /// The number of the device to return (if there is more then one candidate)
							   unsigned int devNr = 0,
							   /// The character to ignore in \a family
							   char wildcard = '*' ) const { return getDevice( dmdsmFamily, family, devNr, wildcard ); }
	/// \brief Tries to locate a device via the product name.
	///
	/// This function tries to find a device by its product name (or parts of it).
	/// The user can specify only parts of the name and a wildcard. The <b>mvIMPACT::acquire::DeviceManager</b>
	/// object will then try to find the device that matches these parameters in its current list.
	/// The product name is a bit more specific then the family name, but less specific then
	/// the serial. For the 'SampleDevice' for example there might be different product names for different
	/// device types. This might e.g. be 'SampleDevice-G' for a grey version of the sample device and
	/// 'SampleDevice-C' for the color version of the sample device.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLES:</b>
	///
	///\code
	/// // this will return a pointer to the second sample 
	/// // device of type 'G' found or 0 if there aren't 
	/// // two devices of this type in the system
	/// getDeviceByProduct( "SampleDevice-G", 1 );
	/// // will return a pointer to the first device whose 
	/// // product string starts with 'SampleDev' or 0 if 
	/// // no such device can be found.
	/// getDeviceByProduct( "SampleDev*", 0, '*' );
	/// // will return the first recognized device in the system
	/// getDeviceByProduct( "*", 0, '*' );
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>DeviceManager::getDeviceBySerial,<br>
	/// DeviceManager::getDeviceByFamily,<br>
	/// DeviceManager::getDeviceByProductAndID</b>
	/// \return<br>
	/// - A pointer to the device if found.<br>
	/// - an invalid pointer or reference otherwise.
	Device*	getDeviceByProduct( /// The full product name of the requested device or known parts of it and wildcard characters
								const std::string& product = "",
								/// The number of the device to return (if there is more then one candidate)
								unsigned int devNr = 0,
								/// The character to ignore in \a product
								char wildcard = '*' ) const { return getDevice( dmdsmProduct, product, devNr, wildcard ); }
	/// \brief Tries to locate a device via the product name and the device ID.
	///
	/// This function behaves like
	/// <b>mvIMPACT::acquire::DeviceManager::getDeviceByProduct</b>
	/// except that the second parameter now is interpreted as the device ID.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLES:</b>
	///
	///\code
	/// // this will return a pointer to the sample device of 
	/// // type 'G' which has been assigned a device ID of '1' 
	/// // or 0 if there is no sample device with this ID in the system.
	/// getDeviceByProductAndID( "SampleDevice-G", 1 );
	/// // will return a pointer to the device whose product string
	/// // starts with 'SampleDev' and whose device ID has been set
	/// // to '0' or 0 if no such device can be found.
	/// getDeviceByProductAndID( "SampleDev*", 0, '*' );
	/// // will return the first recognized device with an assigned 
	/// // device ID of '0' in the system.
	/// getDeviceByProductAndID( "*", 0 );
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \sa
	/// <b>Device::deviceID,<br>
	/// DeviceManager::getDeviceByFamily,<br>
	/// DeviceManager::getDeviceByProduct,<br>
	/// DeviceManager::getDeviceBySerial,<br>
	/// Device::setID</b>
	/// \return<br>
	/// - A pointer to the device if found.<br>
	/// - an invalid pointer or reference otherwise.
	Device*	getDeviceByProductAndID(	/// The full product name of the requested device or known parts of it and wildcard characters
										const std::string& product = "",
										/// The ID associated with this device.
										unsigned int devID = 0,
										/// The character to ignore in \a product
										char wildcard = '*' ) const { return getDevice( static_cast<TDMR_DeviceSearchMode>( dmdsmProduct | dmdsmUseDevID ), product, devID, wildcard ); }
};

//-----------------------------------------------------------------------------
/// \brief Defines valid interface list types, which can be located using an
/// instance of <b>mvIMPACT::acquire::DeviceComponentLocator</b>.
enum TDeviceListType
//-----------------------------------------------------------------------------
{
	/// \brief Specifies a certain setting.
	///
	/// An additional string defines the name of the setting to look for.
	dltSetting = dmltSetting,
	/// \brief Specifies the list of driver owned image request objects.
	dltRequest = dmltRequest,
	/// \brief Specifies a certain image request control.
	///
	/// An additional string defines the name of the setting to look for.
	dltRequestCtrl = dmltRequestCtrl,
	/// \brief Specifies the driver interfaces list containing general information.
	///
	/// This e.g. can be properties containing the driver version, the current state
	/// of the device and stuff like that.
	dltInfo = dmltInfo,
	/// \brief Specifies the driver interface list containing statistical information.
	///
	/// This list e.g. might contain the current frame rate, the total number of images 
	/// captured, etc..
	dltStatistics = dmltStatistics,
	/// \brief Specifies the driver interface list containing properties, which influence
	/// the overall operation of the device.
	///
	/// This list e.g. might contain the priority of the drivers internal worker thread,
	/// the number of request objects the driver shall work with, etc..
	dltSystemSettings = dmltSystemSettings,
	/// \brief Specifies the driver interface list containing properties to work with any
	/// kind of I/O pin belonging to that device.
	///
	/// Here properties addressing the digital inputs and outputs and other I/O related
	/// properties can be found.
	dltIOSubSystem = dmltIOSubSystem,
	/// \brief Specifies the driver interface list providing access to the drivers <b>H</b>ardware <b>R</b>eal-<b>T</b>ime <b>C</b>ontroller (HRTC).
	///
	/// Here properties to control the behaviour of the HRTCs can be found.
	/// \note
	/// This feature might not be available for every device. 
	dltRTCtr = dmltRTCtr,
	/// \brief Specifies the driver interface list providing access to the recognized camera description
	/// lists.
	///
	/// Within this list all recognized camera descriptions can be found, each forming a sub list 
	/// containing the properties describing the camera.
	///
	/// \note This feature is only available for frame grabber devices currently.
	dltCameraDescriptions = dmltCameraDescriptions,
	/// \brief Specifies the driver interface list providing access to the device specific settings
	/// lists.
	///
	/// \note This feature currently is only available for frame grabber devices.
	dltDeviceSpecificData = dmltDeviceSpecificData
};

//-----------------------------------------------------------------------------
/// \brief A class to locate components within the driver.
/// 
/// Every driver will offer a set of properties, methods and component lists.
/// <b>mvIMPACT::acquire::Property</b> objects contain data such as the current gain in dB, the state of a
/// digital input, etc.. <b>mvIMPACT::acquire::Method</b> objects can be executed like a normal function and
/// <b>mvIMPACT::acquire::ComponentList</b> objects are used to group certain
/// objects together to form a logical unit.
///
/// When it's neccessary to locate one or more of these objects without knowing
/// exactly where to look for them this locator class can be used to look for the component.
///
/// In general the properties interessting for the user can be found in one of the
/// classes offered by this interface, but when a special property is needed or a 
/// new property, that hasn't been embedded into the C++ interface, this class offers
/// a way to get hold of its handle.
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLE:</b>
///
///\code
/// // assuming a new property 'MyProp' has been added to the setting of a 
/// // device driver whos product string is 'MyDevice' and it has not been 
/// // added to the corresponding class or the property shall be accessed
/// // without rebuilding the application.
/// // The latter situation will require some kind of interpreter that
/// // can pass the required information to the device driver
/// //-----------------------------------------------------------------------------
/// enum TMyEnumType
/// //-----------------------------------------------------------------------------
/// {
///   metOne = 0,
///   metTwo,
///   metThree
/// };
///
/// //-----------------------------------------------------------------------------
/// void fn( void )
/// //-----------------------------------------------------------------------------
/// {
///   DeviceManager devMgr;
///   Device* pDev = devMgr.getDeviceByProduct( "MyDev*" );
///   if( pDev )
///   {
///     // get access to the base setting
///     DeviceComponentLocator locator(pDev, dltSetting, "Base");
///     Property prop;
///     locator.bindComponent( prop, "MyProp" );
///     // set the value by string
///     prop.writeS( "MyVal" );
///     if( prop.type() == ctPropInt )
///     {
///       PropertyI iProp;
///       int myVal = 666;
///       iProp.write( myVal );
///     }
///     // if the type is known this test can be omitted:
///     PropertyF fProp;
///     locator.bindComponent( fProp, "MyFloatProperty" );
///     fProp.write( 3.14 );
///
///     // When it's an enumerated property this is legal as well:
///     typedef EnumPropertyI<TMyEnumType> PropertyIMyEnumType;
///     PropertyIMyEnumType eProp;
///     locator.bindComponent( eProp, "MyEnumeratedProperty" );
///     prop.write( metOne );
///   }
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///
class DeviceComponentLocator : public ComponentLocatorBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new unbound locator.
	explicit DeviceComponentLocator() : ComponentLocatorBase() {}
	/// \brief Constructs a new bound to the specified base list locator.
	explicit DeviceComponentLocator(	/// A unique identifier to the base list from where to start to search for
										/// the search base.
										HLIST baselist ) : ComponentLocatorBase(baselist) {}
	/// \brief Constructs a new locator and searches the search base list.
	explicit DeviceComponentLocator(	/// A unique identifier to the base list from where to start to search for
										/// the search base.
										HLIST baselist,
										/// The name or path ('/' separated) to the search base.
										const std::string& pathToSearchBase ) : ComponentLocatorBase(baselist, pathToSearchBase) {}
	/// \brief Contstructs a new locator and bind the search base to the specified list type of the device.
	explicit DeviceComponentLocator(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from
										/// a <b>mvIMPACT::acquire::DeviceManager</b> object. 
										Device* pDev,
										/// The type list to locate
										TDeviceListType deviceListType,
										/// A string that can contain the name of the list if there
										/// is more then one candidate (e.g. when looking for settings)
										const std::string& sublistName = "" ) : ComponentLocatorBase()
	{
		bindSearchBaseList( pDev, deviceListType, sublistName );
	}
	/// \brief Assign a new search base to the locator.
	///
	/// This new search base will be search starting from the base list specified.
	/// \return The unique identifier of the new search base.
	HLIST bindSearchBaseList(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from
								/// a <b>mvIMPACT::acquire::DeviceManager</b> object. 
								Device* pDev,
								/// The type list to locate
								TDeviceListType deviceListType,
								/// The name or path to the search base.
								const std::string& sublistName = "" )
	{
		if( !pDev->isOpen() )
		{
			pDev->open();
		}

		HLIST hList;
		TDMR_ERROR result;
		if( ( result = DMR_FindList( pDev->hDrv(), ( sublistName.length() == 0 ) ? 0 : sublistName.c_str(), static_cast<TDMR_ListType>(deviceListType), 0, &hList ) ) != DMR_NO_ERROR )
		{
			std::ostringstream oss;
			oss << "Couldn't find list " << sublistName << "(type: " << deviceListType << ")";
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, INVALID_ID, oss.str() );
		}
		bindSearchBase( hList );
		return searchbase_id();
	}
};

//-----------------------------------------------------------------------------
/// \brief A wrapper class to handle <b>mvIMPACT::acquire::ImageBuffer</b> structures.
///
/// This class acts as a simple wrapper to handle <b>mvIMPACT::acquire::ImageBuffer</b> structures.
/// using this class the user is no longer responsible for the memory management
/// of <b>mvIMPACT::acquire::ImageBuffer</b> structures.
///
/// Instances of this class are reference counted. Memory is freed once the last instance
/// to it is destroyed. For details read the corresponding sections in the documentation
/// of the various constructors and function belonging to this class.
class ImageBufferDesc
//-----------------------------------------------------------------------------
{
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	friend class Request;
	friend class ImageProcessingBase;
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		int				m_refCnt;
		bool			m_boBufferAllocated;
		ImageBuffer*	m_pBuffer;
		ReferenceCountedData( bool boAllocated = false, ImageBuffer* pBuffer = 0 )
			: m_refCnt(1), m_boBufferAllocated(boAllocated), m_pBuffer(pBuffer) {}
		~ReferenceCountedData()
		{
			if( m_pBuffer )
			{
				if( m_boBufferAllocated )
				{
					DMR_ReleaseImageBuffer( &m_pBuffer );
				}
				else
				{
					DMR_ReleaseImageRequestBufferDesc( &m_pBuffer );
				}
			}
		}
	} *m_pRefData;
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}
	explicit ImageBufferDesc( bool boAllocated, ImageBuffer* pBuf ) : m_pRefData(new ImageBufferDesc::ReferenceCountedData(boAllocated, pBuf)) {}
	#endif // DOXYGEN_SHOULD_SKIP_THIS
public:
#ifndef WRAP_DOTNET
	/// \brief Constructs a new <b>mvIMPACT::acquire::ImageBufferDesc</b> from an existing one.
	///
	/// The image buffer associated with this descriptor will not be copied! The internal
	/// data will be reference counted and changing this new object will also affect the
	/// original one. The internal data is freed when the last descriptor referencing the
	/// image is destroyed.
	ImageBufferDesc(	/// The source buffer descriptor.
						const ImageBufferDesc& source ) : m_pRefData(source.m_pRefData)
	{
		++(m_pRefData->m_refCnt);
	}
#endif // #ifndef WRAP_DOTNET
	/// \brief Constructs a new <b>mvIMPACT::acquire::ImageBufferDesc</b> object with \a channelCount channel specific
	/// data elements.
	///
	/// This constructor does <b>NOT</b> allocate memory for the actual pixel data but only for the
	/// a structure describing an image.
	explicit ImageBufferDesc(	/// The number of channel specific data elements to allocate
								/// memory for.
								int channelCount ) : m_pRefData(new ImageBufferDesc::ReferenceCountedData())
	{
		DMR_AllocImageRequestBufferDesc( &(m_pRefData->m_pBuffer), channelCount );
	}
	/// \brief Constructs a new <b>mvIMPACT::acquire::ImageBufferDesc</b> object and allocates all memory needed.
	///
	/// This constructor will allocate and handle a new and complete <b>ImageBuffer</b> object including
	/// memory for the pixel data for the given pixel format.
	///
	/// The size(in bytes) of allocated pixel memory will depend on the \a pixelFormat as well as on the
	/// parameters \a width and \a height. <b>mvIMPACT::acquire::ImageBuffer::iSize</b> will return the
	/// amount of memory allocated for the buffer.
	explicit ImageBufferDesc(	/// The desired pixel format for the new <b>mvIMPACT::acquire::ImageBuffer</b>
								/// object handled by this descriptor.
								TImageBufferPixelFormat pixelFormat,
								/// The width of the new <b>mvIMPACT::acquire::ImageBuffer</b> object handled
								/// by this descriptor.
								int width,
								/// The height of the new <b>mvIMPACT::acquire::ImageBuffer</b> object handled
								/// by this descriptor.
								int height ) : m_pRefData(new ImageBufferDesc::ReferenceCountedData())
	{
		DMR_AllocImageBuffer( &(m_pRefData->m_pBuffer), pixelFormat, width, height );
	}
	/// \brief De-allocates all managed memory again when this is the last object referencing the
	/// image.
	~ImageBufferDesc() { dealloc(); }
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of two different <b>mvIMPACT::acquire::ImageBufferDesc</b>
	///
	/// The image buffer associated with this descriptor will not be copied! The internal
	/// data will be reference counted and changing this new object will also affect the
	/// original one. The internal data is freed when the last descriptor referencing the
	/// image is destroyed.
	ImageBufferDesc& operator=( const ImageBufferDesc& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefData = rhs.m_pRefData;
			++(m_pRefData->m_refCnt);
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	/// \brief Returns a deep copy of the <b>mvIMPACT::acquire::ImageBuffer</b> object referenced by this descriptor.
	///
	/// This function will create a deep copy of the <b>mvIMPACT::acquire::ImageBuffer</b> object referenced by this
	/// descriptor. Afterwards modifying one of the images will <b>NOT</b> influence the other one.
	///
	/// \return A deep copy of the <b>mvIMPACT::acquire::ImageBuffer</b> object referenced by this descriptor.
	ImageBufferDesc	clone( void ) const
	{
		ImageBuffer* pDst = 0;
		DMR_CopyImageBuffer( m_pRefData->m_pBuffer, &pDst, 0 );
		return ImageBufferDesc(true, pDst);
	}
	/// \brief Grants access to the underlying <b>mvIMPACT::acquire::ImageBuffer</b> structure managed by this object.
	///
	/// \return A pointer to the <b>mvIMPACT::acquire::ImageBuffer</b> object referenced by this descriptor.
	ImageBuffer* getBuffer( void ) const { return m_pRefData->m_pBuffer; }
};

//-----------------------------------------------------------------------------
/// \brief Contains information about a captured image.
///
/// This class provides access to all sorts of information about the captured image.
/// Only Instances of <b>mvIMPACT::acquire::FunctionInterface</b> are allowed to create objects of <b>mvIMPACT::acquire::Request</b>.
/// Consequently the only way to get access to a <b>mvIMPACT::acquire::Request</b> object is via a call to
/// <b>mvIMPACT::acquire::FunctionInterface::getRequest</b>.
///
/// A <b>mvIMPACT::acquire::Request</b> represents an object used by the driver to fill its internal job
/// queues. Whenever an image shall be captured a <b>mvIMPACT::acquire::Request</b> is send to the driver
/// and the hardware then tries to capture the desired image as fast as possible.
///
/// Requests are managed by the driver. The only thing the user needs to configure is the
/// maximum number of requests he wants the driver to work with. To make sure a
/// certain number of requests are available the function
/// <b>mvIMPACT::acquire::FunctionInterface::ensureRequests</b> can be used.
/// This can be useful for time critical applications where the hardware can capture
/// images in the background, while the PC performs other tasks. In that case its
/// necessary to make sure, that the request queue never runs low to ensure loss less
/// image acquisition.
class Request
//-----------------------------------------------------------------------------
{
	// only the function interface object is allowed to create new requests as
	// it maintains an internal reference to each request created.
	friend class FunctionInterface;
	int										m_requestNr;
	mutable ImageBufferDesc					m_imageBufferDesc;
	mutable RequestInfo						m_requestInfo;
	mutable RequestResult					m_requestResult;
	HDRV									m_hDrv;
	explicit								Request( HDRV hDrv, int requestNr ) : m_requestNr(requestNr), m_imageBufferDesc(1), m_hDrv(hDrv) {}
public:
	/// \brief Returns a const reference to the <b>mvIMPACT::acquire::RequestInfo</b> structure of this request.
	///
	/// The referenced <b>mvIMPACT::acquire::RequestInfo</b> structure contains additional information about
	/// the image, e.g. a timestamp that defines the time this image has been taken with.
	///
	/// \note
	/// Here the same as for the function <b>mvIMPACT::acquire::Request::getResult</b> applies regarding
	/// the fact, that the const reference returned by this function shall never be stored
	/// for the next request as well.
	const RequestInfo& getInfo(	void ) const
	{
		// 'old' downward compatible version
		DMR_GetImageRequestInfo( m_hDrv, m_requestNr, &m_requestInfo );
		return m_requestInfo;
	}
	/// \brief Returns a const reference to the <b>mvIMPACT::acquire::RequestInfo</b> structure of this request.
	///
	/// The referenced <b>mvIMPACT::acquire::RequestInfo</b> structure contains additional information about
	/// the image, e.g. a timestamp that defines the time this image has been taken with.
	///
	/// \note
	/// Here the same as for the function <b>mvIMPACT::acquire::Request::getResult</b> applies regarding
	/// the fact, that the const reference returned by this function shall never be stored
	/// for the next request as well.
	const RequestInfo& getInfo(	/// This parameter is provided for downward compatibility only. When developing
								/// a new application 'true' should be passed to this function, but when using this
								/// function at least version 1.5.1.x of the mvDeviceManager-lib is required on every target
								/// machine this executable shall run on.
								///
								/// When passing 'false' to the function, only the values for
								/// - frameID
								/// - frameNr
								/// - exposeStart_us
								/// - exposeTime_us
								/// - transferDelay_us
								/// - gain_dB
								///
								/// will be updated in the returned structure.
								bool boGetFullInfo ) const
	{
		if( boGetFullInfo )
		{
			// 'new' version, providing more information, but also requires at least version 1.5.1.x of the mvDeviceManager-lib
			DMR_GetImageRequestInfoEx( m_hDrv, m_requestNr, &m_requestInfo, sizeof(m_requestInfo), 0, 0 );
		}
		else
		{
			// 'old' downward compatible version
			getInfo();
		}
		return m_requestInfo;
	}
	/// \brief Returns a const reference to the <b>mvIMPACT::acquire::RequestResult</b> of this request.
	///
	/// This function returns a const reference to the <b>mvIMPACT::acquire::RequestResult</b> of this
	/// <b>mvIMPACT::acquire::Request</b>.
	/// \note
	/// Please do <b>NOT</b> store this reference in some variable to use it for the
	/// evaluation of the next <b>mvIMPACT::acquire::Request</b> as well, as this will not work. Whenever
	/// <b>mvIMPACT::acquire::Request::getResult</b> is called the function will make sure
	/// that the data in the returned structure is up to date while when working with
	/// an old reference to the <b>mvIMPACT::acquire::RequestResult</b> structure the data in the structure
	/// might refer to a previous result. 
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// So do <b>NOT</b> write code like this:
	///\code
	/// FunctionInterface fi( pDev );
	/// fi.imageRequestSingle();
	/// int requestNr = fi.imageRequestWaitFor( 500 );
	/// const RequestResult& rr = fi.getRequest( requestNr );
	/// fi.imageRequestUnlock( requestNr );
	/// while( !terminated )
	/// {
	///   fi.imageRequestSingle();
	///   int requestNr = fi.imageRequestWaitFor( 500 );
	///   if( rr.result == rrOK ) // This is an ERROR, as the result might be old!!! Never do this.
	///   {
	///     // process result
	///   }
	///   fi.imageRequestUnlock( requestNr );
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	const RequestResult& getResult(	void ) const
	{
		DMR_GetImageRequestResult( m_hDrv, m_requestNr, &m_requestResult );
		return m_requestResult;
	}
	/// \brief Returns a const reference to the <b>mvIMPACT::acquire::RequestResult</b> of this request.
	///
	/// This function returns a const reference to the <b>mvIMPACT::acquire::RequestResult</b> of this
	/// <b>mvIMPACT::acquire::Request</b>.
	/// \note
	/// Please do <b>NOT</b> store this reference in some variable to use it for the
	/// evaluation of the next <b>mvIMPACT::acquire::Request</b> as well, as this will not work. Whenever
	/// <b>mvIMPACT::acquire::Request::getResult</b> is called the function will make sure
	/// that the data in the returned structure is up to date while when working with
	/// an old reference to the <b>mvIMPACT::acquire::RequestResult</b> structure the data in the structure
	/// might refer to a previous result. 
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// So do <b>NOT</b> write code like this:
	///\code
	/// FunctionInterface fi( pDev );
	/// fi.imageRequestSingle();
	/// int requestNr = fi.imageRequestWaitFor( 500 );
	/// const RequestResult& rr = fi.getRequest( requestNr );
	/// fi.imageRequestUnlock( requestNr );
	/// while( !terminated )
	/// {
	///   fi.imageRequestSingle();
	///   int requestNr = fi.imageRequestWaitFor( 500 );
	///   if( rr.result == rrOK ) // This is an ERROR, as the result might be old!!! Never do this.
	///   {
	///     // process result
	///   }
	///   fi.imageRequestUnlock( requestNr );
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	const RequestResult& getResult(	/// This parameter is provided for downward compatibility only. When developing
									/// a new application 'true' should be passed to this function, but when using this
									/// function at least version 1.5.1.x of the mvDeviceManager-lib is required on every target
									/// machine this executable shall run on.
									///
									/// When passing 'false' to the function, only the values for
									/// - result
									/// - state
									///
									/// will be updated in the structure. This then is the same behaviour then calling
									/// the overloaded function <b>mvIMPACT::acquire::Request::getResult</b> without parameters
									bool boGetFullResult ) const
	{
		if( boGetFullResult )
		{
			// 'new' version, providing more information, but also requires at least version 1.5.1.x of the mvDeviceManager-lib
			DMR_GetImageRequestResultEx( m_hDrv, m_requestNr, &m_requestResult, sizeof(m_requestResult), 0, 0 );
		}
		else
		{
			// 'old' downward compatible version
			getResult();
		}
		return m_requestResult;
	}
	/// \brief Returns a const reference to the image buffer of this request.
	///
	/// This function returns a const reference to the <b>mvIMPACT::acquire::ImageBuffer</b> of this
	/// <b>mvIMPACT::acquire::Request</b>.
	///
	/// \note
	/// Please do <b>NEVER</b> work with old references to this structure. Please see
	/// the comment made under <b>mvIMPACT::acquire::Request::getResult</b>, as the same
	/// applies for the reference to this <b>mvIMPACT::acquire::ImageBuffer</b>.
	const ImageBuffer& getImageBuffer( void ) const { return *(getImageBufferDesc().getBuffer()); }
	/// \brief Returns a const reference to the image buffer descriptor of this request.
	///
	/// This function returns a const reference to the <b>mvIMPACT::acquire::ImageBufferDesc</b> associated 
	/// with this <b>mvIMPACT::acquire::Request</b>.
	///
	/// \note
	/// Please do <b>NEVER</b> work with old references to this structure. Please see
	/// the comment made under <b>mvIMPACT::acquire::Request::getResult</b>, as the same
	/// applies for the reference to this <b>mvIMPACT::acquire::ImageBufferDesc</b>.
	const ImageBufferDesc& getImageBufferDesc( void ) const
	{
		DMR_GetImageRequestBuffer( m_hDrv, m_requestNr, &(m_imageBufferDesc.m_pRefData->m_pBuffer) );
		return m_imageBufferDesc;
	}
#if defined(MVIMPACT_H_) || defined(DOTNET_ONLY_CODE)
	/// \brief Returns an mvIMPACT image buffer representation of the image associated
	/// with this request.
	///
	/// \note
	/// This function is slow, as it performs a copy of the
	/// image data. So using this function will not affect the actual image data from the
	/// device when modifying the image object.
	///
	/// \note 
	/// This function is provided for downward compatibility only. New applications should use
	/// the overloaded function accepting a parameter of type <b>mvIMPACT::acquire::TImpactBufferFlag</b>.
	/// This function might be faster and provides the user with more control over the way the image
	/// is constructed. However if the \a new function is used also a new driver has to be deployed
	/// on every target system running software compiled with this interface. At least version
	/// 1.3.5 of the mvDeviceManager-lib.
	///
	/// <br><br>
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// This function will only be available if \a mvIMPACT.h has been included before including
	/// this interface!
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	Image getIMPACTImage( void ) const
	{
		mvIMPACT_C::IPL_BUFHANDLE hBuf = IPL_DONT_CARE;
		DMR_GetImpactRequestBuffer( m_hDrv, m_requestNr, &hBuf );
		return Image::imageFactory( hBuf );
	}
	/// \brief Returns an mvIMPACT image buffer representation of the image associated
	/// with this request.
	///
	/// \note
	/// This function might be fast depending on the \a flags parameter or might behave like
	/// <b>mvIMPACT::acquire::Request::getIMPACTImage</b>.
	///
	/// <br><br>
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// This function will only be available if \a mvIMPACT.h has been included before including
	/// this interface!
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	Image getIMPACTImage(	/// Flags defining how the buffer is created and behaves.
							TImpactBufferFlag flags ) const
	{
		mvIMPACT_C::IPL_BUFHANDLE hBuf = IPL_DONT_CARE;
		DMR_GetImpactRequestBufferEx( m_hDrv, m_requestNr, &hBuf, flags, 0 );
		return Image::imageFactory( hBuf );
	}
#endif // #if defined(MVIMPACT_H_) || defined(DOTNET_ONLY_CODE)
	/// \brief Returns a string representation of certain <b>mvIMPACT::acquire::Request</b> related parameters.
	std::string getParamS( TImageRequestParam param ) const
	{
		size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
		char* pBuf = new char[bufSize];
		while( (TPROPHANDLING_ERROR)DMR_GetImageRequestParamS( m_hDrv, m_requestNr, param, pBuf, bufSize ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
		{
			delete [] pBuf;
			bufSize *= 2;
			pBuf = new char[bufSize];
		}
		std::string result(pBuf);
		delete [] pBuf;
		return result;
	}
};

//-----------------------------------------------------------------------------
/// \brief A base class for sets of properties, that can be modified by the user.
class ComponentCollection
//-----------------------------------------------------------------------------
{
protected:
	HOBJ m_hRoot;
	explicit ComponentCollection() : m_hRoot(INVALID_ID) {}
	explicit ComponentCollection( HOBJ hRoot ) : m_hRoot(hRoot) {}
	explicit ComponentCollection( Device* pDev )
	{
		if( !pDev->isOpen() )
		{
			pDev->open();
		}
	}
public:
	virtual ~ComponentCollection() {}
	/// \brief Returns a unique identifier for the component collection referenced by this object.
	///
	/// This handle will always reference an object of type <b>mvIMPACT::acquire::ComponentList</b>.
	/// \return A unique identifier for the component referenced by this object.
	HOBJ hObj( void ) const { return m_hRoot; }
	/// \brief Restores the default for every component of this collection.
	///
	/// Calling this function will restore the default value for every component
	/// belonging to this collection.
	///
	void restoreDefault( void ) const { OBJ_RestoreDefault( m_hRoot ); }
};

//-----------------------------------------------------------------------------
/// \brief A helper class to control the way an image request will be processed.
///
class ImageRequestControl : public ComponentCollection
//-----------------------------------------------------------------------------
{
	// only the function interface object is allowed to create new requests as
	// it maintains an internal reference to each ImageRequestControl created.
	friend class FunctionInterface;
	// \todo only for downward compatibility. Will be removed
	explicit ImageRequestControl( HLIST hList )
	{
		init( hList );
	}
	void init( HLIST hList )
	{
		m_hRoot = hList;
		ComponentLocator locator( m_hRoot );
		locator.bindComponent( mode, "Mode" );
		locator.bindComponent( imageCount, "ImageCount" );
		locator.bindComponent( setting, "Setting" );
		locator.bindComponent( resultQueue, "ResultQueue" );
	}
public:
	explicit ImageRequestControl(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a 
									/// <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal image request control to access with 
									/// this instance. A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::availableImageRequestControls</b>,
									/// new image request controls can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createImageRequestControl</b>
									const std::string& name = "Base" ) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltRequestCtrl, name);
		init( locator.searchbase_id() );
	}
	PYTHON_ONLY(%immutable;)
	/// \brief The mode this object shall be operated in.
	///
	/// Valid values for this property are defined by the enumeration 
	/// <b>mvIMPACT::acquire::TImageRequestControlMode</b>.
	///
	/// This property can e.g. be used to prepare internal data structures without requesting a
	/// 'real' image from the hardware. This can be useful when the image dimensions must be known
	/// before the first image is captured.
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// <b>EXAMPLE:</b>
	///
	///\code
	/// Device* pDev = getDevicePointerFromSomewhere();
	/// ImageRequestControl irc(pDev);
	/// irc.mode.write( ircmTrial ); // set to prepare mode
	/// FunctionInterface fi(pDev);
	/// fi.imageRequestSingle( &irc ); // request dummy image
	/// int reqNr = fi.imageRequestWaitFor( 500 );
	/// // waitFor will return as fast as possible. No 'real' image will be taken
	/// // but a request object that contains a dummy image with the format, dimensions
	/// // and other informations will be returned, that is (apart from the pixel data)
	/// // similar to any 'real' image that would be captured with the current settings	
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	PropertyIImageRequestControlMode mode;
	/// \brief An integer property defining the number of images to capture with each request.
	///
	/// \brief This property will currently have no effect
	PropertyI imageCount;
	/// \brief An integer property defining which setting will be used for the acquisition.
	///
	/// This property defines a translation dictionary. It maps the name of the setting (the parameter
	/// passed to the function <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>) to the actual
	/// underlying handle of the request. Therefore either the name or the handle of the setting can be used
	/// to set this property to the desired value.
	PropertyI setting;
	/// \brief An integer property defining to which result queue the resulting image
	/// will be send after the acquisition.
	PropertyI resultQueue;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyIImageRequestControlMode	getMode( void ) const { return mode; }
	PropertyI							getImageCount( void ) const { return imageCount; }
	PropertyI							getSetting( void ) const { return setting; }
	PropertyI							getResultQueue( void ) const { return resultQueue; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief The function interface for <b>MATRIX VISION GmbH</b> devices
///
/// This class contains all basic function needed when working with a device.
/// There are not too many functions as most data will be represented by 'properties'
/// in other classes of this module, keeping the set of functions to remember rather
/// small. To construct a new function interface a pointer to a <b>mvIMPACT::acquire::Device</b> object
/// must be passed to the constructor of <b>mvIMPACT::acquire::FunctionInterface</b>. In order to work
/// with the <b>mvIMPACT::acquire::FunctionInterface</b> object the device needs to be initialized, so
/// if the <b>mvIMPACT::acquire::Device</b> object pointed to by \a pDev in the constructors parameter list
/// hasn't been opened already the construtor will try to do that.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLE:</b>
///
/// This sample assumes a valid pointer to a <b>mvIMPACT::acquire::Device</b> object has been obtained.
/// To find out how to do that see the detailed description of the class <b>mvIMPACT::acquire::DeviceManager</b>.
///
///\code
/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
///
/// using namespace std;
/// using namespace mvIMPACT::acquire;
///
/// static volatile bool boTerminated = false;
/// const unsigned int MAX_REQUESTS = 4;
/// //-----------------------------------------------------------------------------
/// void showPropVal( const Property& prop )
/// //-----------------------------------------------------------------------------
/// {
///   cout << prop.name() << ": " << prop.readS() << endl;
/// }
///
/// //-----------------------------------------------------------------------------
/// void captureThread( Device* pDev )
/// //-----------------------------------------------------------------------------
/// {
///   if( !pDev )
///   {
///     return; // error! Invalid pointer!
///   }
///   FunctionInterface fi( pDev );
///   Settings setting( pDev );
///
///   int maxExposureTime = setting.cameraSetting.expose_us.read( Property::maxValue );
///   // make sure enough requests are available:
///   fi.ensureRequests(MAX_REQUESTS);
///   // now we can work with at least MAX_REQUESTS requests
///
///   // prefill the default capture queue
///   for( unsigned int i=0; i<MAX_REQUESTS; i++ )
///   {
///     fi.imageRequestSingle();
///   }
///
///   // run thread loop
///   const Request* pRequest = 0;
///   int requestNr = -1;
///   while( !boTerminated )
///   {
///     // wait for results from the default capture queue
///     requestNr = fi.imageRequestWaitFor( 500 );
///     if( fi.isRequestNrValid( requestNr ) )
///     {
///       pRequest = fi.getRequest(requestNr);
///       if( fi.isRequestOK( pRequest ) )
///       {
///         ++cnt;
///         if( cnt%100 == 0 )
///         {
///           // modify the exposure time to see how modifying 
///           // properties affects the capture results
///           setting.cameraSetting.expose_us.write( ( cnt * 100 ) % maxExposureTime );
///           // display some statistics
///           showPropVal( setting.cameraSetting.expose_us );
///           showPropVal( statistics.framesPerSecond );
///           showPropVal( statistics.captureTime_s );
///         }
///         const ImageBuffer& ib = pRequest->getImageBuffer();
///         // do whatever is necessary to display/store or process the image
///       }
///       else
///       {
///         cout << "Error: " << pRequest->getResult().result << endl;
///       }
///       fi.imageRequestUnlock( requestNr );
///       fi.imageRequestSingle();
///     }
///     else
///     {
///       cout << "Error: There has been no request in the queue!" << endl;
///     }
///   }
///
///   // free resources
///   fi.imageRequestReset( 0, 0 );
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
class FunctionInterface
//-----------------------------------------------------------------------------
{
	typedef std::vector<Request*> RequestVector;
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		ComponentList						m_requestList;
		ComponentList						m_imageRequestControlList;
		mutable std::vector<std::string>	m_imageRequestControls;
		mutable RequestVector				m_requests;
		mutable std::vector<std::string>	m_settings;
		mutable unsigned int				m_lastImageRequestChangedCounter;
		mutable unsigned int				m_lastSettingsListChangedCounter;
		const Device*						m_pDevice;
		PropertyI							m_requestCount;
		ComponentList						m_settingsList;
		/// \todo downward compatibility... Will be removed someday.
		ImageRequestControl*				m_pDefImageRequestControl;
		unsigned int	m_refCnt;
		ReferenceCountedData( const Device* pDev ) : m_lastImageRequestChangedCounter(0), 
			m_lastSettingsListChangedCounter(0), m_pDevice(pDev), m_refCnt(1) {}
		~ReferenceCountedData()
		{
			RequestVector::size_type rvSize = m_requests.size();
			for( RequestVector::size_type i=0; i<rvSize; i++ )
			{
				delete m_requests[i];
			}
			delete m_pDefImageRequestControl;		
		}
	} *m_pRefData;
	#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}
	//-----------------------------------------------------------------------------
	void updateRequests( void ) const
	//-----------------------------------------------------------------------------
	{
		RequestVector::size_type rListSize = static_cast<RequestVector::size_type>(m_pRefData->m_requestList.size());
		RequestVector::size_type vSize = m_pRefData->m_requests.size();
		if( rListSize < vSize )
		{
			// requests have been deleted...
			for( RequestVector::size_type i=rListSize; i<vSize; i++ )
			{
				delete m_pRefData->m_requests[i];
			}
			m_pRefData->m_requests.resize(rListSize);
		}
		else if( rListSize > vSize )
		{
			// there are new requests
			ComponentIterator it( m_pRefData->m_requestList );
			it = it.firstChild();
			for( RequestVector::size_type i=0; ( i<vSize ) && it.isValid(); i++ )
			{
				++it;
			}
			while( it.isValid() )
			{
				// this might happen, if there are several instances referring to the same device
				// and another instance has created new requests in the meantime, or if this instance
				// has just been created
				m_pRefData->m_requests.push_back( new Request( m_pRefData->m_pDevice->hDrv(), static_cast<int>(m_pRefData->m_requests.size()) ) );
				++it;
			}
		}
	}
	//-----------------------------------------------------------------------------
	void updateSettings( void ) const
	//-----------------------------------------------------------------------------
	{
		unsigned int actChangedCounter = m_pRefData->m_settingsList.changedCounter();
		if( m_pRefData->m_lastSettingsListChangedCounter != actChangedCounter )
		{
			// something has changed in the settings list -> update the string array
			// the string array must be filled from scratch each time because settings might have been
			// deleted as well...
			m_pRefData->m_settings.clear();
			ComponentIterator it(m_pRefData->m_settingsList);
			it = it.firstChild();
			while( it.isValid() )
			{
				// this might happen, if there are several instances referring to the same device
				// and another instance has created new settings in the meantime, or if this instance
				// has just been created
				m_pRefData->m_settings.push_back( it.name() );
				++it;
			}
			m_pRefData->m_lastSettingsListChangedCounter = actChangedCounter;
		}
	}
	//-----------------------------------------------------------------------------
	void updateImageRequestControls( void ) const
	//-----------------------------------------------------------------------------
	{
		unsigned int actChangedCounter = m_pRefData->m_imageRequestControlList.changedCounter();
		if( m_pRefData->m_lastImageRequestChangedCounter != actChangedCounter )
		{
			// something has changed in the image request controls list -> update the string array
			// the string array must be filled from scratch each time because objects might have been
			// deleted as well...
			m_pRefData->m_imageRequestControls.clear();
			ComponentIterator it(m_pRefData->m_imageRequestControlList);
			it = it.firstChild();
			while( it.isValid() )
			{
				// this might happen, if there are several instances referring to the same device
				// and another instance has created new object in the meantime, or if this instance
				// has just been created
				m_pRefData->m_imageRequestControls.push_back( it.name() );
				++it;
			}
			m_pRefData->m_lastImageRequestChangedCounter = actChangedCounter;
		}
	}
public:
	/// \brief Constructs a new function interface for the device pointed to by \a pDev.
	///
	/// In order to work with the <b>mvIMPACT::acquire::FunctionInterface</b> object the device needs to be
	/// initialized, so if the <b>mvIMPACT::acquire::Device</b> object pointed to by \a pDev in the constructors
	/// parameter list hasn't been opened already the construtor will try to do that.
	/// Thus internally a call to <b>mvIMPACT::acquire::Device::open</b> might be preformed with all consequences
	/// following from this call.
	///
	/// \sa
	/// <b>Device::open</b>
	explicit FunctionInterface(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from
								/// a <b>mvIMPACT::acquire::>DeviceManager</b> object.
								Device* pDev )
	{
		if( !pDev->isOpen() )
		{
			pDev->open();
		}
		m_pRefData = new ReferenceCountedData(pDev);
		DeviceComponentLocator locator(pDev, dltSetting);
		m_pRefData->m_settingsList = ComponentList(locator.searchbase_id());
		locator.bindSearchBaseList( pDev, dltRequest );
		m_pRefData->m_requestList = ComponentList(locator.searchbase_id());
		locator.bindSearchBaseList( pDev, dltRequestCtrl );
		m_pRefData->m_imageRequestControlList = ComponentList(locator.searchbase_id());
		/// \todo downward compatibility... Will be removed someday.
		ComponentIterator it(m_pRefData->m_imageRequestControlList);
		it = it.firstChild();
		m_pRefData->m_pDefImageRequestControl = new ImageRequestControl( it );
		/// \todo downward compatibility... Will be removed someday. END
		locator.bindSearchBaseList( pDev, dltSystemSettings );
		locator.bindComponent( m_pRefData->m_requestCount, "RequestCount" );
		updateRequests();
	}
	/// \brief Constructs a new <b>mvIMPACT::acquire::FunctionInterface</b> from
	/// and exisiting one.
	explicit FunctionInterface(	/// A constant reference to the <b>mvIMPACT::acquire::FunctionInterface</b> object, this object shall be created from
								const FunctionInterface& src ) : m_pRefData(src.m_pRefData)
	{
		++(m_pRefData->m_refCnt);
	}
	/// \brief Class destructor.
	virtual	~FunctionInterface( void )
	{
		dealloc();
	}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::FunctionInterface</b> objects
	FunctionInterface& operator=( const FunctionInterface& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefData = rhs.m_pRefData;
			// inc. the NEW reference count
			++m_pRefData->m_refCnt;
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	/// \brief Creates a new <b>mvIMPACT::acquire::ImageRequestControl</b> object.
	///
	/// \note
	/// This feature is currently not implemented! Calling this function will have no effect! So far
	/// just one image request control object can be handled.
	/// \return<br>
	/// - the number associated with the new object if successful(this is a positive number then)
	/// - a negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	createImageRequestControl(	/// The name of the new <b>mvIMPACT::acquire::ImageRequestControl</b> object.
									const std::string& name,
									/// The name of the <b>mvIMPACT::acquire::ImageRequestControl</b> the new object shall be derived from.
									const std::string& parent = "Base" )
	{
		HLIST newID;
		int result = DMR_CreateRequestControl( m_pRefData->m_pDevice->hDrv(), name.c_str(), parent.c_str(), &newID, 0 );
		// no update necessary, done when the user accesses the object
		//updateImageRequestControls();
		return result;
	}
	/// \brief Creates a new setting.
	///
	/// This function creates a new setting base on an existing one. New settings can only be derived
	/// from settings that already exist. When the driver has been initialised there will at least be
	/// one base setting called 'Base', which acts as the base for all other settings.
	///
	/// When a new setting is created it derives all the properties from the parent setting. That means
	/// initially the new setting will contain the very same data as the parent setting. As long as a
	/// component hasn't been modified in the new setting it will depend on the parent settings data.
	/// That means if e.g. a property in the parent list is modified, the newly created setting will
	/// also benefit from the updated value.
	///
	/// To release a certain component from this dependency it must be assigned a new value. The function
	/// <b>mvIMPACT::acquire::Component::isDefault</b> will return false afterwards indicating, that the component no longer
	/// depends on the parent.
	///
	/// To restore this parent <-> child dependency the user can call the function
	/// <b>mvIMPACT::acquire::Component::restoreDefault</b>. Afterwards settings applied to the parent component
	/// will also be visible in the child component again.
	///
	/// When a new setting has been created successfully the name used to create the setting can
	/// be passed to any of the constructors of the setting related classes (<b>mvIMPACT::acquire::Settings</b>, 
	/// <b>mvIMPACT::acquire::CameraSettings</b>, <b>mvIMPACT::acquire::ImageProcessing</b>, ...) to access the new components.
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - a negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	createSetting(	/// The name of the setting to be created.
						const std::string& name,
						/// The name of the setting to derive the new setting from.
						const std::string& parent = "Base" )
	{
		HLIST newID;
		int result = DMR_CreateSetting( m_pRefData->m_pDevice->hDrv(), name.c_str(), parent.c_str(), &newID );
		updateSettings();
		return result;
	}
	/// \brief Makes sure that at least \a requestCount requests are available
	///
	/// Call this function if you want to make sure, that at least \a requestCount
	/// requests are available for any following operation. If there are at least
	/// \a requestCount already, this function does nothing.
	void ensureRequests( /// The number of request to be <i>at least</i> present after the function call
						int requestCount )
	{
		m_pRefData->m_requestCount.write( requestCount );
		updateRequests();
	}
	/// \brief Returns the names of the settings available for this <b>mvIMPACT::acquire::Device</b>.
	///
	/// This function returns const reference an array containing the names of all settings available
	/// for the current <b>mvIMPACT::acquire::Device</b>. These names are valid constructor parameters for objects
	/// of the type <b>mvIMPACT::acquire::Settings</b>, <b>mvIMPACT::acquire::ImageProcessing</b>, <b>mvIMPACT::acquire::ImageDestination</b> and <b>CameraSettings</b> or
	/// classes derived from these types.
	///
	/// New settings can be created by calling
	/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
	/// \return A const reference to an array containing the names of all available settings.
	const std::vector<std::string>&	getAvailableSettings( void ) const
	{
		updateSettings();
		return m_pRefData->m_settings;
	}
	/// \brief Returns a pointer to the desired <b>mvIMPACT::acquire::ImageRequestControl</b> object.
	///
	/// This function returns a pointer to the <b>mvIMPACT::acquire::ImageRequestControl</b> stored at \a requestCtrlNr
	/// in the internal array of image request controls.
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html	
	/// If \a requestCtrlNr refers to an invalid <b>mvIMPACT::acquire::ImageRequestControl</b><br>
	/// (e.g. when \a requestCtrlNr is higher then the actual number of <br>
	/// available image request controls ) a STL out_of_range exception is thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly	
	///
	/// \note
	/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
	///	<b>mvIMPACT::acquire::FunctionInterface::availableImageRequestControls</b> and 
	/// <b>mvIMPACT::acquire::ImageRequestControl</b> instead!
	///
	/// \return A pointer to a <b>mvIMPACT::acquire::ImageRequestControl</b> object.
	ImageRequestControl* getImageRequestControl(	/// The number of the image request control
													int requestCtrlNr ) const
	{
		return ( ( requestCtrlNr == 0 ) ? m_pRefData->m_pDefImageRequestControl : 0 );
	}
	/// \brief Returns the names of the image request controls available for this <b>mvIMPACT::acquire::Device</b>.
	///
	/// This function returns const reference an array containing the names of all image request controls available
	/// for the current <b>mvIMPACT::acquire::Device</b>. These names are valid constructor parameters for objects
	/// of the type <b>mvIMPACT::acquire::ImageRequestControl</b>.
	///
	/// New image request controls can be created by calling <b>mvIMPACT::acquire::FunctionInterface::createImageRequestControl</b>.
	/// \return A const reference to an array containing the names of all available settings.
	const std::vector<std::string>& availableImageRequestControls( void ) const
	{
		updateImageRequestControls();
		return m_pRefData->m_imageRequestControls;
	}
	/// \brief Returns a const pointer to the desired <b>mvIMPACT::acquire::Request</b>.
	///
	/// This function returns a pointer to the <b>mvIMPACT::acquire::Request</b> stored at \a requestNr
	/// in the internal array of requests.
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// If \a requestNr refers to an invalid <b>mvIMPACT::acquire::Request</b><br>
	/// (e.g. when \a requestNr is higher then the actual number of<br>
	/// available request) an STL out_of_range exception will be thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	/// \return A pointer to a <b>mvIMPACT::acquire::Request</b> object.
	const Request* getRequest(	/// The number of the request
								int requestNr ) const
	{
		updateRequests();
		return m_pRefData->m_requests.at( requestNr );
	}
	/// \brief Deletes all requests currently queued for the specified <b>mvIMPACT::acquire::ImageRequestControl</b>
	///
	/// This function will terminate all running image acquisitions associated with the queue
	/// bound to the specified image request control and in addition to that
	/// will empty the queue of pending image requests for that queue.
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestSingle,<br>
	///	   mvIMPACT::acquire::FunctionInterface::imageRequestUnlock,<br>
	///    mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int imageRequestReset(	/// The <b>mvIMPACT::acquire::ImageRequestControl</b> for which all
							/// the requests shall be cancelled.
							int requestCtrlNr,
							/// Currently ignored.
							int mode ) const { return DMR_ImageRequestReset( m_pRefData->m_pDevice->hDrv(), requestCtrlNr, mode ); }
	/// \brief Sends an image request to the <b>mvIMPACT::acquire::Device</b> driver.
	///
	/// This functions sends a single image request to the camera. To wait for the image
	/// to become ready call the function
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>.
	///
	/// \note
	/// In order to make sure, that no image data is lost it is important to understand, how
	/// the request mechanism works. The driver works with a fixed number of <b>mvIMPACT::acquire::Request</b>
	/// objects. The number of <b>mvIMPACT::acquire::Request</b> objects available to the driver can be set
	/// either by modifying <b>SystemBase::requestCount</b> or by calling
	/// <b>mvIMPACT::acquire::FunctionInterface::ensureRequests</b>. Each <b>mvIMPACT::acquire::Request</b> will
	/// consum a certain amount of memory. Once an image has been captured by the <b>mvIMPACT::acquire::Request</b>
	/// this amount will be slightly more then the image itself needs in memory, so modify this
	/// parameter gently. On the other hand its necessary to have more then a single request
	/// in order to ensure a loss less acquisition. E.g. when working with free running cameras
	/// image might be lost because when an image has been captured and processed the next
	/// vertical sync. pulse has already been missed when the <b>mvIMPACT::acquire::Request</b> is unlocked again.
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestReset,<br>
	///	   mvIMPACT::acquire::FunctionInterface::imageRequestUnlock,<br>
	///    mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int imageRequestSingle( /// A pointer to the <b>mvIMPACT::acquire::ImageRequestControl</b> object, 
							/// to be used for this request. <b>mvIMPACT::acquire::ImageRequestControl</b>
							/// objects define (among other things), which <b>mvIMPACT::acquire::Settings</b> will
							/// be used for this image acquisition (via the property
							/// <b>mvIMPACT::acquire::ImageRequestControl::setting</b>).
							ImageRequestControl* pImageRequestControl = 0,
							/// If a valid pointer to an integer is passed here, this
							/// variable receives the number of the <b>mvIMPACT::acquire::Request</b> which
							/// will be used to process this request.
							int* pRequestUsed = 0 ) const 
	{
		return DMR_ImageRequestSingle( m_pRefData->m_pDevice->hDrv(), pImageRequestControl ? pImageRequestControl->hObj() & 0xFFFF : 0, pRequestUsed );
	}

	/// \brief Sends an image request to the <b>mvIMPACT::acquire::Device</b> driver.
	///
	/// \note
	/// This function has been declared <b>deprecated</b> and might not be available in future releases. Use
	/// the new overload accepting a pointer to an <b>mvIMPACT::acquire::ImageRequestControl</b> as the
	/// first parameter.
	int imageRequestSingle( /// The <b>mvIMPACT::acquire::ImageRequestControl</b> objects index in the
							/// interfaces internal array of <b>mvIMPACT::acquire::ImageRequestControl</b>
							/// objects to be used for this request. <b>mvIMPACT::acquire::ImageRequestControl</b>
							/// objects define (among other things), which <b>mvIMPACT::acquire::Settings</b> will
							/// be used for this image acquisition.
							int requestCtrlNr,
							/// If a valid pointer to an integer is passed here, this
							/// variable receives the number of the <b>mvIMPACT::acquire::Request</b> which
							/// will be used to process this request.
							int* pRequestUsed = 0 ) const { return DMR_ImageRequestSingle( m_pRefData->m_pDevice->hDrv(), requestCtrlNr, pRequestUsed ); }
	/// \brief Unlocks the request for the driver again.
	///
	/// To ensure that no image data is overwritten by another image request while the user still
	/// deals with the image from a previous acquisition each image buffer will be locked by the driver when
	/// it is returned to the user by a call to <b>mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>.
	/// No new image will be captured into the same buffer until the user unlocks the buffer again
	/// by calling <b>mvIMPACT::acquire::FunctionInterface::imageRequestUnlock</b>.
	///
	/// \note
	/// After unlocking a request it is no longer guaranteed that the memory once referenced by the 
	/// request and the image buffer belonging to it stays valid, so do <b>NEVER</b> try to access
	/// memory belonging to an unlocked request object. If you need to copy the image buffer or 
	/// modify it in any other way, do everything you have to do <b>BEFORE</b> calling this function!
	///
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestReset,<br>
	///	   mvIMPACT::acquire::FunctionInterface::imageRequestSingle,<br>
	///    mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	imageRequestUnlock( /// The number of the request to unlock. This is typically
							/// a value returned from a call to
							/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestWaitFor</b>.
							int requestNr ) const { return DMR_ImageRequestUnlock( m_pRefData->m_pDevice->hDrv(), requestNr ); }
	/// \brief Waits for an image request to become ready.
	///
	/// This function waits for an image request previously send to the camera by calling
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestSingle</b>.
	///
	/// \note Whenever a <b>mvIMPACT::acquire::Request</b> is returned to the user the image data 
	/// described by the <b>mvIMPACT::acquire::Request</b> remains valid until the user unlocks
	/// the image buffer again or the driver is closed.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::imageRequestUnlock, <br>
	///    mvIMPACT::acquire::FunctionInterface::getRequest</b>
	/// \return When the return value is positive the return value is the request number of the
	/// image request in the interfaces internal array of image requests. In this case the user
	/// can call <b>mvIMPACT::acquire::FunctionInterface::getRequest</b> to get access to the
	/// results. <br><br>When the result is negative the return value is an error code.
	/// The error code that is returned in most of the cases will be <b>mvIMPACT::acquire::TDMR_ERROR::DEV_WAIT_FOR_REQUEST_FAILED</b>.
	/// To find out possible reasons for this error have a look at the corresponding explanation.
	int	imageRequestWaitFor( /// The maximum wait time in milli-seconds for
							 /// this request to become ready. If \a timeout_ms
							 /// is '-1', the functions time-out interval never
							 /// elapses.
							 int timeout_ms,
							 /// The queue where to wait for the request.
							 int queueNr = 0 ) const
	{
		int requestNr;
		TDMR_ERROR result = DMR_ImageRequestWaitFor( m_pRefData->m_pDevice->hDrv(), timeout_ms, queueNr, &requestNr );
		if( result != DMR_NO_ERROR )
		{
			return result;
		}
		return requestNr;
	}
	/// \brief Check if \a requestNr specifies a valid <b>mvIMPACT::acquire::Request</b>
	/// \return <br>
	/// - true if \a requestNr specifies a valid request.
	/// - false otherwise
	bool isRequestNrValid( int requestNr ) const { return requestNr >= 0; }
	/// \brief Checks if a request has been processed successfully.
	/// \return <br>
	/// - true if the request has been processed successfully.
	/// - false otherwise.
	bool isRequestOK( const Request* p ) const
	{
		if( p )
		{
			return ( p->getResult().result == rrOK );
		}
		return false;
	}
	/// \brief Loads a previously stored setting.
	///
	/// This function can be used to restore a previously stored setting again.
	///
	/// To load a setting from a file the <b>mvIMPACT::acquire::TStorageFlag::sfFile</b> should be specified
	/// as part of \a storageflags. To load a setting from a platform specific location
	/// such as the Registry under Windows&copy; <b>mvIMPACT::acquire::TStorageFlag::sfFile</b> should be
	/// specified. It's not allowed to combine <b>mvIMPACT::acquire::TStorageFlag::sfFile</b> and
	/// <b>mvIMPACT::acquire::TStorageFlag::sfNative</b> for this operation.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::saveSetting</b>.
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	loadSetting( /// The name or the full path under where the setting is located
					 const std::string& name,
					 /// The flags which define which information shall be read from the location
					 /// and how this information shall be interpreted.
					 TStorageFlag storageflags = sfNative,
					 /// Specifies where the information is located.
					 TScope scope = sGlobal ) const { return DMR_LoadSetting( m_pRefData->m_pDevice->hDrv(), name.c_str(), storageflags, scope ); }
	/// \brief Loads the default settings
	///
	/// This function will try to load the settings from a default location. This function
	/// can only succeed if a setting has been stored previously by a call to
	/// <b>mvIMPACT::acquire::FunctionInterface::saveSettingToDefault</b>.
	///
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	loadSettingFromDefault(	/// Specifies where the information is located.
								TScope scope = sUser ) const { return DMR_LoadSettingFromDefault( m_pRefData->m_pDevice->hDrv(), scope ); }
	/// \brief Returns the number of available requests.
	/// \return Returns the number of available requests.
	unsigned int requestCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_requests.size()); }
	/// \brief Stores the current settings.
	///
	/// This function can be used to store the current settings either in a XML-file or
	/// (under Windows&copy;) into the Registry. A setting contains all the values set
	/// for properties that control the overall way an image is acquired( e.g. the exposure time, etc.).
	///
	/// To store a setting in a file the <b>mvIMPACT::acquire::TStorageFlag::sfFile</b> should be specified
	/// as part of \a storageflags. To store a setting in a platform specific location
	/// such as the Registry under Windows&copy; <b>mvIMPACT::acquire::TStorageFlag::sfFile</b> should be
	/// specified. Both flags can be combined. In that case the same setting will be stored in a
	/// file <b>AND</b> in a platform specific location if these location differ (platform dependent!).
	///
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	saveSetting( /// The name or the full path under which this setting shall be stored
					 const std::string& name,
					 /// The flags which define which information shall be stored and how this
					 /// information shall be stored.
					 TStorageFlag storageflags = sfNative,
					 /// Specifies where the information shall be stored.
					 TScope scope = sGlobal ) const { return DMR_SaveSetting( m_pRefData->m_pDevice->hDrv(), name.c_str(), storageflags, scope ); }
	/// \brief Stores the current settings under a default location.
	///
	/// Under Windows&copy; this will be in the Registry. A setting contains all the values set
	/// for properties that control the overall way an image is acquired( e.g. the exposure time, etc.).
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int saveSettingToDefault(	/// Specifies where the information shall be stored.
								TScope scope = sUser ) const { return DMR_SaveSettingToDefault( m_pRefData->m_pDevice->hDrv(), scope ); }
	/// \brief Stores the current system settings under a default location.
	///
	/// These are the settings which can be altered by creating an instance of the class
	/// <b>mvIMPACT::acquire::SystemBase</b>. Under Windows&copy; this function will store the current settings
	/// in the Registry.
	///
	/// Modifying data in this section of properties will affect every device belonging to the same
	/// family (e.g. every USB 2.0 camera device) when the data is saved. When the modified data is
	/// stored it will be restored by each device belonging to the same family during the next
	/// initialisation. So at runtime changing and saving the settings of one device will not affect
	/// the behaviour of another until the data has been stored and the other device has been closed
	/// and reopened again.
	/// \return
	/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
	/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
	int	saveSystemToDefault(	/// Specifies where the information shall be stored.
								TScope scope = sUser ) const { return DMR_SaveSystemToDefault( m_pRefData->m_pDevice->hDrv(), scope ); }
};

//-----------------------------------------------------------------------------
/// \brief A base class to access various general information about the device and its
/// driver
///
/// This class contains a collection of properties providing various information about
/// the device and its driver.
///
/// Instances of this class can't be constructed directly. Use one of the derived types.
class InfoBase : public ComponentCollection
//-----------------------------------------------------------------------------
{
protected:
	/// \brief Constructs a new <b>mvIMPACT::acquire::InfoBase</b> object.
	explicit InfoBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from
						/// a <b>mvIMPACT::acquire::DeviceManager</b> object.
						Device* pDev ) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltInfo );
		m_hRoot = locator.searchbase_id();
		locator.bindComponent( driverDate, "DriverDate" );
		locator.bindComponent( driverVersion, "DriverVersion" );
		locator.bindComponent( state, "State" );
		locator.bindComponent( loadedSettings, "LoadedSettings" );
		locator.bindComponent( logFile, "LogFile" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief A string property <b>(read-only)</b> containing the date this driver has been compiled.
	PropertyS							driverDate;
	/// \brief A string property <b>(read-only)</b> containing the version number of this driver.
	PropertyS							driverVersion;
	/// \brief An enumerated integer property <b>(read-only)</b> containing the current state of this device.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceState</b>.
	PropertyIDeviceState				state;
	/// \brief A string property <b>(read-only)</b> containing the name of the setting currently loaded.
	PropertyS							loadedSettings;
	/// \brief A string property <b>(read-only)</b> containing the name and the full path of the current log-file
	/// for this device.
	PropertyS							logFile;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyS							getDriverDate( void ) const { return driverDate; }
	PropertyS							getDriverVersion( void ) const { return driverVersion; }
	PropertyIDeviceState				getState( void ) const { return state; }
	PropertyS							getLoadedSettings( void ) const { return loadedSettings; }
	PropertyS							getLogFile( void ) const { return logFile; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A class to query various general information about the device, its
/// driver and other information.
class Info : public InfoBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::Info</b> object.
	explicit Info(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
					Device* pDev ) : InfoBase(pDev) {}
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A more specific class to query information about a <b>mvBlueFOX</b>
	/// device and its driver.
	///
	/// This class contains a collection of properties providing various information about
	/// a <b>mvBlueFOX</b> device and its driver. 
	class InfoBlueFOX : public InfoBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::InfoBlueFOX</b> object.
		explicit InfoBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev ) : InfoBase(pDev)
		{
			ComponentLocator locator( m_hRoot );
			locator.bindComponent( firmwareVersion, "FirmwareVersion" );
			locator.bindSearchBase( locator.searchbase_id(), "Camera" );
			locator.bindComponent( sensorFPGAVersion, "SensorFPGAVersion" );
			locator.bindComponent( sensorCaps, "SensorCaps" );
			locator.bindComponent( sensorXRes, "SensorXRes" );
			locator.bindComponent( sensorYRes, "SensorYRes" );
			locator.bindComponent( sensorColorMode, "SensorColorMode" );
			locator.bindComponent( sensorType, "SensorType" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property <b>(read-only)</b> containing the firmware version of this device.
		PropertyI firmwareVersion;
		/// \brief An integer property <b>(read-only)</b> containing the FPGA version of the camera(if known).
		///
		/// \note
		/// If nothing is known about this feature, this property will contain '-1'.
		PropertyI sensorFPGAVersion;
		/// \brief An integer property <b>(read-only)</b> containing a bit mask containing information
		/// about the sensors capabilities(if known).
		///
		/// \note
		/// If nothing is known about this feature, this property will contain '-1'.
		PropertyI sensorCaps;
		/// \brief An integer property <b>(read-only)</b> containing the horizontal resolution
		/// of the camera sensor.
		PropertyI sensorXRes;
		/// \brief An integer property <b>(read-only)</b> containing the vertical resolution
		/// of the camera sensor.
		PropertyI sensorYRes;
		/// \brief An enumerated integer property <b>(read-only)</b> containing the type of the sensor
		/// (color/mono/...)(if known).
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TInfoSensorColorMode</b>.
		///
		/// \note
		/// If nothing is known about this feature, this property will contain <b>mvIMPACT::acquire::TInfoSensorColorMode::iscmUnknown</b>.
		PropertyIInfoSensorColorMode sensorColorMode;
		/// \brief An enumerated integer property <b>(read-only)</b> containing the type of sensor chip of the
		/// camera(if known).
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TInfoSensorType</b>.
		///
		/// This usually will either be <b>mvIMPACT::acquire::TInfoSensorType::istCCD</b> or <b>mvIMPACT::acquire::TInfoSensorType::istCMOS</b>.
		PropertyIInfoSensorType	sensorType;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI							getFirmwareVersion( void ) const { return firmwareVersion; }
		PropertyI							getSensorFPGAVersion( void ) const { return sensorFPGAVersion; }
		PropertyI							getSensorCaps( void ) const { return sensorCaps; }
		PropertyI							getSensorXRes( void ) const { return sensorXRes; }
		PropertyI							getSensorYRes( void ) const { return sensorYRes; }
		PropertyIInfoSensorColorMode		getSensorColorMode( void ) const { return sensorColorMode; }
		PropertyIInfoSensorType				getSensorType( void ) const { return sensorType; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A more specific class to query information about a <b>MATRIX VISION GmbH</b> frame grabber
	/// device and its driver.
	///
	/// This class contains a collection of properties providing various information about
	/// a <b>MATRIX VISION GmbH</b> frame grabber device and its driver. 
	class InfoFrameGrabber : public InfoBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::InfoFrameGrabber</b> object.
		explicit InfoFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev ) : InfoBase(pDev)
		{
			ComponentLocator locator( m_hRoot );
			locator.bindComponent( deviceDriverVersion, "DeviceDriverVersion" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property <b>(read-only)</b> containing the device driver version of this device.
		///
		/// This is the version of the underlying hardware driver.
		PropertyS							deviceDriverVersion;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyS							getDeviceDriverVersion( void ) const { return deviceDriverVersion; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

//-----------------------------------------------------------------------------
/// \brief A class to represent a digital input pin.
class DigitalInput
//-----------------------------------------------------------------------------
{
	friend class	IOSubSystem;
	HDRV			m_hDrv;
	PropertyI		m_register;
	int				m_bitNumber;
	std::string		m_description;
	explicit		DigitalInput( HDRV hDrv, PropertyI reg, int bitNumber, const std::string desc ) : m_hDrv(hDrv), m_register(reg), m_bitNumber(bitNumber), m_description(desc) {}
public:
	/// \brief Returns the current state of this input pin.
	/// \return
	/// - true if the current state of this pin is considered as 'logic 1'
	/// - false otherwise
	bool get( void ) const
	{
		DMR_UpdateDigitalInputs( m_hDrv );
		return m_register.read(m_bitNumber) != 0;
	}
	/// \brief Returns a description for this digital input.
	///
	/// This might contain connector descriptions or other information like
	/// e.g. 'Trigger-In(J8.4/J8.5)', which means, this is the trigger input
	/// of connector \a J8 pins \a 4 and \a 5.
	std::string getDescription( void ) const { return m_description; }
};

//-----------------------------------------------------------------------------
/// \brief A class to represent a digital output pin.
class DigitalOutput
//-----------------------------------------------------------------------------
{
	friend class	IOSubSystem;
	PropertyI		m_register;
	int				m_bitNumber;
	std::string		m_description;
	explicit		DigitalOutput( PropertyI reg, int bitNumber, const std::string desc ) : m_register(reg), m_bitNumber(bitNumber), m_description(desc) {}
public:
	/// \brief Inverts the current state of the digital output and returns the
	/// previous state.
	/// \return
	/// - true if the previous state of this pin was considered as 'logic 1'
	/// - false otherwise
	bool flip( void )
	{
		bool oldState = get();
		m_register.write( !oldState, m_bitNumber );
		return oldState;
	}
	/// \brief Returns the current state of this output pin.
	/// \return
	/// - true if the current state of this pin is considered as 'logic 1'
	/// - false otherwise
	bool get( void ) const { return m_register.read( m_bitNumber ) != 0; }
	/// \brief Sets the output pin to 'logic 1'.
	void set( void ) { m_register.write( 1, m_bitNumber ); }
	/// \brief Sets the output pin to 'logic 0'.
	void reset( void ) { m_register.write( 0, m_bitNumber ); }
	/// \brief Returns a description for this digital output.
	///
	/// This might contain connector descriptions or other information like
	/// e.g. 'CC1(J1)', which means, this is the CameraLink&reg; control 
	/// channel 1 of connector \a J1.
	std::string getDescription( void ) const { return m_description; }
};

//-----------------------------------------------------------------------------
/// \brief A class to represent a sync. output pin.
///
/// Instances of this class can be used to define and generate sync. signals 
/// at the corresponding outputs of the device.
///
/// \note
/// Instances of this class can't be constructed directly, but must be obtained
/// via the device specific class derived from <b>mvIMPACT::acquire::IOSubSystem</b>.
class SyncOutput
//-----------------------------------------------------------------------------
{
	friend class	IOSubSystem;
	ComponentList	m_list;
	explicit		SyncOutput( HLIST hList ) : m_list(hList)
	{
		ComponentLocator locator(hList);
		locator.bindComponent( frequency_Hz, "Frequency_Hz" );
		locator.bindComponent( lowPart_pc, "LowPart_pc" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief A float property defining the frequency(in Hertz) for the sync. signal
	/// generated by this pin.
	PropertyF frequency_Hz;
	/// \brief A float property defining the width in percent the sync. signal stays
	/// low during one period. The output signal generated will be a square pulse.
	PropertyF lowPart_pc;
	PYTHON_ONLY(%mutable;)
	/// \brief Returns a description for this sync. output.
	///
	/// This might contain connector descriptions or other information like
	/// e.g. 'VD-OUT(J9.24)', which means, this is the VD output at connector J9
	/// pin 24.
	std::string getDescription( void ) const { return m_list.name(); }
#ifdef DOTNET_ONLY_CODE
	PropertyF getFrequency_Hz( void ) const { return frequency_Hz; }
	PropertyF getLowPart_pc( void ) const { return lowPart_pc; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A class to represent one step of a real time control(<b>RTCtr</b>) program.
///
/// An object of this class represents a single instruction in a program represented
/// by an <b>mvIMPACT::acquire::RTCtrProgram</b>. <b>mvIMPACT::acquire::RTCtrProgramStep</b> object can't be constructed
/// directly, but must be accessed via the function
/// <b>mvIMPACT::acquire::RTCtrProgram::programStep</b> of the program they belong
/// to.
///
/// The instruction this <b>mvIMPACT::acquire::RTCtrProgramStep</b> will executed when the program is
/// executed is defined by the property <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b>. Depending
/// on the value of this property certain other parameters will influence the
/// behaviour of this instruction.
class RTCtrProgramStep
//-----------------------------------------------------------------------------
{
	friend class RTCtrProgram;
	explicit RTCtrProgramStep( HOBJ hObj )
	{
		ComponentLocator locator( hObj );
		locator.bindComponent( address, "Address" );
		locator.bindComponent( clocks_us, "Clocks_us" );
		locator.bindComponent( frameID, "FrameID" );
		locator.bindComponent( digitalInputs, "DigitalInputs" );
		locator.bindComponent( digitalOutputs, "DigitalOutputs" );
		locator.bindComponent( opCode, "OpCode" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief An integer property, which defines the absolute jump address within this <b>mvIMPACT::acquire::RTCtrProgram</b>.
	///
	/// This property only is taken into account, if <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b> is set to <b>mvIMPACT::acquire::TRTProgOpCodes::rtctrlProgJumpLoc</b>.
	PropertyI address;
	/// \brief An integer property, which defines the frame ID of the triggered image <b>mvIMPACT::acquire::RTCtrProgram</b>.
	///
	/// This property only is taken into account, if <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b> is set to <b>mvIMPACT::acquire::TRTProgOpCodes::rtctrlProgTriggerSet</b>.
	PropertyI frameID;
	/// \brief An integer property, which defines the waiting time <b>mvIMPACT::acquire::RTCtrProgram</b>.
	///
	/// This property only is taken into account, if <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b> is set to <b>mvIMPACT::acquire::TRTProgOpCodes::rtctrlProgWaitClocks</b>.
	PropertyI clocks_us;
	/// \brief An enumerated integer property to define for which digital input state this program step waits for.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDigIOState</b>.
	///
	/// This property only is taken into account, if <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b> is set to <b>mvIMPACT::acquire::TRTProgOpCodes::rtctrlProgWaitDigin</b>.
	PropertyIDigIOState digitalInputs;
	/// \brief An enumerated integer property to define how to set the digital outputs
	/// of this device.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDigIOState</b>.
	///
	/// This property only is taken into account, if <b>mvIMPACT::acquire::RTCtrProgramStep::opCode</b> is set to <b>mvIMPACT::acquire::TRTProgOpCodes::rtctrlProgSetDigout</b>.
	PropertyIDigIOState digitalOutputs;
	/// \brief An enumerated integer property defining the general purpose of this <b>mvIMPACT::acquire::RTCtrProgramStep</b> object.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TRTProgOpCodes</b>.
	PropertyIRTProgOpCodes	opCode;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI				getAddress( void ) const { return address; }
	PropertyI				getFrameID( void ) const { return frameID; }
	PropertyI				getClocks_us( void ) const { return clocks_us; }
	PropertyIDigIOState		getDigitalInputs( void ) const { return digitalInputs; }
	PropertyIDigIOState		getDigitalOutputs( void ) const { return digitalOutputs; }
	PropertyIRTProgOpCodes	getOpCode( void ) const { return opCode; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A class to represent real time control programs
///
/// Real time control programs can be used to control the way how an when images
/// are exposed an transmitted to the user.
///
/// An <b>mvIMPACT::acquire::RTCtrProgram</b> e.g. can be used to achieve a constant frame rate with
/// a desired frequency. This can be done e.g. by triggering the camera with a constant frequency.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
/// <b>EXAMPLE:</b>
/// An appropriate signal for triggering the camera can be generated as follows:
///\code
/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
///
/// using namespace mvIMPACT::acquire;
///
/// void runAt10Hz( Device* pBf )
/// {
///   CameraSettingsBlueFOX bfs( pBf );
///   IOSubSystemBlueFOX bfIOs( pBf );
///   // define a HRTC program that results in a define image frequency
///   // the hardware real time controller shall be used to trigger an image
///   bfs.triggerSource.write( ctsRTCtrl );
///   // when the hardware real time controller switches the trigger signal to 
///   // high the exposure of the image shall start
///   bfs.triggerMode.write( ctmOnRisingEdge );
///
///   // error checks
///   if( bfIOs.RTCCtrProgramCount() == 0 )
///   {
///     // no HRTC controllers available (this never happens for the mvBlueFOX)
///     return;
///   }
///
///   RTCtrProgram* pRTCtrlprogram = bfIOs.getRTCtrProgram( 0 );
///   if( !pRTCtrlprogram )
///   {
///     // this only should happen if the system is short of memory
///     return;
///   }
///
///   // start of the program
///
///   // we need 5 steps for the program
///   pRTCtrlprogram->setProgramSize(5);
///
///   // wait a certain amount of time to achieve the desired frequency
///   int progStep = 0;
///   RTCtrProgramStep* pRTCtrlStep = 0;
///   pRTCtrlStep = pRTCtrlprogram->programStep( progStep++ );
///   pRTCtrlStep->opCode.write( rtctrlProgWaitClocks );
///   pRTCtrlStep->clocks_us.write( 99900 );
///
///   // trigger an image
///   pRTCtrlStep = pRTCtrlprogram->programStep( progStep++ );
///   pRTCtrlStep->opCode.write( rtctrlProgTriggerSet );
///
///   // high time for the trigger signal (should not be smaller then 100 us)
///   pRTCtrlStep = pRTCtrlprogram->programStep( progStep++ );
///   pRTCtrlStep->opCode.write( rtctrlProgWaitClocks );
///   pRTCtrlStep->clocks_us.write( 100 );
///
///   // end trigger signal
///   pRTCtrlStep = pRTCtrlprogram->programStep( progStep++ );
///   pRTCtrlStep->opCode.write( rtctrlProgTriggerReset );
///
///   // restart the program
///   pRTCtrlStep = pRTCtrlprogram->programStep( progStep++ );
///   pRTCtrlStep->opCode.write( rtctrlProgJumpLoc );
///   pRTCtrlStep->address.write( 0 );
///
///   // start the program
///   pRTCtrlprogram->mode.write( rtctrlModeRun );
///
///   // Now this camera will deliver images at exactly 10 Hz ( 1 / ( 99900 us + 100us ) )
///   // when it is constantly feed with image requests.
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
///
/// Once this program has been defined it can be executed by setting the \a mode
/// property to <b>mvIMPACT::acquire::TRTCtrlModes::rtctrlModeRun</b>. As in this example we do not
/// wait for an external signal the property <b>mvIMPACT::acquire::CameraSettings::triggerMode</b>
/// must be set to a value demanding an external signal
/// ( e.g. <b>mvIMPACT::acquire::TCameraTriggerMode::ctmOnRisingEdge </b> ) and the  property 
/// <b>mvIMPACT::acquire::CameraSettings::triggerMode</b>
/// must be set to <b>mvIMPACT::acquire::TCameraTriggerSource::ctsRTCtrl</b>
/// to inform the driver, that the signal generate by the real time program shall
/// be used as the trigger signal.
///
/// \note
/// <b>mvIMPACT::acquire::RTCtrProgram</b> objects can't be created directly! To access an <b>mvIMPACT::acquire::RTCtrProgram</b>
/// associated with a certain device create an instance of an object derived from
/// <b>mvIMPACT::acquire::IOSubSystem</b> and then use the function
/// <b>mvIMPACT::acquire::IOSubSystem::RTCCtrProgramCount()</b> to find out if there are
/// hardware real time controller machines available for this device and if so how
/// many of them can be accessed. Pointers to the machines then can be obtained by calling the
/// function <b>mvIMPACT::acquire::IOSubSystem::getRTCtrProgram()</b> with the number of the
/// controller (zero based) to be modified.
class RTCtrProgram
//-----------------------------------------------------------------------------
{
	friend class IOSubSystem;
	typedef std::vector<RTCtrProgramStep*> RTCtrlProgramStepVector;
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		HDRV							m_hDrv;
		mutable RTCtrlProgramStepVector	m_programSteps;
		PropertyI						m_programSize;
		HLIST							m_hRTCtrList;
		HOBJ							m_programStepList;
		mutable unsigned int			m_programChangedCounter;
		unsigned int					m_refCnt;
		ReferenceCountedData( HDRV hDrv, HLIST hList ) : m_hDrv(hDrv), m_hRTCtrList(hList), m_programChangedCounter(UINT_MAX), m_refCnt(1) {}
		~ReferenceCountedData()
		{
			RTCtrlProgramStepVector::size_type vSize = m_programSteps.size();
			for( RTCtrlProgramStepVector::size_type i=0; i<vSize; i++ )
			{
				delete m_programSteps[i];
			}
		}
	} *m_pRefData;
	#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	void bindPublicProperties( HLIST hList )
	//-----------------------------------------------------------------------------
	{
		ComponentLocator locator( hList );
		locator.bindComponent( mode, "Mode" );
		locator.bindComponent( filename, "Filename" );
		locator.bindComponent( programState, "ProgramState" );
	}
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}
	//-----------------------------------------------------------------------------
	void updateProgram( void ) const
	//-----------------------------------------------------------------------------
	{
		RTCtrlProgramStepVector::size_type vSize = m_pRefData->m_programSteps.size();
		unsigned int lSize = ComponentList( m_pRefData->m_programStepList ).size();
		if( lSize < vSize )
		{
			// steps have been deleted somewhere...
			for( unsigned int i=lSize; i<vSize; i++ )
			{
				delete m_pRefData->m_programSteps[i];
			}
			m_pRefData->m_programSteps.resize( lSize );
		}
		else if( lSize > vSize )
		{
			// new steps have been created
			ComponentIterator iter( m_pRefData->m_programStepList );
			iter = iter.firstChild();
			// move to the next valid end point
			for( unsigned int i=0; i<vSize; i++ )
			{
				iter.nextSibling();
			}

			while( iter.isValid() )
			{
				m_pRefData->m_programSteps.push_back( new RTCtrProgramStep( iter ) );
				iter = iter.nextSibling();
			}
		}
	}
	//-----------------------------------------------------------------------------
	explicit RTCtrProgram( HDRV hDrv, HLIST hList ) : m_pRefData(new ReferenceCountedData(hDrv, hList))
	//-----------------------------------------------------------------------------
	{
		ComponentLocator locator( hList );		
		locator.bindComponent( m_pRefData->m_programSize, "ProgramSize" );
		bindPublicProperties( m_pRefData->m_hRTCtrList );
		m_pRefData->m_programStepList = locator.findComponent( "RTCtrProgram" );		
		updateProgram();
	}
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::RTCtrProgram</b> from
	/// and exisiting one.
	explicit RTCtrProgram(	/// A constant reference to the <b>mvIMPACT::acquire::RTCtrProgram</b> object, this object shall be created from
							const RTCtrProgram& src ) : m_pRefData(src.m_pRefData)
	{
		++(m_pRefData->m_refCnt);
		bindPublicProperties( m_pRefData->m_hRTCtrList );
	}
	/// \brief Class destructor.
	~RTCtrProgram()
	{
		dealloc();
	}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::RTCtrProgram</b> objects
	RTCtrProgram& operator=( const RTCtrProgram& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefData = rhs.m_pRefData;
			// inc. the NEW reference count
			++m_pRefData->m_refCnt;
			bindPublicProperties( m_pRefData->m_hRTCtrList );
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	/// \brief A function to define the number of instructions this program should consist of.
	void setProgramSize(	/// The new number of program instructions
							int newSize )
	{
		m_pRefData->m_programSize.write( newSize );
		updateProgram();
	}
	/// \brief Returns the number of program instructions for this program.
	/// \return The number of program instructions for this program.
	int	getProgramSize( void ) const { return m_pRefData->m_programSize.read(); }
	/// \brief Returns a pointer to a program instruction of the program.
	/// \return A pointer to a program instruction of the program.
	RTCtrProgramStep* programStep(	/// The index of the program instruction to obtain.
									unsigned int nr ) const
	{
		updateProgram();
		return m_pRefData->m_programSteps.at( nr );
	}
	PYTHON_ONLY(%immutable;)
	/// \brief An enumerated integer property defining the current state this program is into.
	///
	/// In order to affect the behaviour of the image acquisition an <b>mvIMPACT::acquire::RTCtrProgram</b> must be in
	/// running mode. Apart from that the property <b>mvIMPACT::acquire::CameraSettings::triggerSource</b> must be set
	/// appropriately.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TRTCtrlModes</b>.
	PropertyIRTCtrlModes mode;
	/// \brief A string property storing the filename for this program.
	///
	/// <b>mvIMPACT::acquire::RTCtrProgram</b>s can be stored and loaded from/to XML files.
	/// To do this, this property must be set to the desired filename.
	/// \sa
	/// <b>mvIMPACT::acquire::RTCtrProgram::load, <br>mvIMPACT::acquire::RTCtrProgram::save</b>
	PropertyS filename;
	/// \brief A string property <b>(read-only)</b> containing information
	/// about the current state of the program.
	PropertyS programState;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyIRTCtrlModes		getMode( void ) const { return mode; }
	PropertyS					getFilename( void ) const { return filename; };
	PropertyS					getProgramState( void ) const { return programState; };
#endif // #ifdef DOTNET_ONLY_CODE
	/// \brief Loads an existing program specified by the property <b>mvIMPACT::acquire::RTCtrProgram::filename</b>.
	///
	/// The default file extension for these programs is '*.rtp'. If the user doesn't
	/// specify this file extension, it is appended automatically. Only
	/// files of this type can be loaded by this function.
	int load( void ) { return DMR_LoadRTCtrProgram( m_pRefData->m_hDrv, m_pRefData->m_hRTCtrList ); }
	/// \brief stores the current state of the program under the name specified by the
	/// property <b>mvIMPACT::acquire::RTCtrProgram::filename</b>
	///
	/// The default file extension for files stored using this function is '*.rtp'. If
	/// the user doesn't specify this file extension, it is appended automatically. Only
	/// files of this type can be loaded by the function <b>mvIMPACT::acquire::RTCtrProgram::load</b>.
	int save( void ) { return DMR_SaveRTCtrProgram( m_pRefData->m_hDrv, m_pRefData->m_hRTCtrList ); }
};

//-----------------------------------------------------------------------------
/// \brief A base class to handle digital inputs and outputs.
///
/// This class can't be instantiated by the user, but acts as a base class for
/// hardware specific classes. Please use a device specific class, which has
/// been derived from this class instead.
///
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
///\endxmlonly
///\htmlinclude code_fragment_start_cpp.html
///
/// <b>EXAMPLES</b>(lists all available digital inputs and outputs and their description): 
///\code
/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
/// #include <iostream>
///
/// using namespace std;
/// using namespace mvIMPACT::acquire;
///
/// void listIOPins( Device* pDev )
/// {
///   IOSubSystemFrameGrabber io(pDev);
///   unsigned int iCnt = io.getInputCount();
///   cout << "available digital inputs: " << iCnt << endl;
///   for( unsigned int d=0; d<iCnt; d++ )
///   {
///     out << io.input(d)->getDescription() << endl;
///   }
///   unsigned int oCnt = io.getOutputCount();
///   cout << "available digital outputs: " << oCnt << endl;
///   for( unsigned int e=0; e<oCnt; e++ )
///   {
///     DigitalOutput* pOutput = io.output(e);
///     out << "setting " << pOutput->getDescription() << " to high" << endl;
///     // set this output to logic '1'
///     pOutput->set();
///   }
/// }
///\endcode
///\htmlinclude code_fragment_end.html
///\xmlonly
/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
///\endxmlonly
class IOSubSystem
//-----------------------------------------------------------------------------
{
protected:
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	typedef std::vector<RTCtrProgram*> RTCtrProgramVector;
	typedef std::vector<DigitalInput*> DigitalInputVector;
	typedef std::vector<DigitalOutput*> DigitalOutputVector;
	typedef std::vector<SyncOutput*> SyncOutputVector;
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		HDRV						m_hDrv;
		DigitalInputVector			m_vInputs;
		DigitalOutputVector			m_vOutputs;
		SyncOutputVector			m_vHDOutputs;
		SyncOutputVector			m_vVDOutputs;
		mutable RTCtrProgramVector	m_RTCtrPrograms;
		unsigned int				m_refCnt;
		ReferenceCountedData( HDRV hDrv ) : m_hDrv(hDrv), m_refCnt(1) {}
		~ReferenceCountedData()
		{
			DigitalInputVector::size_type vInputsSize = m_vInputs.size();
			for( DigitalInputVector::size_type i=0; i<vInputsSize; i++ )
			{
				delete m_vInputs[i];
			}

			DigitalOutputVector::size_type vOutputsSize = m_vOutputs.size();
			for( DigitalOutputVector::size_type j=0; j<vOutputsSize; j++ )
			{
				delete m_vOutputs[j];
			}

			SyncOutputVector::size_type vSyncOutputsSize = m_vHDOutputs.size();
			for( SyncOutputVector::size_type k=0; k<vSyncOutputsSize; k++ )
			{
				delete m_vHDOutputs[k];
			}

			vSyncOutputsSize = m_vVDOutputs.size();
			for( SyncOutputVector::size_type l=0; l<vSyncOutputsSize; l++ )
			{
				delete m_vVDOutputs[l];
			}

			RTCtrProgramVector::size_type vRTCProgSize = m_RTCtrPrograms.size();
			for( RTCtrProgramVector::size_type m=0; m<vRTCProgSize; m++ )
			{
				delete m_RTCtrPrograms[m];
			}
		}
	} *m_pRefData;
	//-----------------------------------------------------------------------------
	explicit IOSubSystem( Device* pDev )
	//-----------------------------------------------------------------------------
	{
		if( !pDev->isOpen() )
		{
			pDev->open();
		}
		m_pRefData = new ReferenceCountedData(pDev->hDrv());
	}
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}
	void registerDigitalInput( PropertyI reg, int nr, const std::string& desc )	{ m_pRefData->m_vInputs.push_back( new DigitalInput( m_pRefData->m_hDrv, reg, nr, desc ) ); }
	void registerDigitalOutput( PropertyI reg, int nr, const std::string& desc ) { m_pRefData->m_vOutputs.push_back( new DigitalOutput( reg, nr, desc ) ); }
	void registerHDOutput( HLIST hList ) { m_pRefData->m_vHDOutputs.push_back( new SyncOutput(hList) ); }
	void registerVDOutput( HLIST hList ) { m_pRefData->m_vVDOutputs.push_back( new SyncOutput(hList) ); }
	void registerRTCtrProgram( HDRV hDrv, HLIST hList ) { m_pRefData->m_RTCtrPrograms.push_back( new RTCtrProgram( hDrv, hList ) ); }
	#endif // DOXYGEN_SHOULD_SKIP_THIS
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::IOSubSystem</b> from
	/// and exisiting one.
	explicit IOSubSystem(	/// A constant reference to the <b>mvIMPACT::acquire::IOSubSystem</b> object, this object shall be created from
							const IOSubSystem& src ) : m_pRefData(src.m_pRefData)
	{
		++(m_pRefData->m_refCnt);
	}
	virtual ~IOSubSystem()
	{
		dealloc();
	}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::IOSubSystem</b> objects
	IOSubSystem& operator=( const IOSubSystem& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefData = rhs.m_pRefData;
			// inc. the NEW reference count
			++m_pRefData->m_refCnt;
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	/// \brief Returns a pointer to a <b>mvIMPACT::acquire::RTCtrProgram</b> associated with
	/// this device.
	RTCtrProgram* getRTCtrProgram( unsigned int programNr ) const { return m_pRefData->m_RTCtrPrograms.at( programNr ); }
	/// \brief Returns the number of <b>mvIMPACT::acquire::RTCtrProgram</b>s available for the <b>mvIMPACT::acquire::Device</b>
	/// associated with this object.
	unsigned int RTCCtrProgramCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_RTCtrPrograms.size()); }
	/// \brief Returns the number of <b>mvIMPACT::acquire::DigitalInput</b>s available for the <b>mvIMPACT::acquire::Device</b>
	/// associated with this object.
	unsigned int getInputCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_vInputs.size()); }
	/// \brief Returns the current state of the digital input register.
	///
	/// This function can be used to read all digital inputs as a single value. Each
	/// bit represents the status of one digital output pin.
	///
	/// <b>EXAMPLE:</b>
	///
	/// a value of '3' returned by this function means, that digital inputs 0 and 1 are
	/// currently have a voltage considered as logical '1' applied to them.
	virtual unsigned int readInputRegister( void ) const = 0;
	/// \brief Returns a const pointer to a <b>mvIMPACT::acquire::DigitalInput</b> object.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// If \a inputNr references an invalid pin a STL out_of_range exception
	/// will be thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \note
	/// The possibility to access the digital inputs of a device as single objects is
	/// just provided for convenience. The same thing can be achieved by calling the
	/// function <b>mvIMPACT::acquire::IOSubSystem::readInputRegister</b>.
	const DigitalInput*	input(	/// The number of the digital input.
								unsigned int inputNr ) const { return m_pRefData->m_vInputs.at( inputNr ); }
	/// \brief Returns a pointer to a <b>mvIMPACT::acquire::DigitalOutput</b> object.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// If \a outputNr references an invalid pin an STL out_of_range exception
	/// will be thrown.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \note
	/// The possibility to access the digital outputs of a device as single objects is
	/// just provided for convenience. The same thing can be achieved by calling the function
	/// <b>mvIMPACT::acquire::IOSubSystem::writeOutputRegister</b> with the corresponding bit mask.
	DigitalOutput* output(	/// The number of the digital output.
							unsigned int outputNr ) const { return m_pRefData->m_vOutputs.at( outputNr ); }
	/// \brief Returns the number of digital outputs available for the <b>mvIMPACT::acquire::Device</b>
	/// associated with this object.
	unsigned int getOutputCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_vOutputs.size()); }
	/// \brief Returns the current state of the digital output register.
	///
	/// This function can be used to read all digital outputs as a single value. Each
	/// bit represents the status of one digital output pin.
	///
	/// <b>EXAMPLE:</b>
	///
	/// a value of '3' returned by this function means, that digital output 0 and 1 are
	/// currently set to high.
	virtual unsigned int readOutputRegister( void ) const = 0;
	/// \brief Alters the state of the digital output register.
	///
	/// This function can be used to alter the state of certain (or all) digital outputs
	/// with a single function call. By working with the parameter \a mask certain bits
	/// can remain unaffected.
	///
	/// <b>EXAMPLE:</b>
	///
	/// If the previous state of a digital output register was '5', which means, that outputs
	/// 0 and 2 are set to high a call to
	/// <b>mvIMPACT::acquire::IOSubSystem::writeOutputRegister</b> with
	/// \a value set to 2 and \a mask set to 3 would result in '6' as the new value for the
	/// output register. Pin 2 will remain unaffected, as \a mask states just to modify
	/// pin 0 and 1 ( 3 = 00000011 binary ).
	virtual void writeOutputRegister(	/// The value to be applied to the output register
										unsigned int value,
										/// The mask to specify which pins to modify. A bit
										/// set to '1' in this parameter means, that the
										/// state of this output has to adopt its style according to
										/// the value in \a value.
										unsigned int mask = UINT_MAX ) = 0;
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class to handle the digital inputs and outputs for <b>mvBlueFOX</b>
	/// USB cameras.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	///
	/// A sample to show how to work with this class and the mvBlueFOX (Creating and instance
	/// of this class for another device might aise an exception):
	///
	///\code
	/// #include <iostream>
	/// #include <conio.h>
	/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
	///
	/// using namespace std;
	/// using namespace mvIMPACT::acquire;
	///
	/// void doSomeIOStuff( Device* pBf )
	/// {
	///   IOSubSystemBlueFOX bfIOs( pBf );
	///   cout << "output 0 was " << bfIOs.output(0)->get() << " and is now(after flipping) ";
	///   bfIOs.output(0)->flip();
	///   cout << bfIOs.output(0)->get() << endl;
	///   cout << "input threshold(" << bfIOs.digitalInputThreshold.readS() << ") set to " << bfdit10V << endl;
	///   if( bfIOs.digitalInputThreshold.isWriteable() ) // mvBlueFOX-M doesn't support modifying the input threshold
	///   {
	///     bfIOs.digitalInputThreshold.write( bfdit10V );
	///     cout << "input threshold is now " << bfIOs.digitalInputThreshold.readS() << endl;
	///   }
	///   cout << "input 0 is " << bfIOs.input(0)->get() << endl;
	///   cout << "press any key." << endl;
	///   _getch();
	///   cout << "input 0 is " << bfIOs.input(0)->get() << endl;
	///   cout << "press any key." << endl;
	///   _getch();
	///   cout << "input 0 is " << bfIOs.input(0)->get() << endl;
	///   // switch on digital out 0 and 1 ( 3 = 00000011 binary )
	///   bfIOs.writeOutputRegister( 3 );
	///   cout << "outputs: %d, inputs: " << bfIOs.readOutputRegister(), bfIOs.readInputRegister() ;
	///   // the next line will reset bit 0 only, resulting in output 1 to remain high
	///   // as the mask parameter of '1' defines that only the LSB of the register will be
	///   // affected by the first parameter of the function call
	///   bfIOs.writeOutputRegister( 0, 1 );
	///   cout << "outputs: " << bfIOs.readOutputRegister() << ", inputs " << bfIOs.readInputRegister() << endl;
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \note
	/// The <b>mvBlueFOX</b> defines an additional property <b>mvIMPACT::acquire::CameraSettings::flashMode</b>.
	/// This might affect the state of the digital outputs as well.
	///
	/// If a digital output is defined to be 'logic 0' but the flash mode is switched on
	/// for the same digital output, the output will be high during the expose time of
	/// the camera sensor. If a digital output is defined to be 'logic 1' the output will
	/// be high all the time.
	class IOSubSystemBlueFOX : public IOSubSystem
	//-----------------------------------------------------------------------------
	{
	private:
		unsigned int readRegister( const PropertyI& reg ) const
		{
			std::vector<int> v;
			reg.read( v );
			std::vector<int>::size_type vSize = v.size();
			unsigned int result = 0;
			for( std::vector<int>::size_type i=0; i<vSize; i++ )
			{
				result |= ( ( v[i] & 1 ) << i );
			}
			return result;
		}
		PropertyI	m_inputRegister;
		PropertyI	m_outputRegister;
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::IOSubSystemBlueFOX</b> object.
		explicit IOSubSystemBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
										Device* pDev ) : IOSubSystem(pDev)
		{
			DeviceComponentLocator locator(pDev, dltIOSubSystem);
			locator.bindComponent( digitalInputThreshold, "DigitalInputThreshold" );
			locator.bindComponent( m_inputRegister, "DigitalInputs" );
			locator.bindComponent( m_outputRegister, "DigitalOutputs" );

			// register all input pins
			unsigned int pinCount = m_inputRegister.valCount();
			std::ostringstream oss;
			for( unsigned int i=0; i<pinCount; i++ )
			{
				oss << "DigitialInput" << i;
				registerDigitalInput( m_inputRegister, i, oss.str() );
				oss.seekp(0);
			}

			// register all output pins
			pinCount = m_outputRegister.valCount();
			for( unsigned int j=0; j<pinCount; j++ )
			{
				oss << "DigitalOutput" << j;
				registerDigitalOutput( m_outputRegister, j, oss.str() );
				oss.seekp(0);
			}

			// register all real time control machines if available
			unsigned int cnt=0;
			HLIST hList;
			TDMR_ERROR result;
			while( ( result = DMR_FindList( pDev->hDrv(), 0, dmltRTCtr, cnt, &hList ) ) == DMR_NO_ERROR )
			{
				registerRTCtrProgram( pDev->hDrv(), hList );
				++cnt;
			}
		}
		/// \brief Returns the current state of the digital input register.
		///
		/// This function can be used to read all digital inputs as a single value. Each
		/// bit represents the status of one digital output pin.
		///
		/// <b>EXAMPLE:</b>
		///
		/// a value of '3' returned by this function means, that digital inputs 0 and 1 are
		/// currently have a voltage considered as logical '1' applied to them.
		virtual unsigned int readInputRegister( void ) const
		{
			DMR_UpdateDigitalInputs( m_pRefData->m_hDrv );
			return readRegister( m_inputRegister );
		}
		/// \brief Returns the current state of the digital output register.
		///
		/// This function can be used to read all digital outputs as a single value. Each
		/// bit represents the status of one digital output pin.
		///
		/// <b>EXAMPLE:</b>
		///
		/// a value of '3' returned by this function means, that digital output 0 and 1 are
		/// currently set to high.
		virtual unsigned int readOutputRegister( void ) const { return readRegister( m_outputRegister ); }
		/// \brief Alters the state of the digital output register.
		///
		/// This function can be used to alter the state of certain (or all) digital outputs
		/// with a single function call. By working with the parameter \a mask certain bits
		/// can remain unaffected.
		///
		/// <b>EXAMPLE:</b>
		///
		/// If the previous state of a digital output register was '5', which means, that outputs
		/// 0 and 2 are set to high a call to
		/// <b>mvIMPACT::acquire::IOSubSystem::writeOutputRegister</b> with
		/// \a value set to 2 and \a mask set to 3 would result in '6' as the new value for the
		/// output register. Pin 2 will remain unaffected, as \a mask states just to modify
		/// pin 0 and 1 ( 3 = 00000011 binary ).
		void writeOutputRegister(	/// The value to be applied to the output register
									unsigned int value,
									/// The mask to specify which pins to modify. A bit
									/// set to '1' in this parameter means, that the
									/// state of this output has to adopt its style according to
									/// the value in \a value.
									unsigned int mask = UINT_MAX )
		{
			unsigned int newVal = ( readRegister( m_outputRegister ) & ~mask ) | ( mask & value );
			DigitalOutputVector::size_type vSize = m_pRefData->m_vOutputs.size();
			std::vector<int> v(vSize);
			for( std::vector<int>::size_type i=0; i<vSize; i++ )
			{
				v[i] = ( ( newVal & ( 1 << i ) ) != 0 );
			}
			m_outputRegister.write( v );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the threshold for the digital
		/// inputs in Volt.
		///
		/// If a voltage applied to the digital input lies above the threshold this pin
		/// will be considered as 'logic 1' otherwise it will be considered as 'logic 0'.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueFOXDigitalInputThreshold</b>.
		///
		/// \note
		/// This property is <b>read-only</b> for <b>mvBlueFOX-M</b> devices and will always be 2V.
		PropertyIBlueFOXDigitalInputThreshold digitalInputThreshold;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIBlueFOXDigitalInputThreshold getDigitalInputThreshold( void ) const { return digitalInputThreshold; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class to handle the digital inputs and outputs for frame grabber
	/// devices.
	///
	/// This class provides a convenient basic access to the digital inputs and 
	/// outputs of a <b>MATRIX VISION GmbH</b> frame grabber device.
	///
	/// \note
	/// The number of digital inputs and outputs available will vary significantly
	/// from device to device. Some devices might not even have digital inputs and/or
	/// digital outputs. Therefore it's crucial to check for available pins before
	/// using them. The corresponding functions to do that can be found in the
	/// base class <b>mvIMPACT::acquire::IOSubSystem</b>.
	///
	/// To create more complex digital output related signals the class 
	/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber</b> should be used.
	class IOSubSystemFrameGrabber : public IOSubSystem
	//-----------------------------------------------------------------------------
	{
		ComponentList m_inputs;
		ComponentList m_outputs;
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b> object.
		explicit IOSubSystemFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
											Device* pDev ) : IOSubSystem(pDev)
		{
			DeviceComponentLocator locator(pDev, dltIOSubSystem);
			locator.bindComponent( m_inputs, "DigitalInputs", 0, 1 );
			if( m_inputs.isValid() )
			{
				ComponentIterator it( m_inputs );
				it = it.firstChild();
				while( it.isValid() )
				{
					registerDigitalInput( PropertyI(it), 0, it.name() );
					++it;
				}
			}
			locator.bindComponent( m_outputs, "DigitalOutputs", 0, 1 );
			if( m_outputs.isValid() )
			{
				ComponentIterator it( m_outputs );
				it = it.firstChild();
				while( it.isValid() )
				{
					if( it.isList() )
					{
						ComponentLocator outputStateLocator(it);
						registerDigitalOutput( PropertyI(outputStateLocator.findComponent("State")), 0, it.name() );
					}
					++it;
				}
			}
			ComponentIterator itSyncs;
			locator.bindComponent( itSyncs, "SyncOutputs", 0, 1 );
			if( itSyncs.isValid() && itSyncs.firstChild() )
			{
				itSyncs = itSyncs.firstChild();
				locator.bindComponent( syncOutputMode, "Mode" );
				while( itSyncs.isValid() )
				{
					if( itSyncs.isList() )
					{
						std::string name = itSyncs.name();
                        if( name.substr( 0, 3 ) == "VD-" )
						{
							registerVDOutput( itSyncs );
						}
						else if( name.substr( 0, 3 ) == "HD-" )
						{
							registerHDOutput( itSyncs );
						}
						else
						{
							; // type not recognized?!
						}
					}
					++itSyncs;
				} 
			}
		}
		/// \brief Returns the number of available HD output pins for the <b>mvIMPACT::acquire::Device</b>
		/// associated with this object.
		unsigned int getHDOutputCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_vHDOutputs.size()); }
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::SyncOutput</b> object that represents
		/// a HD output for this device.
		///
		/// \a outputNr <b>MUST</b> be a valid number ( larger or equal then 0 and smaller then the
		/// value returned by <b>mvIMPACT::acquire::getHDOutputCount</b>.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// If \a outputNr references an invalid pin an STL out_of_range exception
		/// will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		///
		/// \return A pointer to a <b>mvIMPACT::acquire::SyncOutput</b> object.
		SyncOutput* HDOutput(	/// The number of the HD output to return.
								unsigned int outputNr ) const { return m_pRefData->m_vHDOutputs.at( outputNr ); }
		/// \brief Returns the number of available VD output pins for the <b>mvIMPACT::acquire::Device</b>
		/// associated with this object.
		unsigned int getVDOutputCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_vVDOutputs.size()); }
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::SyncOutput</b> object that represents
		/// a VD output for this device.
		///
		/// \a outputNr <b>MUST</b> be a valid number ( larger or equal then 0 and smaller then the
		/// value returned by <b>mvIMPACT::acquire::getVDOutputCount</b>.
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// If \a outputNr references an invalid pin an STL out_of_range exception
		/// will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		///
		/// \return A pointer to a <b>mvIMPACT::acquire::SyncOutput</b> object.
		SyncOutput* VDOutput(	/// The number of the VD output to return.
								unsigned int outputNr ) const { return m_pRefData->m_vVDOutputs.at( outputNr ); }
		/// \brief Returns the current state of the digital input register.
		///
		/// This function can be used to read all digital inputs as a single value. Each
		/// bit represents the status of one digital output pin.
		///
		/// <b>EXAMPLE:</b>
		///
		/// a value of '3' returned by this function means, that digital inputs 0 and 1 are
		/// currently have a voltage considered as logical '1' applied to them.
		///
		/// \return The current state of the digital inputs where bit 0 in the result represents
		/// the state of digital input 0, bit 1 the state of digital input 1 a.s.o..
		virtual unsigned int readInputRegister( void ) const
		{
			DMR_UpdateDigitalInputs( m_pRefData->m_hDrv );
			if( !m_inputs.isValid() )
			{
				return 0; 
			}
			unsigned int result = 0;
			ComponentIterator it( m_inputs );
			int i=0;
			it = it.firstChild();
			while( it.isValid() )
			{
				PropertyI input(it);
				result |= ( ( input.read() & 1 ) << i );
				++it;
				++i;
			}
			return result;
		}
		/// \brief Returns the current state of the digital output register.
		///
		/// This function can be used to read all digital outputs as a single value. Each
		/// bit represents the status of one digital output pin.
		///
		/// <b>EXAMPLE:</b>
		///
		/// a value of '3' returned by this function means, that digital output 0 and 1 are
		/// currently set to high.
		///
		/// \return The current state of the digital outputs where bit 0 in the result represents
		/// the state of digital output 0, bit 1 the state of digital output 1 a.s.o..
		virtual unsigned int readOutputRegister( void ) const
		{
			unsigned int result = 0;
			DigitalOutputVector::size_type vSize = m_pRefData->m_vOutputs.size();
			for( DigitalOutputVector::size_type i=0; i<vSize; i++ )
			{
				result |= ( ( m_pRefData->m_vOutputs[i]->get() & 1 ) << i );
			}
			return result;
		}
		/// \brief Alters the state of the digital output register.
		///
		/// This function can be used to alter the state of certain (or all) digital outputs
		/// with a single function call. By working with the parameter \a mask certain bits
		/// can remain unaffected.
		///
		/// <b>EXAMPLE:</b>
		///
		/// If the previous state of a digital output register was '5', which means, that outputs
		/// 0 and 2 are set to high a call to
		/// <b>mvIMPACT::acquire::IOSubSystem::writeOutputRegister</b> with
		/// \a value set to 2 and \a mask set to 3 would result in '6' as the new value for the
		/// output register. Pin 2 will remain unaffected, as \a mask states just to modify
		/// pin 0 and 1 ( 3 = 00000011 binary ).
		void writeOutputRegister(	/// The value to be applied to the output register
									unsigned int value,
									/// The mask to specify which pins to modify. A bit
									/// set to '1' in this parameter means, that the
									/// state of this output has to adopt its style according to
									/// the value in \a value.
									unsigned int mask = UINT_MAX )
		{
			DigitalOutputVector::size_type vSize = m_pRefData->m_vOutputs.size();
			for( DigitalOutputVector::size_type i=0; i<vSize; i++ )
			{
				if( mask & ( 1 << i ) )
				{
					if( value & ( 1 << i ) )
					{
						m_pRefData->m_vOutputs[i]->set();
					}
					else
					{
						m_pRefData->m_vOutputs[i]->reset();
					}
				}
			}
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the current mode for sync. signal creation.
		///
		/// Sometimes it's desired to create a signal to sync. cameras connected to a capture device.
		/// E.g. when capturing 3 monochrome cameras in parallel these should be synchronized. Therefore
		/// some devices can create HD and VD signals that synchronize the connected cameras.
		///
		/// To create snyc. signals this property must be set either to <b>mvIMPACT::acquire::TDeviceSyncOutMode::dsomNonInterlaced</b>
		/// or <b>mvIMPACT::acquire::TDeviceSyncOutMode::dsomInterlaced</b>.
		///
		/// In interlaced mode only the frequency of the VD signals can be modified, while in non-interlaced
		/// mode the width (in percent) the signal stays low can be modified as well.
		///
		/// Now e.g. to sync. two or more CCIR compliant cameras connected to a capture device, that can
		/// create sync. signals, the HD signals must be generated with a CCIR compliant frequency.
		/// The function <b>mvIMPACT::acquire::IOSubSystemFrameGrabber::HDOutput</b> can be used to access the
		/// desired output pin. Then it's property <b>mvIMPACT::acquire::SyncOutput::frequency_Hz</b> is
		/// set to 15625 Hz (CCIR standard). The remaining values can be left untouched. The capture device
		/// will no generate HD signals with the desired frequency and VD outputs with the frequency
		/// stored by the property <b>mvIMPACT::acquire::SyncOutput::frequency_Hz</b> belonging to the
		/// pointer to the object returned by a call to <b>mvIMPACT::acquire::IOSubSystemFrameGrabber::VDOutput</b>.
		PropertyIDeviceSyncOutMode syncOutputMode;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIDeviceSyncOutMode getSyncOutputMode( void ) const { return syncOutputMode; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A class to create complex digital output signals.
	///
	/// Instances of this class can be used to create more complex digital output
	/// related signals like a single pulse or sequence of pulses on a certain pin
	/// as a reaction of a signal on one of the digital inputs of a device.
	///
	/// The availability of the features provided by this class depend heavily on the
	/// used frame grabber. Therefore it's crucial to check if a desired feature is available
	/// at all. This class either provides the functions needed for this checks or it's
	/// functions will return appropriate error codes.
	///
	/// \note
	/// If the property <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::controlMode</b>
	/// is not available <b>NO</b> feature of this class can be used.
	/// 
	/// \note
	/// If the translation dictionary of <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::controlMode</b>
	/// does not contain <b>mvIMPACT::acquire::TDigitalOutputControlMode::docmRTC</b> the function
	/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::defineLineScanPulse</b> will <b>NOT</b>
	/// be available.
	///
	/// \note 
	/// Calling unsupported functions or accessing unsupported features will raise an exception.
	///
	/// Pointers to <b>mvIMPACT::acquire::DigitalOutput</b> objects <b>MUST</b> be obtained
	/// by an instance to a <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b> object of the
	/// same device.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	///
	/// <b>EXAMPLES:</b>
	///\code
	/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
	/// #include <iostream>
	/// #include <vector>
	///
	/// using namespace std;
	/// using namespace mvIMPACT::acquire;
	///
	/// Device* pDev = getValidDevicePointerFromSomewhere();
	/// IOSubSystemFrameGrabber io(pDev);
	/// unsigned int iCnt = io.getInputCount();
	/// cout << "available digital inputs: " << iCnt << endl;
	/// for( unsigned int d=0; d<iCnt; d++ )
	/// {
	///   cout << io.input(d)->getDescription() << endl;
	/// }
	/// unsigned int oCnt = io.getOutputCount();
	/// cout << "available digital outputs: " << oCnt << endl;
	/// // set all available digital outputs to high
	/// for( unsigned int e=0; e<oCnt; e++ )
	/// {
	///   DigitalOutput* pOutput = io.output(e);
	///   cout << "setting " << pOutput->getDescription() << " to high" << endl;
	///   pOutput->set();
	/// }
	///
	/// // check there is at least one digital output
	/// if( oCnt > 0 )
	/// {
	///   OutputSignalGeneratorFrameGrabber osg(pDev);
	///   // check if this device supports enhanced signal creation at all
	///   if( osg.controlMode.isValid() )
	///   {
	///     // define a simple pulse on the first digital output detected. 
	///     // this pulse will be low after 100 us for
	///     // 200us and then switches back to high.
	///     osg.definePulse( io.output( 0 ), 0, 100, 200 );
	/// 
	///     // define a more complex pulse
	///     vector<int> v;
	///     v.push_back(100);
	///     v.push_back(299);
	///     v.push_back(666);
	///     osg.definePulseSequence( io.output( 0 ), 0, v );
	///     osg.controlMode.write( docmSoftware );
	///     osg.imageTrigger.write( ditAfterDigOutSignals );
	/// 
	///     // check if line scan pulse creation is supported by this device
	///     vector<pair<string, TDigitalOutputControlMode> > dict;
	///     osg.controlMode.getTranslationDict( dict );
	///     unsigned int dictSize = osg.controlMode.dictSize();
	///     for( unsigned int i=0; i<dictSize; i++ )
	///     {
	///       if( dict[i].second == docmRTC )
	///       {
	///         // supported -> define some signal
	///         cout << "checkGrabberInterface: This device supports RTC control signal creation." << endl;
	///         osg.controlMode.write( docmRTC );
	///         osg.defineLineScanPulse( io.output( 0 ), dsosePeriodically, 100, 100, 1, 1 );
	///       }
	///     }
	///   }
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// Whenever a signal has been defined for a a certain digital output
	/// pin, this pin can no longer controlled using the corresponding functions
	/// in the class <b>mvIMPACT::acquire::DigitalOutput</b>. In order to do that
	/// the pin in question must be released using the function
	/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::undefineSignal</b>.
	class OutputSignalGeneratorFrameGrabber
	//-----------------------------------------------------------------------------
	{
		#ifndef DOXYGEN_SHOULD_SKIP_THIS
		//-----------------------------------------------------------------------------		
		struct OutputProperties
		//-----------------------------------------------------------------------------
		{
			PropertyIDeviceDigitalOutputMode mode;
			PropertyI polarity;
			PropertyI delay_us;
			PropertyI width_us;
			PropertyI width_pclk;
			PropertyI startLevel;
			PropertyI polaritySwitchAfter_us;
			OutputProperties( HLIST hOutput )
			{
				ComponentLocator locator(hOutput);
				locator.bindComponent( mode, "Mode" );
				locator.bindComponent( polarity, "Polarity" );
				locator.bindComponent( delay_us, "Delay_us" );
				locator.bindComponent( width_us, "Width_us" );
				locator.bindComponent( width_pclk, "Width_pclk" );
				locator.bindComponent( startLevel, "StartLevel" );
				locator.bindComponent( polaritySwitchAfter_us, "PolaritySwitchAfter_us" );
			}
		};
		#ifndef DOXYGEN_SHOULD_SKIP_THIS
		//-----------------------------------------------------------------------------
		struct ReferenceCountedData
		//-----------------------------------------------------------------------------
		{
			ComponentList								m_outputs;
			PropertyIDeviceSignalOutputStartEvent		m_pulseStartEventLineScan;
			PropertyI									m_softwareSignalPeriod_pclk;
			PropertyI									m_output;
			PropertyI									m_width_pclk;
			PropertyI									m_polarity;
			PropertyI									m_divider;
			std::map<std::string, OutputProperties*>	m_mOutputs;
			unsigned int								m_refCnt;
			ReferenceCountedData() : m_refCnt(1) {}
			~ReferenceCountedData()
			{
				std::map<std::string, OutputProperties*>::iterator itEnd = m_mOutputs.end();
				std::map<std::string, OutputProperties*>::iterator it = m_mOutputs.begin();
				while( it != itEnd )
				{
					delete it->second;
					++it;
				}
			}
		} *m_pRefData;
		#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
		//-----------------------------------------------------------------------------
		void bindPublicProperties( HLIST hList )
		//-----------------------------------------------------------------------------
		{
			ComponentLocator locator(hList);
			locator.bindComponent( controlMode, "ControlMode" );
			locator.bindComponent( pulseStartEvent, "PulseStartEvent" );
			locator.bindComponent( imageTrigger, "ImageTrigger" );
		}
		//-----------------------------------------------------------------------------
		void dealloc( void )
		//-----------------------------------------------------------------------------
		{
			--(m_pRefData->m_refCnt);
			if( m_pRefData->m_refCnt == 0 )
			{
				delete m_pRefData;
			}
		}
		//-----------------------------------------------------------------------------
		OutputProperties* getOutputProperties( DigitalOutput* pOutput )
		//-----------------------------------------------------------------------------
		{
			if( pOutput )
			{
				std::map<std::string, OutputProperties*>::iterator it = m_pRefData->m_mOutputs.find( pOutput->getDescription() );
				if( it != m_pRefData->m_mOutputs.end() )
				{
					return it->second;
				}
			}
			return 0;
		}
		#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber</b> object.
		explicit OutputSignalGeneratorFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
													Device* pDev )
		{
			m_pRefData = new ReferenceCountedData();
			DeviceComponentLocator locator(pDev, dltIOSubSystem);
			locator.bindComponent( m_pRefData->m_outputs, "DigitalOutputs" );
			locator.bindSearchBase( m_pRefData->m_outputs.hObj() );
			bindPublicProperties( m_pRefData->m_outputs.hObj() );
			locator.bindComponent( m_pRefData->m_pulseStartEventLineScan, "PulseStartEvent(LineScan)" );
			locator.bindComponent( m_pRefData->m_softwareSignalPeriod_pclk, "SoftwareSignalPeriod_pclk" );
			locator.bindComponent( m_pRefData->m_output, "Output" );
			locator.bindComponent( m_pRefData->m_width_pclk, "Width_pclk" );
			locator.bindComponent( m_pRefData->m_polarity, "Polarity" );
			locator.bindComponent( m_pRefData->m_divider, "Divider" );
			if( m_pRefData->m_outputs.isValid() )
			{
				ComponentIterator it(m_pRefData->m_outputs.hObj());
				it = it.firstChild();
				while( it.isValid() )
				{
					if( it.isList() )
					{
						m_pRefData->m_mOutputs.insert( std::pair<std::string, OutputProperties*>(it.name(), new OutputProperties(it)) );
					}
					++it;
				}
			}
		}
		/// \brief Constructs a new <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber</b> from
		/// and exisiting one.
		explicit OutputSignalGeneratorFrameGrabber(	/// A constant reference to the <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber</b> object, this object shall be created from
													const OutputSignalGeneratorFrameGrabber& src ) : m_pRefData(src.m_pRefData)
		{
			++(m_pRefData->m_refCnt);
			bindPublicProperties( m_pRefData->m_outputs.hObj() );
		}
		/// \brief Class destructor.
		~OutputSignalGeneratorFrameGrabber()
		{
			dealloc();
		}
#	ifndef WRAP_PYTHON
		/// \brief Allows assignments of <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber</b> objects
		OutputSignalGeneratorFrameGrabber& operator=( const OutputSignalGeneratorFrameGrabber& rhs )
		{
			if( this != &rhs )
			{
				dealloc();
				m_pRefData = rhs.m_pRefData;
				// inc. the NEW reference count
				++m_pRefData->m_refCnt;
				bindPublicProperties( m_pRefData->m_outputs.hObj() );
			}
			return *this;
		}
#	endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
		/// \brief Assigns a single pulse to a digital output.
		///
		/// Whenever a single pulse of a certain duration and polarity shall be generated
		/// on a digital output as a reaction on a trigger signal that was either generated by one of
		/// digital inputs of the device or software this is the right function to use.
		///
		/// When the signal is generated can be defined by the properties 
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::pulseStartEvent</b> and
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::imageTrigger</b>.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::undefineSignal</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int definePulse(	/// A pointer to a <b>mvIMPACT::acquire::DigitalOutput</b> object
							/// obtained from an instance of the class <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b>
							/// for this device.
							DigitalOutput* pOutput,
							/// The polarity of the pulse to generate.
							///
							/// - 0: The pulse will be low for \a width_pclk and high otherwise
							/// - 1: The pulse will be high for \a width_pclk and high otherwise
							int polarity,
							/// The delay after the trigger event before a signal generation starts
							int delay,
							/// The width of the pulse to generate
							int width )
		{
			OutputProperties* p = getOutputProperties( pOutput );
			if( p )
			{
				p->mode.write( ddomPulse );
				p->polarity.write( polarity );
				p->delay_us.write( delay );
				p->width_us.write( width );
				return DMR_NO_ERROR;
			}
			else
			{
				return DMR_FEATURE_NOT_AVAILABLE;
			}
		}
		/// \brief Assigns a complex signal to a digital output.
		///
		/// This function can be used when a complex signal shall be generated
		/// on a digital output as a reaction on a trigger signal that was either generated by one of
		/// digital inputs of the device or software.
		///
		/// When the signal is generated can be defined by the properties 
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::pulseStartEvent</b> and
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::imageTrigger</b>.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::undefineSignal</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int definePulseSequence(	/// A pointer to a <b>mvIMPACT::acquire::DigitalOutput</b> object
									/// obtained from an instance of the class <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b>
									/// for this device.
									DigitalOutput* pOutput,
									/// The start level of the generated signal.
									///
									/// - 0: The signal will start with 'low'
									/// - 1: The signal will start with 'high'
									int startLevel,
									/// An array of integer values. Each values defines a switch in polarity
									/// of the signal after 'x' us.
									/// An array containing '1000', '2000' therefore will describe a signal
									/// starting with \a startLevel, switches polarity after 1000 us and then
									/// again switches polarity after 2000 us.
									std::vector<int>& sequence )
		{
			OutputProperties* p = getOutputProperties( pOutput );
			if( p )
			{
				p->mode.write( ddomUser );
				p->startLevel.write( startLevel );
				p->polaritySwitchAfter_us.write( sequence );
				return DMR_NO_ERROR;
			}
			else
			{
				return DMR_FEATURE_NOT_AVAILABLE;
			}
		}
		/// \brief Removes the signal definition from the specified output pin.
		///
		/// Whenever a signal has been defined for a a certain digital output
		/// pin, this pin can no longer controlled using the corresponding functions
		/// in the class <b>mvIMPACT::acquire::DigitalOutput</b>. This function removes the
		/// signal definition and hands back manual control of that digital output to the user.
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int undefineSignal(	/// A pointer to a <b>mvIMPACT::acquire::DigitalOutput</b> object
							/// obtained from an instance of the class <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b>
							/// for this device.
							DigitalOutput* pOutput )
		{
			OutputProperties* p = getOutputProperties( pOutput );
			if( p )
			{
				p->mode.write( ddomManual );
				return DMR_NO_ERROR;
			}
			else
			{
				return DMR_FEATURE_NOT_AVAILABLE;
			}
		}
		/// \brief Defines a pulse to trigger line scan cameras.
		///
		/// Calling this function without setting <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::controlMode</b>
		/// to <b>mvIMPACT::acquire::TDigitalOutputControlMode::docmRTC</b> will have <b>NO</b> effect.
		///
		/// \note
		/// Not every frame grabber will offer the <b>mvIMPACT::acquire::TDigitalOutputControlMode::docmRTC</b>
		/// mode. Check is the mode is available by reading the properties translation dictionary with
		/// the functions <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDictValue</b>. The detailed description
		/// of this class might contain source code examples for the language you are working with.
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		///
		/// \sa
		/// <b>mvIMPACT::acquire::OutputSignalGeneratorFrameGrabber::undefineSignal</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int defineLineScanPulse(	/// A pointer to a <b>mvIMPACT::acquire::DigitalOutput</b> object
									/// obtained from an instance of the class <b>mvIMPACT::acquire::IOSubSystemFrameGrabber</b>
									/// for this device.
									DigitalOutput* pOutput,
									/// Defines the start event for the signal generation. Valid values for this parameter
									/// are defined by <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent</b>.
									TDeviceSignalOutputStartEvent pulseStartEvent,
									/// Defines the frequency for a continuously generated signal if
									/// \a pulseStartEvent is <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInRisingEdge</b>
									/// or <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInFallingEdge</b> and is 
									/// ignored otherwise.
									int softwareSignalPeriod_pclk,
									/// The width of the signal to generate if \a pulseStartEvent is <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInRisingEdge</b>,
									/// <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsosePeriodically</b> or
									/// <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInFallingEdge</b> and is 
									/// ignored otherwise.
									int width_pclk,
									/// The polarity of the signal to generate if \a pulseStartEvent is <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInRisingEdge</b>,
									/// <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsosePeriodically</b> or
									/// <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsoseSyncInFallingEdge</b> and is 
									/// ignored otherwise.
									///
									/// - 0: The signal will be low for \a width_pclk and high otherwise
									/// - 1: The signal will be high for \a width_pclk and high otherwise
									int polarity,
									/// Defines the divider value if \a pulseStartEvent is
									/// <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent::dsosePeriodically</b>
									unsigned int divider )
		{
			OutputProperties* p = getOutputProperties( pOutput );
			if( p )
			{
				m_pRefData->m_pulseStartEventLineScan.write( pulseStartEvent );
				m_pRefData->m_output.writeS( pOutput->getDescription() );
				switch( pulseStartEvent )
				{
				case dsoseSyncInRisingEdge:
				case dsoseSyncInFallingEdge:
					m_pRefData->m_width_pclk.write( width_pclk );
					m_pRefData->m_polarity.write( polarity );
					m_pRefData->m_divider.write( divider );
					break;
				case dsosePeriodically:
					m_pRefData->m_softwareSignalPeriod_pclk.write( softwareSignalPeriod_pclk );
					m_pRefData->m_width_pclk.write( width_pclk );
					m_pRefData->m_polarity.write( polarity );
					break;
				default:
					// nothing to do
					break;
				}
				return DMR_NO_ERROR;
			}
			else
			{
				return DMR_FEATURE_NOT_AVAILABLE;
			}
		}	
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the general method used to create output
		/// signals.
		///
		/// This setting always applies to every signal defined. Modifying this property will also 
		/// change the behaviour of signals already defined.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDigitalOutputControlMode</b>.
		///
		/// When switching to <b>mvIMPACT::acquire::TDigitalOutputControlMode::docmRTC</b> mode
		/// only one signal can be created currently.
		///
		/// \note
		/// Not every frame grabber will offer the <b>mvIMPACT::acquire::TDigitalOutputControlMode::docmRTC</b>
		/// mode. Check is the mode is available by reading the properties translation dictionary with
		/// the functions <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyIDigitalOutputControlMode::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		PropertyIDigitalOutputControlMode controlMode;
		/// \brief An enumerated integer property defining the general behaviour of created output
		/// signals.
		///
		/// This setting always applies to every signal defined. Modifying this property will also 
		/// change the behaviour of signals already defined.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceSignalOutputStartEvent</b>.
		PropertyIDeviceSignalOutputStartEvent pulseStartEvent;
		/// \brief An enumerated integer property defining the general behaviour of created output
		/// signals.
		///
		/// This setting always applies to every signal defined. Modifying this property will also 
		/// change the behaviour of signals already defined.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceImageTrigger</b>.
		PropertyIDeviceImageTrigger imageTrigger;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIDigitalOutputControlMode getControlMode( void ) { return controlMode; }
		PropertyIDeviceSignalOutputStartEvent getPulseStartEvent( void ) const { return pulseStartEvent; }
		PropertyIDeviceImageTrigger getImageTrigger( void ) const { return imageTrigger; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

//-----------------------------------------------------------------------------
/// \brief A base class for camera related settings.
///
/// This class acts as a base class for camera related settings. It can't be constructed
/// directly by the user.
class CameraSettingsBase : public ComponentCollection
//-----------------------------------------------------------------------------
{
protected:
	explicit	CameraSettingsBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal setting to access with this instance.
									/// A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
									/// settings can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
									const std::string& settingName = "Base" ) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltSetting, settingName.c_str());
		locator.bindSearchBase( locator.searchbase_id(), "Camera" );
		m_hRoot = locator.searchbase_id();
		locator.bindComponent( imageRequestTimeout_ms, "ImageRequestTimeout_ms" );
		locator.bindSearchBase( locator.searchbase_id(), "Aoi" );
		locator.bindComponent( aoiHeight, "H" );
		locator.bindComponent( aoiStartX, "X" );
		locator.bindComponent( aoiStartY, "Y" );
		locator.bindComponent( aoiWidth, "W" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief An integer property defining the number of lines to capture.
	PropertyI aoiHeight;
	/// \brief An integer property defining the X-offset for each capture line.
	///
	/// Example: When setting this property to 5 the first pixel in each line of
	/// the resulting image will be pixel number 5 of each line transmitted by
	/// the camera.
	PropertyI aoiStartX;
	/// \brief An integer property defining the Y-offset.
	///
	/// Example: When setting this property to 5 the first line of
	/// the resulting image will be line number 5 of the image transmitted by
	/// the camera.
	PropertyI aoiStartY;
	/// \brief An integer property defining the number of pixels to capture per line.
	PropertyI aoiWidth;
	/// \brief An integer property defining the maximum time to wait for an image in ms.
	PropertyI imageRequestTimeout_ms;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI getAoiHeight( void ) const { return aoiHeight; }
	PropertyI getAoiStartX( void ) const { return aoiStartX; }
	PropertyI getAoiStartY( void ) const { return aoiStartY; }
	PropertyI getAoiWidth( void ) const { return aoiWidth; }
	PropertyI getImageRequestTimeout_ms( void ) const { return imageRequestTimeout_ms; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief Camera related settings.
///
/// This class contains properties to modify camera related parameters.
///
/// \note
/// This class is provided for compatibility only and has been declared deprecated! Only
/// the <b>mvBlueFOX</b> supports all the properties declared in this class. No new
/// properties will be added to this class anymore.<br>
/// Users should use the device specific setting classes derived from
/// <b>mvIMPACT::acquire::CameraSettingsBase</b>
/// \if BUILD_MVGRABBER_DOCUMENTATION
/// \note
/// like e.g. <b>mvIMPACT::acquire::CameraSettingsFrameGrabber</b>
/// \elseif BUILD_MVBLUEFOX_DOCUMENTATION
/// \note
/// like e.g. <b>mvIMPACT::acquire::CameraSettingsBlueFOX</b>
/// \endif
class CameraSettings : public CameraSettingsBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new instance of <b>mvIMPACT::acquire::CameraSettings</b>.
	explicit CameraSettings( /// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
							Device* pDev,
							/// The name of the driver internal setting to access with this instance.
							/// A list of valid setting name can be obtained by a call to
							/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
							/// settings can be created with the function
							/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
							const std::string& settingName = "Base" ) : CameraSettingsBase(pDev, settingName)
	{
		ComponentLocator locator( m_hRoot );
		locator.bindComponent( gain_dB, "Gain_dB" );
		locator.bindComponent( offset_pc, "Offset_pc" );
		locator.bindComponent( offsetAutoCalibration, "OffsetAutoCalibration" );
		locator.bindComponent( triggerMode, "TriggerMode" );
		locator.bindComponent( exposeMode, "ExposeMode" );
		locator.bindComponent( pixelClock_KHz, "PixelClock_KHz" );
		locator.bindComponent( expose_us, "Expose_us" );
		locator.bindComponent( binningMode, "BinningMode" );
		locator.bindComponent( frameDelay_us, "FrameDelay_us" );
		locator.bindComponent( lineDelay_clk, "LineDelay_clk" );
		locator.bindComponent( flashMode, "FlashMode" );
		locator.bindComponent( testMode, "TestMode" );
		locator.bindComponent( triggerSource, "TriggerSource" );
	}
	PYTHON_ONLY(%immutable;)
	/// \brief An integer property defining the gain in dB.
	PropertyF gain_dB;
	/// \brief An integer property defining the analogue sensor offset in percent of the
	/// allowed range (sensor specific).
	///
	/// This property has no effect if <b>mvIMPACT::acquire::CameraSettings::offsetAutoCalibration</b> is set to
	/// <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b>.
	PropertyF offset_pc;
	/// \brief An enumerated integer property defining the offset calibration mode.
	///
	/// If this property is set to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOff</b>
	/// the offset can be adjusted manually by modifying the <b>mvIMPACT::acquire::CameraSettings::offset_pc</b> property.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoOffsetCalibration</b>.
	PropertyIAutoOffsetCalibration offsetAutoCalibration;
	/// \brief An enumerated integer property which defines what kind of trigger mode
	/// shall be used for an image acquisition.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraTriggerMode</b>.
	PropertyICameraTriggerMode triggerMode;
	/// \brief An enumerated integer property defining the exposure mode the camera sensor
	/// is operated in.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExposeMode</b>.
	PropertyICameraExposeMode exposeMode;
	/// \brief An enumerated integer property defining the pixel clock of the camera sensor in KHz.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraPixelClock</b>.
	PropertyICameraPixelClock pixelClock_KHz;
	/// \brief An integer property which defines the exposure time for an
	/// image in us.
	PropertyI expose_us;
	/// \brief An enumerated integer property defining the binning mode the camera is operated in.
	///
	/// By default the no binning will be performed.
	/// \note
	/// Not every camera will support every binning mode. To find out which binning modes
	/// are supported by your camera you can query the properties translation table with
	/// the functions <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictString</b> and
	/// <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictValue</b>
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDict</b>
	/// in addition to the functions mentioned above.
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraBinningMode</b>.
	PropertyICameraBinningMode binningMode;
	/// \brief An integer property defining the delay in us between an external trigger
	/// event an the begin of the sensor exposure.
	PropertyI frameDelay_us;
	/// \brief An integer property defining the delay in clocks between two lines.
	///
	/// Can be used to slow down the image readout the reduce the peak bandwidth required
	/// for the transfer.
	PropertyI lineDelay_clk;
	/// \brief An enumerated integer property defining the behaviour of the flash output
	/// of the camera (if available).
	///
	/// If this property is set the cameras flash output (if available) will be pulsed
	/// during the exposure period of the sensor.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraFlashMode</b>.
	PropertyICameraFlashMode flashMode;
	/// \brief An enumerated integer property defining the image transmission mode of the camera.
	///
	/// If this property is set to <b>mvIMPACT::acquire::TCameraTestMode::ctmOff</b> the 'normal' image
	/// captured by the cameras sensor will be transmitted. This is the default.
	/// To ensure correct operation the camera might define several test modes where
	/// some kind of well defined pattern will be transmitted.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraFlashMode</b>.
	PropertyICameraTestMode testMode;
	/// \brief An enumerated integer property defining where the trigger signal is
	/// expected to occur.
	///
	/// When working with hardware generated signals via <b>mvIMPACT::acquire::RTCtrProgram</b> objects
	/// this property should be set to <b>mvIMPACT::acquire::TCameraTriggerSource::ctsRTCtrl</b> as otherwise
	/// the program will not affect the behaviour of the camera.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraTriggerSource</b>.
	PropertyICameraTriggerSource triggerSource;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyF						getGain_dB( void ) const { return gain_dB; }
	PropertyF						getOffset_pc( void ) const { return offset_pc; }
	PropertyIAutoOffsetCalibration	getOffsetAutoCalibration( void ) const { return offsetAutoCalibration; }
	PropertyICameraTriggerMode		getTriggerMode( void ) const { return triggerMode; }
	PropertyICameraExposeMode		getExposeMode( void ) const { return exposeMode; }
	PropertyICameraPixelClock		getPixelClock_KHz( void ) const { return pixelClock_KHz; }
	PropertyI						getExpose_us( void ) const { return expose_us; }
	PropertyICameraBinningMode		getBinningMode( void ) const { return binningMode; }
	PropertyI						getFrameDelay_us( void ) const { return frameDelay_us; }
	PropertyI						getLineDelay_clk( void ) const { return lineDelay_clk; }
	PropertyICameraFlashMode		getFlashMode( void ) const { return flashMode; }
	PropertyICameraTestMode			getTestMode( void ) const { return testMode; }
	PropertyICameraTriggerSource	getTriggerSource( void ) const { return triggerSource; }
#endif // #ifdef DOTNET_ONLY_CODE
};

#ifndef IGNORE_MVBLUELYNX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief Camera related settings.
	///
	/// This class contains properties to modify camera related parameters.
	class CameraSettingsBlueLYNX : public CameraSettingsBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new instance of <b>mvIMPACT::acquire::CameraSettingsBlueLYNX</b>.
		explicit CameraSettingsBlueLYNX( /// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal setting to access with this instance.
									/// A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
									/// settings can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
									const std::string& settingName = "Base" ) : CameraSettingsBase( pDev, settingName )
		{
			ComponentLocator locator( m_hRoot );
			locator.bindComponent( gain_dB,                "Gain_dB" );
			locator.bindComponent( offset_pc,              "Offset_pc" );
			locator.bindComponent( offsetAutoCalibration,  "OffsetAutoCalibration" );
			locator.bindComponent( triggerMode,            "TriggerMode" );
			locator.bindComponent( exposeMode,             "ExposeMode" );
			locator.bindComponent( pixelClock_KHz,         "PixelClock_KHz" );
			locator.bindComponent( expose_us,              "Expose_us" );
			locator.bindComponent( binningMode,            "BinningMode" );
			locator.bindComponent( frameDelay_us,          "FrameDelay_us" );
			locator.bindComponent( lineDelay_clk,          "LineDelay_clk" );
			locator.bindComponent( flashMode,              "Flash" );
			locator.bindComponent( flashOutputMask,        "FlashOutputMask" );
			locator.bindComponent( testMode,               "TestMode" );
			locator.bindComponent( dataClipMode,           "DataClipMode" );
			locator.bindComponent( preFlashMode,           "PreFlashMode" );
			locator.bindComponent( flashTime_lines,        "FlashTime_lines" );
			locator.bindComponent( preExposeErase,         "PreExposeErase" );
			locator.bindComponent( inputThreshold_mV,      "InputThreshold_mV" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property defining the gain in dB.
		PropertyF								gain_dB;
		/// \brief An integer property defining the analogue sensor offset in percent of the
		/// allowed range (sensor specific).
		///
		/// This property has no effect if <b>mvIMPACT::acquire::CameraSettings::offsetAutoCalibration</b> is set to
		/// <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b>.
		PropertyF								offset_pc;
		/// \brief An enumerated integer property defining the offset calibration mode.
		///
		/// If this property is set to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOff</b>
		/// the offset can be adjusted manually by modifying the <b>mvIMPACT::acquire::CameraSettings::offset_pc</b> property.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoOffsetCalibration</b>.
		PropertyIAutoOffsetCalibration			offsetAutoCalibration;
		/// \brief An enumerated integer property which defines what kind of trigger mode
		/// shall be used for an image acquisition.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraTriggerMode</b>.
		PropertyICameraTriggerMode				triggerMode;
		/// \brief An enumerated integer property defining the exposure mode the camera sensor
		/// is operated in.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueLYNXCameraExposeMode</b>.
		PropertyIBlueLYNXCameraExposeMode		exposeMode;
		/// \brief An enumerated integer property defining the pixel clock of the camera sensor in KHz.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueLYNXCameraPixelClock</b>.
		PropertyIBlueLYNXCameraPixelClock		pixelClock_KHz;
		/// \brief An integer property which defines the exposure time for an
		/// image in us.
		PropertyI								expose_us;
		/// \brief An enumerated integer property defining the binning mode the camera is operated in.
		///
		/// By default the no binning will be performed.
		/// \note
		/// Not every camera will support every binning mode. To find out which binning modes
		/// are supported by your camera you can query the properties translation table with
		/// the functions <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraBinningMode</b>.
		PropertyICameraBinningMode				binningMode;
		/// \brief An integer property defining the delay in us between an external trigger
		/// event an the begin of the sensor exposure.
		PropertyI								frameDelay_us;
		/// \brief An integer property defining the delay in clocks between two lines.
		///
		/// Can be used to slow down the image readout the reduce the peak bandwidth required
		/// for the transfer.
		PropertyI								lineDelay_clk;
		/// \brief An enumerated integer property defining the behaviour of the flash output
		/// of the camera (if available).
		///
		/// If this property is set the cameras flash output (if available) will be pulsed
		/// during the exposure period of the sensor.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueLYNXCameraFlashMode</b>.
		PropertyIBlueLYNXCameraFlashMode		flashMode;
		/// \brief An integer property defining flash output mask.
		///
		/// If this property can be set specified for <b>mvIMPACT::acquire::TBlueLYNXCameraFlashMode::blcfmSoftware</b>.
		PropertyI 								flashOutputMask;
		/// \brief An enumerated integer property defining the image transmission mode of the camera.
		///
		/// If this property is set to <b>mvIMPACT::acquire::TCameraTestMode::ctmOff</b> the 'normal' image
		/// captured by the cameras sensor will be transmitted. This is the default.
		/// To ensure correct operation the camera might define several test modes where
		/// some kind of well defined pattern will be transmitted.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraFlashMode</b>.
		PropertyICameraTestMode					testMode;
		/// \brief An enumerated integer property defining the behaviour of the sensor video data.
		///
		/// If this property is set to <b>TBlueLYNXCameraDataClipMode::blcdcmOn</b> the video data
		/// will be clipped to <b>247</b>, leaves room to draw overlay with color information.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueLYNXCameraDataClipMode</b>.
		PropertyIBlueLYNXCameraDataClipMode		dataClipMode;
		/// \brief An integer property defining the delay if the flash to exposure.
		///
		/// If this property is <b>>0</b> (<i>e.g. set to n</i>) the flash starts <b>n</b> lines prior to exposure.
		PropertyI 								preFlashMode;
		/// \brief An integer property defining the flash time in lines.
		///
		/// If this property is <b>0</b> (<i>auto mode</i>) the flash signal is on during the pre-flash
		/// and exposure of sensor. By setting the property to a value <b>>0 == n</b> the flash signal is on
		/// for <b>n lines</b> while the pre-flash is active.
		PropertyI 								flashTime_lines;
		/// \brief An integer property defining a pre exposure erasure.
		///
		/// If this property is <b>0</b> no erase takes place between trigger signal and the expose.
		/// For a value <b>>0 == n</b> the sensor performs <b>n</b> erase cycles.
		PropertyI 								preExposeErase;
		/// \brief An integer property defining the input switching threshold for the digital inputs in <b>mV</b> resolution.
		///
		/// The range is <i>(1..16V)</i>, if the threshold is outside this range it will be clipped silently
		/// to legal values. This level determines at which voltage a logical <b>1</b> or <b>0</b> is recognised.
		/// \note There is an hysteresis of <b>+/-0.5V</b> at the digital inputs.
		PropertyI 								inputThreshold_mV;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyF							getGain_dB( void ) const                { return gain_dB; }
		PropertyF							getOffset_pc( void ) const              { return offset_pc; }
		PropertyIAutoOffsetCalibration		getOffsetAutoCalibration( void ) const  { return offsetAutoCalibration; }
		PropertyICameraTriggerMode			getTriggerMode( void ) const            { return triggerMode; }
		PropertyIBlueLYNXCameraExposeMode	getExposeMode( void ) const             { return exposeMode; }
		PropertyIBlueLYNXCameraPixelClock	getPixelClock_KHz( void ) const         { return pixelClock_KHz; }
		PropertyI							getExpose_us( void ) const              { return expose_us; }
		PropertyICameraBinningMode			getBinningMode( void ) const            { return binningMode; }
		PropertyI							getFrameDelay_us( void ) const          { return frameDelay_us; }
		PropertyI							getLineDelay_clk( void ) const          { return lineDelay_clk; }
		PropertyIBlueLYNXCameraFlashMode	getFlashMode( void ) const              { return flashMode; }
		PropertyI 							getFlashOutputMask( void ) const        { return flashOutputMask; }
		PropertyICameraTestMode				getTestMode( void ) const               { return testMode; }
		PropertyIBlueLYNXCameraDataClipMode	getDataClipMode( void ) const           { return dataClipMode; }
		PropertyI 							getPreFlashMode( void ) const           { return preFlashMode; }
		PropertyI 							getFlashTime_lines( void ) const        { return flashTime_lines; }
		PropertyI 							getPreExposeErase( void ) const         { return preExposeErase; }
		PropertyI 							getInputThreshold_mV( void ) const      { return inputThreshold_mV; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUELYNX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class to control the automatic control parameters of the <b>mvBlueFOX</b>
	/// camera.
	///
	/// This class provides access to the properties, which control the way the
	/// AGC(<b>A</b>utomatic <b>G</b>ain <b>C</b>ontrol) and the AEC
	/// (<b>A</b>utomatic <b>E</b>xpose <b>C</b>ontrol) operates.
	///
	/// The values used to capture the image, which are directly influenced by this properties
	/// (e.g. the gain or the exposure time) will be returned as part of the result of the
	/// image request.
	///
	/// \note
	/// Objects of these class can't be constructed directly. It's parameters can
	/// be accessed via an instance of the class <b>mvIMPACT::acquire::CameraSettingsBlueFOX</b>.
	///
	/// \note
	/// <b>IMPORTANT:</b> This part is subject to change in upcoming releases! Use it with
	/// care!
	///
	/// \sa
	/// <b>mvIMPACT::acquire::RequestInfo, <br>mvIMPACT::acquire::Request::getInfo</b>
	class AutoControlParametersBlueFOX
	//-----------------------------------------------------------------------------
	{
		friend class CameraSettingsBlueFOX;
		explicit AutoControlParametersBlueFOX( HOBJ hObj )
		{
			ComponentLocator locator( hObj, "AutoControlParameters" );
			locator.bindComponent( desiredAverageGreyValue, "DesiredAverageGreyValue" );
			locator.bindComponent( controllerSpeed, "ControllerSpeed" );
			locator.bindComponent( controllerDelay_Images, "ControllerDelay_Images" );
			locator.bindComponent( aoiMode, "AoiMode" );
			locator.bindComponent( gainLowerLimit_dB, "GainLowerLimit_dB" );
			locator.bindComponent( gainUpperLimit_dB, "GainUpperLimit_dB" );
			locator.bindComponent( exposeLowerLimit_us, "ExposeLowerLimit_us" );
			locator.bindComponent( exposeUpperLimit_us, "ExposeUpperLimit_us" );
			locator.bindSearchBase( locator.searchbase_id(), "Aoi" );
			locator.bindComponent( aoiHeight, "H" );
			locator.bindComponent( aoiStartX, "X" );
			locator.bindComponent( aoiStartY, "Y" );
			locator.bindComponent( aoiWidth, "W" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property defining the height of the rectangle used for
		/// the parameter calculation.
		PropertyI aoiHeight;
		/// \brief An integer property defining the X-offset of the rectangle used for
		/// the parameter calculation.
		///
		/// Example: When setting this property to 5 the first pixel in each line of
		/// the resulting rectangle used for the calculation will be pixel number 5
		/// of each line transmitted by the camera.
		PropertyI aoiStartX;
		/// \brief An integer property defining the Y-offset of the rectangle used for the
		/// parameter calculation.
		///
		/// Example: When setting this property to 5 the first line of
		/// the resulting rectangle used for the calculation will be line number 5 of the
		/// image transmitted by the camera.
		PropertyI aoiStartY;
		/// \brief An integer property defining the width of the rectangle.
		PropertyI aoiWidth;
		/// \brief An enumerated integer property defining the which area of the image is used
		/// for the calculation of the parameters.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAoiMode</b>.
		PropertyIAoiMode aoiMode;
		/// \brief An integer property defining the average grey value to be reached within
		/// the AOI in the image by the control circuit.
		PropertyI desiredAverageGreyValue;
		/// \brief An enumerated integer property defining the speed the control ciruit will
		/// be operated in.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoControlSpeed</b>.
		///
		/// Once the controller started to react and adapt itself to a new situation, this property will
		/// define how long this adaption will take, while <b>AutoControlParametersBlueFOX::controllerDelay_Images</b>
		/// defines the the number of images to wait from a detected change to the actual start of the 
		/// adaption to this new situation.
		PropertyIAutoControlSpeed controllerSpeed;
		/// \brief An integer property to influence the speed the AGC and/or AEC control circuit will react and adapt
		/// to changes.
		///
		/// While <b>AutoControlParametersBlueFOX::controllerSpeed</b> influences the overall time
		/// needed to adjust the controller to a new situation, this property can be used to define a
		/// delay when the controller shall start to adapt to a changed situation.
		PropertyI controllerDelay_Images;
		/// \brief A float property defining the lower limit for the cameras gain(in dB).
		///
		/// When the AGC is active this value defines the minimum value for the cameras gain.
		/// Even if the controller can reach the desired average grey value, the gain will
		/// never fall below this value.
		PropertyF gainLowerLimit_dB;
		/// \brief A float property defining the upper limit for the cameras gain(in dB).
		///
		/// When the AGC is active this value defines the maximum value for the cameras gain.
		/// Even if the controller can reach the desired average grey value, the gain will
		/// never exceed this value.
		PropertyF gainUpperLimit_dB;
		/// \brief An integer property defining the lower limit for the sensors expose time(in us).
		///
		/// When the AEC is active this value defines the minimum value for the sensors expose time(in us).
		/// Even if the controller can reach the desired average grey value, the expose time will
		/// never fall below this value.
		PropertyI exposeLowerLimit_us;
		/// \brief An integer property defining the upper limit for the sensors expose time in us.
		///
		/// When the AEC is active this value defines the maximum value for the sensors expose time(in us).
		/// Even if the controller can reach the desired average grey value, the expose time will
		/// never exceed this value.
		PropertyI exposeUpperLimit_us;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI						getAoiHeight( void ) const { return aoiHeight; }
		PropertyI						getAoiStartX( void ) const { return aoiStartX; }
		PropertyI						getAoiStartY( void ) const { return aoiStartY; }
		PropertyI						getAoiWidth( void ) const { return aoiWidth; }
		PropertyIAoiMode				getAoiMode( void ) const { return aoiMode; }
		PropertyI						getDesiredAverageGreyValue( void ) const { return desiredAverageGreyValue; }
		PropertyIAutoControlSpeed		getControllerSpeed( void ) const { return controllerSpeed; }
		PropertyI						getControllerDelay_Images( void ) const { return controllerDelay_Images; }
		PropertyF						getGainLowerLimit_dB( void ) const { return gainLowerLimit_dB; }
		PropertyF						getGainUpperLimit_dB( void ) const { return gainUpperLimit_dB; }
		PropertyI						getExposeLowerLimit_us( void ) const { return exposeLowerLimit_us; }
		PropertyI						getExposeUpperLimit_us( void ) const { return exposeUpperLimit_us; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief <b>mvBlueFOX</b> related camera settings.
	///
	/// This class contains properties to control the way the image sensor of the
	/// <b>mvBlueFOX</b> behaves.
	///
	/// \note
	/// <b>IMPORTANT:</b> This part is subject to change in upcoming releases! Use it with
	/// care!
	class CameraSettingsBlueFOX : public CameraSettingsBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::CameraSettingsBlueFOX</b> object
		explicit CameraSettingsBlueFOX( /// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
										Device* pDev,
										/// The name of the driver internal setting to access with this instance.
										/// A list of valid setting name can be obtained by a call to
										/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
										/// settings can be created with the function
										/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
										const std::string& settingName = "Base" ) : CameraSettingsBase(pDev, settingName),
											autoControlParameters(m_hRoot)
		{
			ComponentLocator locator( m_hRoot );
			locator.bindComponent( gain_dB, "Gain_dB" );
			locator.bindComponent( offset_pc, "Offset_pc" );
			locator.bindComponent( offsetAutoCalibration, "OffsetAutoCalibration" );
			locator.bindComponent( offsetAutoBlackLevel, "OffsetAutoBlackLevel" );			
			locator.bindComponent( triggerMode, "TriggerMode" );
			locator.bindComponent( exposeMode, "ExposeMode" );
			locator.bindComponent( pixelClock_KHz, "PixelClock_KHz" );
			locator.bindComponent( expose_us, "Expose_us" );
			locator.bindComponent( binningMode, "BinningMode" );
			locator.bindComponent( frameDelay_us, "FrameDelay_us" );
			locator.bindComponent( lineDelay_clk, "LineDelay_clk" );
			locator.bindComponent( flashToExposeDelay_us, "FlashToExposeDelay_us" );
			locator.bindComponent( flashMode, "FlashMode" );
			locator.bindComponent( testMode, "TestMode" );
			locator.bindComponent( triggerSource, "TriggerSource" );
			locator.bindComponent( autoGainControl, "AutoGainControl" );
			locator.bindComponent( sensorTimingMode, "SensorTimingMode" );
			locator.bindComponent( autoExposeControl, "AutoExposeControl" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property defining the gain in dB.
		PropertyF gain_dB;
		/// \brief An integer property defining the analogue sensor offset in percent of the
		/// allowed range (sensor specific).
		///
		/// This property has no effect if <b>mvIMPACT::acquire::CameraSettings::offsetAutoCalibration</b> is set to
		/// <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b>.
		///
		/// This property influences the average grey level when no light reaches the sensor. By default
		/// this value will be around 10 (if <b>mvIMPACT::acquire::CameraSettingsBlueFOX::offsetAutoCalibration</b> if set
		/// to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b>). This means the average grey value for an image
		/// taken in a completely dark environment will be around 10. When setting
		/// <b>mvIMPACT::acquire::CameraSettingsBlueFOX::offsetAutoCalibration</b> to <b>TAutoOffsetCalibration::aocOff</b>
		///	<b>mvIMPACT::acquire::CameraSettingsBlueFOX::offset_pc</b> can be used to modify this value.
		///
		/// \image html Offset_pc.png
		/// The valid range for this property lies between -100% and +100%, whereas negative values
		/// will shifts the black level towards 0 and positive values to 255.
		PropertyF offset_pc;
		/// \brief An enumerated integer property defining the offset calibration mode.
		///
		/// If this property is set to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOff</b>
		/// the offset can be adjusted manually by modifying the <b>mvIMPACT::acquire::CameraSettings::offset_pc</b> property.
		///
		///	If set to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b> the offset is approx. 10. That means,
		/// that the medium pixel count is 10, in case no light is falling on the sensor.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoOffsetCalibration</b>.
		PropertyIAutoOffsetCalibration offsetAutoCalibration;
		/// \brief An integer property defining the digital value assumed as black.
		///
		/// Modifying this property in rare cases might be useful to achieve a higher dynamic range for noise close to the black
		/// level.
		///
		/// \note
		/// As the <b>mvBlueFOX</b> internally works with a 10 bit analog to digital conversion increasing this
		/// value by 4 will result in a black level increased by about 1 in the resulting 8 bit raw image 
		/// delivered from the camera.
		PropertyI offsetAutoBlackLevel;
		/// \brief An enumerated integer property which defines what kind of trigger mode
		/// shall be used for an image acquisition.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraTriggerMode</b>.
		PropertyICameraTriggerMode triggerMode;
		/// \brief An enumerated integer property defining the exposure mode the camera sensor
		/// is operated in.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExposeMode</b>.
		PropertyICameraExposeMode exposeMode;
		/// \brief An enumerated integer property defining the pixel clock of the camera sensor in KHz.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraPixelClock</b>.
		///
		/// \note
		/// Changing the pixel clock at runtime will have major impact on the overall behaviour of the
		/// camera. The pixel clock should therefore not be modified constantly during the execution
		/// of the application code. Whenever this property is changed, the next images caputured should
		/// be skipped if <b>mvIMPACT::acquire::CameraSettingsBlueFOX::offsetAutoCalibration</b> is set
		/// to <b>mvIMPACT::acquire::TAutoOffsetCalibration::aocOn</b> (which is the default) as then the
		/// control circuits on the camera might need one to three images until all control loops are
		/// locked again.
		///
		/// Every type of mvBlueFOX supports different pixel clocks, thus it's crucial to query the valid
		/// clock modes for each sensor by reading the properties translation dictionary.
		PropertyICameraPixelClock pixelClock_KHz;
		/// \brief An integer property which defines the exposure time for an
		/// image in us.
		PropertyI expose_us;
		/// \brief An enumerated integer property defining the binning mode the camera is operated in.
		///
		/// By default the no binning will be performed.
		/// \note
		/// Not every camera will support every binning mode. To find out which binning modes
		/// are supported by your camera you can query the properties translation table with
		/// the functions <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraBinningMode::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraBinningMode</b>.
		PropertyICameraBinningMode binningMode;
		/// \brief An integer property defining the delay in us between an external trigger
		/// event an the begin of the sensor exposure.
		PropertyI frameDelay_us;
		/// \brief An integer property defining the delay in clocks between two lines.
		///
		/// Can be used to slow down the image readout the reduce the peak bandwidth required
		/// for the transfer.
		PropertyI lineDelay_clk;
		/// \brief An integer property defining the delay in us betwenn the start of the flash signal output
		/// and the beginning of the expose period of the image sensor.
		///
		/// \note
		/// This property is mainly provided for compatibility reasons. Previous versions of the 
		/// <b>mvBlueFOX</b> driver produced a fixed delay of about 300 us between the beginning of the
		/// flash signal creation and the beginning of the sensors expose period. Newer versions of the
		/// driver do <b>NOT</b> produce this delay anymore which might cause a different illumination
		/// for applications using very intensive, short flash and expose times. Applications relying on
		/// the delay introduced in older driver versions should set this property to
		/// '300' by calling <b>mvIMPACT::acquire::PropertyI::write</b>.
		PropertyI flashToExposeDelay_us;
		/// \brief An enumerated integer property defining the behaviour of the flash output
		/// of the camera (if available).
		///
		/// If this property is set the cameras flash output (if available) will be pulsed
		/// during the exposure period of the sensor.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraFlashMode</b>.
		PropertyICameraFlashMode flashMode;
		/// \brief An enumerated integer property defining the image transmission mode of the camera.
		///
		/// If this property is set to <b>mvIMPACT::acquire::TCameraTestMode::ctmOff</b> the 'normal' image
		/// captured by the cameras sensor will be transmitted. This is the default.
		/// To ensure correct operation the camera might define several test modes where
		/// some kind of well defined pattern will be transmitted.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraFlashMode</b>.
		PropertyICameraTestMode testMode;
		/// \brief An enumerated integer property defining where the trigger signal is
		/// expected to occur.
		///
		/// When working with hardware generated signals via <b>mvIMPACT::acquire::RTCtrProgram</b> objects
		/// this property should be set to <b>mvIMPACT::acquire::TCameraTriggerSource::ctsRTCtrl</b> as otherwise
		/// the program will not affect the behaviour of the camera.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraTriggerSource</b>.
		PropertyICameraTriggerSource triggerSource;
		/// \brief An enumerated integer property, which represents the current mode the AGC
		/// (<b>A</b>utomatic <b>G</b>ain <b>C</b>ontrol) is operated in.
		///
		/// The values used to capture the image, which are directly influenced by an activated AGC or AEC
		/// (e.g. the gain or the exposure time) will be returned as part of the result of the
		/// image request.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoGainControl</b>.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::RequestInfo, <br>mvIMPACT::acquire::Request::getInfo</b>
		PropertyIAutoGainControl autoGainControl;
		/// \brief An enumerated integer property, which represents the current mode the AEC
		/// (<b>A</b>utomatic <b>E</b>xpose <b>C</b>ontrol) is operated in.
		///
		/// The values used to capture the image, which are directly influenced by an activated AGC or AEC
		/// (e.g. the gain or the exposure time) will be returned as part of the result of the
		/// image request.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAutoExposureControl</b>.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::RequestInfo, <br>mvIMPACT::acquire::Request::getInfo</b>
		PropertyIAutoExposureControl autoExposeControl;
		/// \brief An enumerated integer property defining the current image sensor timing mode.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueFOXSensorTiming</b>.
		PropertyIBlueFOXSensorTiming sensorTimingMode;
		/// \brief Provides access to the control parameters for AGC and AEC.
		///
		/// \note
		/// These settings will only affect the image if <b>mvIMPACT::acquire::CameraSettingsBlueFOX::autoGainControl</b>,
		/// <b>mvIMPACT::acquire::CameraSettingsBlueFOX::autoExposeControl</b> or both are set to active.
		AutoControlParametersBlueFOX autoControlParameters;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyF						getGain_dB( void ) const { return gain_dB; }
		PropertyF						getOffset_pc( void ) const { return offset_pc; }
		PropertyIAutoOffsetCalibration	getOffsetAutoCalibration( void ) const { return offsetAutoCalibration; }
		PropertyI						getOffsetAutoBlackLevel( void ) const { return offsetAutoBlackLevel; }
		PropertyICameraTriggerMode		getTriggerMode( void ) const { return triggerMode; }
		PropertyICameraExposeMode		getExposeMode( void ) const { return exposeMode; }
		PropertyICameraPixelClock		getPixelClock_KHz( void ) const { return pixelClock_KHz; }
		PropertyI						getExpose_us( void ) const { return expose_us; }
		PropertyICameraBinningMode		getBinningMode( void ) const { return binningMode; }
		PropertyI						getFrameDelay_us( void ) const { return frameDelay_us; }
		PropertyI						getLineDelay_clk( void ) const { return lineDelay_clk; }
		PropertyI						getFlashToExposeDelay_us( void ) const { return flashToExposeDelay_us; }		
		PropertyICameraFlashMode		getFlashMode( void ) const { return flashMode; }
		PropertyICameraTestMode			getTestMode( void ) const { return testMode; }
		PropertyICameraTriggerSource	getTriggerSource( void ) const { return triggerSource; }
		PropertyIAutoGainControl		getAutoGainControl( void ) const { return autoGainControl; }
		PropertyIAutoExposureControl	getAutoExposeControl( void ) const { return autoExposeControl; }
		PropertyIBlueFOXSensorTiming	getSensorTimingMode( void ) const { return sensorTimingMode; }
		AutoControlParametersBlueFOX&	getAutoControlParameters( void ) { return autoControlParameters; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief <b>MATRIX VISION GmbH</b> frame grabber related camera settings.
	///
	/// This class contains properties to control the way the <b>MATRIX VISION GmbH</b> frame grabber
	/// behaves in connection with the connected camera.
	///
	/// \note
	/// Not every frame grabber will support every property defined in this class. Please
	/// refer to the description of the individual properties and make heavy use of the
	/// function <b>mvIMPACT::acquire::Component::isValid</b> in order to check whether
	/// a property is available for the device.
	class CameraSettingsFrameGrabber : public CameraSettingsBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::CameraSettingsFrameGrabber</b> object
		explicit CameraSettingsFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
												Device* pDev,
												/// The name of the driver internal setting to access with this instance.
												/// A list of valid setting name can be obtained by a call to
												/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
												/// settings can be created with the function
												/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
												const std::string& settingName = "Base" ) : CameraSettingsBase(pDev, settingName)
		{
			ComponentLocator locator( m_hRoot );
			locator.bindComponent( type, "Type" );
			locator.bindComponent( aoiMode, "AoiMode" );
			locator.bindComponent( gain_dB, "Gain_dB" );
			locator.bindComponent( offset_mV, "Offset_mV" );
			locator.bindComponent( scanClock, "ScanClock" );
			locator.bindComponent( triggerMode, "TriggerMode" );
			locator.bindComponent( softwareTriggerPeriod_ms, "SoftwareTriggerPeriod_ms" );
			locator.bindComponent( serialPortBaudrate, "SerialPortBaudRate" );
			locator.bindComponent( interlacedMode, "InterlacedMode" );
			locator.bindComponent( acquisitionField, "AcquisitionField" );
			locator.bindComponent( scanRateMode, "ScanRateMode" );
			locator.bindComponent( scanRate_kHz, "ScanRate_kHz" );
			locator.bindComponent( luminance_pc, "Luminance_pc" );
			locator.bindComponent( saturation_pc, "Saturation_pc" );
			locator.bindComponent( hue_pc, "Hue_pc" );
			locator.bindComponent( contrast_pc, "Contrast_pc" );
			locator.bindComponent( lineCounter, "LineCounter" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the camera description used for the 
		/// image acquisition.
		///
		/// This property <b>ALWAYS</b> defines a translation dictionary contain a string representation
		/// and a numerical value for the camera descriptions available for the device. The string
		/// representation of the camera description will be build from the name of the class this
		/// camera description belongs to (e.g. \a 'Standard', \a 'NonStandard' or \a 'CameraLink') and
		/// the name of the camera description itself. Assuming a the device can handle standard
		/// video cameras and a description for a camera named \a 'MyCCIRCamera' will therefore
		/// add \a 'Standard_MyCCIRCamera' and a unique numerical representation to the properties
		/// translation dictionary.
		PropertyI type;
		/// \brief An enumerated integer property defining the used AOI mode for the image capture.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraAoiMode</b>.
		PropertyICameraAoiMode aoiMode;
		/// \brief An integer property defining the gain in dB.
		///
		/// This is the gain applied during the analogue to digital conversion inside the frame
		/// grabber, not applied inside the camera.
		/// 
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyF gain_dB;
		/// \brief An integer property defining the offset in milli-Volt.
		///
		/// This is the analogue offset applied during the analogue to digital conversion inside the frame
		/// grabber, not applied inside the camera.
		/// 
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI offset_mV;
		/// \brief An enumerated integer property defining the scan clock mode used for the current acquisition.
		///
		/// Valid modes are defined by the enumeration <b>mvIMPACT::acquire::TScanClock</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception! Digital frame grabbers will however <b>NOT</b> support
		/// this property.
		PropertyIScanClock scanClock;
		/// \brief An enumerated integer property defining the behaviour of the frame grabbers trigger input.
		///
		/// \note 
		/// All trigger modes are defined by <b>mvIMPACT::acquire::TDeviceTriggerMode</b>. However
		/// not every device will offer all these trigger modes but a subset of them. Valid trigger modes therefore 
		/// can be found by reading the properties translation dictionary.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyIDeviceTriggerMode triggerMode;
		/// \brief An integer property defining the software simulated trigger period.
		///
		/// When <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::triggerMode</b> is set to
		/// <b>mvIMPACT::acquire::TDeviceTriggerMode::dtmPeriodically</b> this property defines the
		/// interval between two consecutive external trigger events simulated by the driver.
		///
		/// Currently this property is only available for <b>mvTITAN</b> and <b>mvGAMMA</b> frame grabbers.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI softwareTriggerPeriod_ms;
		/// \brief An enumerated integer property defining the baud rate of the serial communication port
		/// between frame grabber and camera.
		///
		/// Currently this property is only available for CameraLink&reg; frame grabbers.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraSerialPortBaudRate</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyICameraSerialPortBaudRate serialPortBaudrate;
		/// \brief An enumerated integer property defining how the image from the camera shall be captured.
		///
		/// If a video signal is transmitted to the capture device in an interlaced format, the device
		/// can either capture each individual frame, or merge two frames together into a complete image.
		///
		/// This property will be invisible when the camera description selected by the property
		/// <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::type</b> does define it property 
		/// <b>mvIMPACT::acquire::CameraDescription::interlacedType</b> to be <b>mvIMPACT::acquire::TInterlacedType::itNone</b>
		/// as the decision whether an interlaced image shall be reconstructed from frames or left 
		/// as individual frame is redundant if the video source transmitts full frames only.
		///
		/// The visibility of a property can be checked by calling <b>mvIMPACT::acquire::Component::isVisible</b>
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TInterlacedMode</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyIInterlacedMode interlacedMode;
		/// \brief An enumerated integer property defining which frame(s) of an interlaced video signal 
		/// will be digitised or triggers the start of the acquisition.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAcquisitionField</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyIAcquisitionField acquisitionField;
		/// \brief An enumerated integer property defining the scan rate mode for this setting.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDeviceScanRateMode</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyIDeviceScanRateMode scanRateMode;
		/// \brief An integer property defining the current scan frequency of the capture device.
		///
		/// This property is only visible if the <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::scanRateMode</b>
		/// property is <b>NOT</b> in an auto mode.
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI scanRate_kHz;
		/// \brief An integer property defining the luminance value to be applied to the image data by the
		/// frame grabber in per cent.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI luminance_pc;
		/// \brief An integer property defining the saturation value to be applied to the image data by the
		/// frame grabber in per cent.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI saturation_pc;
		/// \brief An integer property defining the hue value to be applied to the image data by the
		/// frame grabber in per cent.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI hue_pc;
		/// \brief An integer property defining the contrast value to be applied to the image data by the
		/// frame grabber in per cent.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyI contrast_pc;
		/// \brief An enumerated integer property defining the way line counter information is handled by the 
		/// device.
		///
		/// This is interessting for line scan camera applications. More information can be found a the documentation
		/// of the enumeration <b>mvIMPACT::acquire::TLineCounter</b>.
		///
		/// \note
		/// This property will not be available for every frame grabber, so before using it, check
		/// if the property is available at all by calling <b>mvIMPACT::acquire::Component::isValid</b>. Accessing
		/// an invalid property will raise an exception!
		PropertyILineCounter lineCounter;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI							getType( void ) const { return type; }
		PropertyICameraAoiMode				getAoiMode( void ) const { return aoiMode; }
		PropertyF							getGain_dB( void ) const { return gain_dB; }
		PropertyI							getOffset_mV( void ) const { return offset_mV; }
		PropertyIScanClock					getScanClock( void ) const { return scanClock; }
		PropertyIDeviceTriggerMode			getTriggerMode( void ) const { return triggerMode; }
		PropertyI							getSoftwareTriggerPeriod_ms( void ) const { return softwareTriggerPeriod_ms; }
		PropertyICameraSerialPortBaudRate	getSerialPortBaudRate( void ) const { return serialPortBaudrate; }
		PropertyIInterlacedMode				getInterlacedMode( void ) const { return interlacedMode; }
		PropertyIAcquisitionField			getAcquisitionField( void ) const { return acquisitionField; }
		PropertyIDeviceScanRateMode			getScanRateMode( void ) const { return scanRateMode; }
		PropertyI							getScanRate_kHz( void ) const { return scanRate_kHz; }
		PropertyI							getLuminance_pc( void ) const { return luminance_pc; }
		PropertyI							getSaturation_pc( void ) const { return saturation_pc; }
		PropertyI							getHue_pc( void ) const { return hue_pc; }
		PropertyI							getContrast_pc( void ) const { return contrast_pc; }
		PropertyILineCounter				getLineCounter( void ) const { return lineCounter; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A class describing how a camera is connected to a frame grabber device.
	///
	/// With an instance of this class the user can define on which input channels the
	/// camera used for this setting is connected to the frame grabber and how the camera
	/// transmits it's image data.
	class ConnectorFrameGrabber : public ComponentCollection
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::ConnectorFrameGrabber</b> object
		explicit ConnectorFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
										Device* pDev,
										/// The name of the driver internal setting to access with this instance.
										/// A list of valid setting name can be obtained by a call to
										/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
										/// settings can be created with the function
										/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
										const std::string& settingName = "Base" ) : ComponentCollection(pDev)
		{
			DeviceComponentLocator locator(pDev, dltSetting, settingName.c_str());
			locator.bindSearchBase( locator.searchbase_id(), "Connector" );
			m_hRoot = locator.searchbase_id();
			locator.bindComponent( cameraOutputUsed, "CameraOutputUsed" );
			locator.bindComponent( videoChannel, "VideoChannel" );
			locator.bindComponent( pinDescription, "PinDescription" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the video output of the camera used for the
		/// connection to the frame grabber.
		///
		/// \note
		/// Not every frame grabber will support every possible value defined in the enumeration
		/// <b>mvIMPACT::acquire::TCameraOutput</b>. For example a CameraLink&reg; frame grabber
		/// will not offer to use a SVideo connector. Therefore the translation dictionary of this 
		/// property should be used to find out, which connector types are available.
		PropertyICameraOutput cameraOutputUsed;
		/// \brief An integer property containing the video channel the camera belonging to the current
		/// setting is connected to.
		///
		/// The maximum possible video channel might change when the property 
		/// <b>mvIMPACT::acquire::ConnectorFrameGrabber::cameraOutputUsed</b> is modified as the different
		/// ways to transmit a video signal require more or less video input channels. While e.g. a composite
		/// video signal can be transmitted via a single wire, an RGB signal requires either 3 or 4 wires 
		/// (depending on whether the sync. signal is transmitted on a separate cable or not).
		/// 
		/// The first channel will always have the number 0. The limits (max/min values) can be queried
		/// by calling the function <b>mvIMPACT::acquire::PropertyI::read</b> with either 
		/// <b>mvIMPACT::acquire::TPropertyLimits::plMaxValue</b> or <b>mvIMPACT::acquire::TPropertyLimits::plMinValue</b>.
		/// as \a index.
		PropertyI videoChannel;
		/// \brief A string property <b>(read-only)</b> containing a description for the video channel 
		/// currently selected by the property <b>mvIMPACT::acquire::ConnectorFrameGrabber::videoChannel</b>
		///
		/// The description string contains information about the connector pins belonging to this video
		/// input of the frame grabber as well as the corresponding name of this video input.
		PropertyS pinDescription;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyICameraOutput	getCameraOutputUsed( void ) const { return cameraOutputUsed; }
		PropertyI				getVideoChannel( void ) const { return videoChannel; }
		PropertyS				getPinDescription( void ) const { return pinDescription; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A base class to describe a camera.
	///
	/// A camera description object provides an abstract way to prepare the capture 
	/// device (e.g. a frame grabber) for the connected imaging device (e.g. a camera).
	/// 
	/// By selecting one of the available camera descriptions the underlying hardware 
	/// will use the information provided in the camera description to prepare the
	/// image capture. Therefore it is crucial to select a camera description
	/// that matches the connected video signal as close as possible. If no description
	/// for the camera or imaging device connected is available a new description
	/// should be generated from one of the existing ones. This can be achieved by calling
	/// the function <b>mvIMPACT::acquire::CameraDescriptionBase::copyDescription</b>. A new
	/// camera description with the name that is passed to the function will be created.
	///
	/// \note
	/// The name must be unique. There can't be two descriptions with the same name
	/// belonging to the same generic class (i.e. \a 'Standard' or \a 'CameraLink'&reg;). However
	/// it's perfectly legal to have a camera description for standard analogue video signals
	/// and one for e.g. CameraLink&reg; signals with the same name.
	///
	/// This new description will be an exact copy of the one the copy function has been 
	/// executed for. After creation this description can be selected e.g. by setting the
	/// property <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::type</b> to the name of the
	/// new description.
	///
	/// \note
	/// Please note that the name passed to the property <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::type</b>
	/// does <b>NOT</b> exactly correspond to the name assigned to the new camera description.
	/// It is a combination of the class the camera is belonging to (e.g. \a 'Standard') and the actual name.
	/// So to select a camera description the name must be build from teh return value of a call to
	/// <b>mvIMPACT::acquire::CameraDescriptionBase::getClassName</b>, an underscore ('_') and the
	/// actual name of the description: &lt;class name&gt;_&lt;desc. name&gt;
	///
	/// Example: For a standard description with the name \a 'MyCam' the full name would be \a 'Standard_MyCam'.
	/// 
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html 
	///
	/// <b>EXAMPLE:</b>
	///
	///\code
	/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
	/// #include <iostream>
	///
	/// using namespace std;
	///
	/// //-----------------------------------------------------------------------------
	/// int main(int argc, char* argv[])
	/// //-----------------------------------------------------------------------------
	/// {
	///   mvIMPACT::acquire::DeviceManager devMgr;
	///   mvIMPACT::acquire::Device* pDev = devMgr[0];
	///   if( !pDev )
	///   {
	///     cout << "No device found" << endl;
	///     return 0;
	///   }
	/// 
	///   try
	///   {
	///     // the next line will raise an exception if this device does not
	///     // support camera descriptions (e.g. if it is a USB camera rather then a frame grabber)
	///     mvIMPACT::acquire::CameraDescriptionManager cdm(pDev);
	///     mvIMPACT::acquire::CameraDescriptionStandard* pCam = cdm.cameraDescriptionStandard( "Generic" );
	///     pCam->copyDescription( "MyCam" );
	///     // Get access to the newly created description
	///     mvIMPACT::acquire::CameraDescriptionStandard* pMyCam = cdm.cameraDescriptionStandard( "MyCam" );
	///     // Modify something
	///     pMyCam->videoStandard.write( vsRS170 );
	///     pMyCam->scanStandard.write( ssITU601 );
	///     // now save the description to make it available in all future sessions
	///     pMyCam->exportDescription();
	///     // select the newly created description
	///     mvIMPACT::acquire::CameraSettingsFrameGrabber cs(pDev);
	///     // the name for this property is always a combination of the class the camera
	///     // description is belonging to and the actual name:
	///     cs.type.writeS( pMyCam->getClassName() + "_" + pMyCam->name.read() );
	///   }
	///   catch( ImpactAcquireException& e )
	///   {
	///     cout << "An exception occurred: " << e.errString() << endl;
	///   }
	///   return 0;
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	class CameraDescriptionBase : public ComponentCollection
	//-----------------------------------------------------------------------------
	{
		HDRV m_hDrv;
	protected:
		explicit CameraDescriptionBase( HDRV hDrv, HLIST hList ) : ComponentCollection(hList), m_hDrv(hDrv)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( name, "Name" );
			locator.bindComponent( videoOutput, "VideoOutput" );
			locator.bindComponent( interlacedType, "InterlacedType" );
			locator.bindSearchBase( locator.searchbase_id(), "ActiveVideoAoi" );
			locator.bindComponent( aoiHeight, "H" );
			locator.bindComponent( aoiStartX, "X" );
			locator.bindComponent( aoiStartY, "Y" );
			locator.bindComponent( aoiWidth, "W" );
		}
	public:
		/// \brief Returns the class this description is belonging to.
		/// \return The class this description is belonging to.
		std::string getClassName( void ) const { return ComponentList(m_hRoot).contentDescriptor(); }
		PYTHON_ONLY(%immutable;)
		/// \brief A string property containing the name of this camera description list.
		PropertyS name;
		/// \brief An enumerated integer property defining how the camera transmits image data.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraInterlacedType</b>.
		PropertyICameraInterlacedType interlacedType;
		/// \brief An enumerated integer property defining the type of video outputs this camera offers
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraOutput</b>.
		PropertyICameraOutput videoOutput;
		/// \brief An integer property defining the number of active lines to capture from the camera.
		PropertyI aoiHeight;
		/// \brief An integer property defining the X-offset in pixels to the first active pixel to capture.
		PropertyI aoiStartX;
		/// \brief An integer property defining the Y-offset.
		PropertyI aoiStartY;
		/// \brief An integer property defining the number of active pixels to capture per line.
		PropertyI aoiWidth;
		PYTHON_ONLY(%mutable;)
		/// \brief Creates a new camera description list as a copy of the current one.
		///
		/// This function can be used to create a new camera description list. It will create
		/// a deep copy of the list referenced by \a hCameraDescList and will append it
		/// to the list of camera descriptions.
		///
		/// \note
		/// This will <b>NOT</b> store the new description permanently. After the driver has been 
		/// closed, this data will be lost. To store the new list in a way, that it will be available
		/// the next time the driver/device is opened again <b>mvIMPACT::acquire::CameraDescriptionBase::exportDescription</b> must
		/// be called with the handle of the newly created description after this function.
		/// \sa
		/// <b>mvIMPACT::acquire::CameraDescriptionBase::exportDescription,<br>
		///    mvIMPACT::acquire::CameraDescriptionBase::importDescription</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int copyDescription(	/// The name for the newly created camera description. This name
								/// <b>MUST NOT</b> match a description already existing.
								const std::string& newName ) const { return DMR_CopyCameraDescription( m_hDrv, m_hRoot, newName.c_str() ); }
		/// \brief Stores the current camera description on disc.
		///
		/// This function can be used to store the current settings of a camera description
		/// permanently so that the next time the driver is initialised these settings are restored.
		///
		/// When exporting a camera description a file in XML format will be written to disc. Under 
		/// Windows&reg; camera descriptions will be stored under 
		/// <b>%ALLUSERS%\\Documents\\MATRIX VISION\\mvIMPACT acquire\\CameraFiles</b> while under
		/// other platforms these files will end up in the current working directory.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::CameraDescriptionBase::copyDescription,<br>
		///    mvIMPACT::acquire::CameraDescriptionBase::importDescription</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int exportDescription( void ) const { return DMR_ExportCameraDescription( m_hDrv, m_hRoot ); }
		/// \brief Updates a camera description with the data stored in a previous session or
		/// with the original default data.
		///
		/// When importing a camera description the device driver will try to retrieve the parameters
		/// needed from a XML file. Under Windows&reg; camera descriptions MUST be stored under 
		/// <b>%ALLUSERS%\\Documents\\MATRIX VISION\\mvIMPACT acquire\\CameraFiles</b> while under
		/// other platforms these files MUST be located in the current working directory. So to get
		/// access to a XML description file within the application, these file must be copied to
		/// this directory <b>BEFORE</b> the device is initialised. During the init process the
		/// device driver will process every file located under this location and will add them to
		/// the internal list of descriptions. Every camera located during this process and also descriptions
		/// created later on during the program operation can be selected via the property
		/// <b>mvIMPACT::acquire::CameraSettingsFrameGrabber::type</b>.
		///
		/// \note
		/// In order not to bloat the device driver with redundant data it's wise only to store the
		/// descripitions needed for the application to run under this location.
		///
		/// \note
		/// Only camera descripitions supported by the capture device will be added to the device
		/// drivers internal list and will therefore be accessible via the
		/// <b>mvIMPACT::acquire::CameraDescriptionManager</b>.
		///
		/// To restore the default values valid during the driver was initialised the function 
		/// <b>mvIMPACT::acquire::ComponentCollection::restoreDefault</b> can be used as well.
		///
		/// \sa
		/// <b>mvIMPACT::acquire::CameraDescriptionBase::exportDescription,<br>
		///    mvIMPACT::acquire::CameraDescriptionBase::copyDescription</b>
		/// \return
		/// - <b>mvIMPACT::acquire::TDMR_ERROR::DMR_NO_ERROR</b> if successful.
		/// - A negative error code of type <b>mvIMPACT::acquire::TDMR_ERROR</b> otherwise.
		int importDescription( void ) const { return DMR_ImportCameraDescription( m_hDrv, m_hRoot ); }
	#ifdef DOTNET_ONLY_CODE
		PropertyS						getName( void ) const { return name; }
		PropertyICameraOutput			getVideoOutput( void ) const { return videoOutput; }
		PropertyICameraInterlacedType	getInterlacedType( void ) const { return interlacedType; }
		PropertyI						getAoiHeight( void ) const { return aoiHeight; }
		PropertyI						getAoiStartX( void ) const { return aoiStartX; }
		PropertyI						getAoiStartY( void ) const { return aoiStartY; }
		PropertyI						getAoiWidth( void ) const { return aoiWidth; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};


	//-----------------------------------------------------------------------------
	/// \brief A base class to describe an arbitrary digital camera signal.
	///
	/// This class provides access to all settings specific for digital video signals.
	class CameraDescriptionDigitalBase : public CameraDescriptionBase
	//-----------------------------------------------------------------------------
	{
	protected:
		explicit CameraDescriptionDigitalBase( HDRV hDrv, HLIST hList ) : CameraDescriptionBase(hDrv, hList)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( bitsPerPixel, "BitsPerPixel" );
			locator.bindComponent( pixelsPerCycle, "PixelsPerCycle" );
			locator.bindComponent( format, "Format" );
			locator.bindComponent( bayerParity, "BayerParity" );
			locator.bindComponent( scanMode, "ScanMode" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property defining the number of bits per pixel currently transmitted by this camera.
		PropertyI bitsPerPixel;
		/// \brief An integer property defining the number of pixels per clock cycle transmitted by this camera.
		PropertyI pixelsPerCycle;
		/// \brief An enumerated integer property defining the data format the camera is sending image data.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraDataFormat</b>.
		PropertyICameraDataFormat format;
		/// \brief An enumerated integer property defining the start pixel for a camera delivering an unconverted
		/// bayer image.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBayerMosaicParity</b>.
		PropertyIBayerMosaicParity bayerParity;
		/// \brief An enumerated integer property providing information about the sensor of this camera.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraScanMode</b>.
		PropertyICameraScanMode scanMode;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI							getBitsPerPixel( void ) const { return bitsPerPixel; }
		PropertyI							getPixelsPerCycle( void ) const { return pixelsPerCycle; }
		PropertyICameraDataFormat			getFormat( void ) const { return format; }
		PropertyIBayerMosaicParity			getBayerParity( void ) const { return bayerParity; }
		PropertyICameraScanMode				getScanMode( void ) const { return scanMode; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A class to describe a CameraLink&reg; compliant camera.
	///
	/// This class provides access to all settings specific for CameraLink&reg; compliant cameras.
	class CameraDescriptionCameraLink : public CameraDescriptionDigitalBase
	//-----------------------------------------------------------------------------
	{
		friend class CameraDescriptionManager;
		explicit CameraDescriptionCameraLink( HDRV hDrv, HLIST hList ) : CameraDescriptionDigitalBase(hDrv, hList)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( dataValid, "DataValid" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the way this camera transmits the data valid (<b>DVAL</b>)
		/// signal.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraLinkDataValidMode</b>.
		PropertyICameraLinkDataValidMode dataValid;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyICameraLinkDataValidMode	getDataValid( void ) const { return dataValid; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A class to describe a non-standard digital video signal.
	///
	/// This class provides access to all settings specific for non-standard digital video signals.
	class CameraDescriptionDigital : public CameraDescriptionDigitalBase
	//-----------------------------------------------------------------------------
	{
		friend class CameraDescriptionManager;
		explicit CameraDescriptionDigital( HDRV hDrv, HLIST hList ) : CameraDescriptionDigitalBase(hDrv, hList)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( frameSync, "FrameSync" );
			locator.bindComponent( lineSync, "LineSync" );
			locator.bindComponent( pixelClk, "PixelClk" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the edge valid for the frame sync signal of this camera.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncEdge</b>.
		///
		/// \note
		/// Not every value defined by this enumeration will be supported by this property. Check which values
		/// are available by reading the properties translation dictionary with
		/// the functions <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		PropertyICameraExternalSyncEdge frameSync;
		/// \brief An enumerated integer property defining the edge valid for the line sync. of this camera.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncEdge</b>.
		///
		/// \note
		/// Not every value defined by this enumeration will be supported by this property. Check which values
		/// are available by reading the properties translation dictionary with
		/// the functions <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		PropertyICameraExternalSyncEdge lineSync;
		/// \brief An enumerated integer property defining the edge valid for the pixel clock of this camera.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncEdge</b>.
		///
		/// \note
		/// Not every value defined by this enumeration will be supported by this property. Check which values
		/// are available by reading the properties translation dictionary with
		/// the functions <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictString</b> and
		/// <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDictValue</b>
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html
		/// C++ offers the more efficient function <b>mvIMPACT::acquire::PropertyICameraExternalSyncEdge::getTranslationDict</b>
		/// in addition to the functions mentioned above.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly
		PropertyICameraExternalSyncEdge pixelClk;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyICameraExternalSyncEdge	getFrameSync( void ) const { return frameSync; }
		PropertyICameraExternalSyncEdge	getLineSync( void ) const { return lineSync; }
		PropertyICameraExternalSyncEdge	getPixelClk( void ) const { return pixelClk; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief An internal base class to describe standard analogue video cameras.
	///
	/// Instances of this class can't be constructed directly. Use one of the derived types.
	class CameraDescriptionStandardBase : public CameraDescriptionBase
	//-----------------------------------------------------------------------------
	{
	protected:
		explicit CameraDescriptionStandardBase( HDRV hDrv, HLIST hList ) : CameraDescriptionBase(hDrv, hList)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( videoStandard, "VideoStandard" );
			locator.bindComponent( scanStandard, "ScanStandard" );
			locator.bindComponent( scanRate_kHz, "ScanRate_kHz" );
			locator.bindComponent( startField, "StartField" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property for defining the video standard this camera
		/// is compliant with.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TVideoStandard</b>.
		PropertyIVideoStandard videoStandard;
		/// \brief An enumerated integer property defining the scan standard this camera is compliant with.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TScanStandard</b>.
		PropertyIScanStandard scanStandard;
		/// \brief An integer property containing the scan rate in kHz needed to driver the AD converter 
		/// of the capture device with to convert the video signal properly.
		PropertyI scanRate_kHz;
		/// \brief An enumerated integer property containing information about the first field transmitted
		/// by a camera.
		///
		/// A camera might transmit either the odd or the even field of an interlaced video signal first.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TAcquisitionField</b>.
		PropertyIAcquisitionField startField;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIVideoStandard		getVideoStandard( void ) const { return videoStandard; }
		PropertyIScanStandard		getScanStandard( void ) const { return scanStandard; }
		PropertyI					getScanRate_kHz( void ) const { return scanRate_kHz; }
		PropertyIAcquisitionField	getStartField( void ) const { return startField; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief A class describing analogue standard compliant video cameras.
	class CameraDescriptionStandard : public CameraDescriptionStandardBase
	//-----------------------------------------------------------------------------
	{
		friend class CameraDescriptionManager;
		explicit CameraDescriptionStandard( HDRV hDrv, HLIST hList ) : CameraDescriptionStandardBase(hDrv, hList) {}
	};

	//-----------------------------------------------------------------------------
	/// \brief A class describing non-standard video cameras
	///
	/// This class can be used to describe a non-standard analogue video camera. A camera
	/// considered as non-standard when it is not compliant with one of the defined 
	/// video standards like e.g. CCIR.
	class CameraDescriptionNonStandard : public CameraDescriptionStandardBase
	//-----------------------------------------------------------------------------
	{
		friend class CameraDescriptionManager;
		explicit CameraDescriptionNonStandard( HDRV hDrv, HLIST hList ) : CameraDescriptionStandardBase(hDrv, hList)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( lineFrequency_Hz, "LineFrequency_Hz" );
			locator.bindComponent( VDOutput, "VDOutput" );
			locator.bindComponent( HDOutput, "HDOutput" );
			locator.bindComponent( syncOutput, "SyncOutput" );
			locator.bindComponent( pixelClockOutput, "PixelClockOutput" );
			locator.bindComponent( fieldGateMode, "FieldGateMode" );
			locator.bindComponent( fieldGateStart, "FieldGateStart" );
			locator.bindComponent( fieldGateWidth, "FieldGateWidth" );
			locator.bindComponent( clampMode, "ClampMode" );
			locator.bindComponent( clampStart_us, "ClampStart_us" );
		}
	public:
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property containing the line frequency of this camera in Hertz.
		PropertyI lineFrequency_Hz;
		/// \brief An enumerated integer property defining whether the vertical sync. information is part of the 
		/// video signal or transmitted via a separate wire.
		/// 
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncOutput</b>.
		PropertyICameraExternalSyncOutput VDOutput;
		/// \brief An enumerated integer property defining whether the horizontal sync. information is part of the 
		/// video signal or transmitted via a separate wire.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncOutput</b>.
		PropertyICameraExternalSyncOutput HDOutput;
		/// \brief An enumerated integer property for RGB cameras containing information where the sync. information is transmitted.
		///
		/// This can either be within one of the three color components or on a separate wire.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncOutput</b>.
		PropertyICameraExternalSyncOutput syncOutput;
		/// \brief An enumerated integer property containing information whether the pixel clock is part of the video signal or
		/// not.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TCameraExternalSyncOutput</b>.
		PropertyICameraExternalSyncOutput pixelClockOutput;
		/// \brief An enumerated integer property defining the clamp mode for this camera description.
		///
		/// This defines how the field detection(ODD/EVEN) is done.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TFieldGateMode</b>.
		PropertyIFieldGateMode fieldGateMode;
		/// \brief An integer property defining the start position (in pixel clocks) of the field gate detection
		/// area.
		/// 
		/// This will only need modification in very rare cases.
		PropertyI fieldGateStart;
		/// \brief An integer property defining the width (in pixel clocks) of the field gate detection
		/// area.
		/// 
		/// This will only need modification in very rare cases.
		PropertyI fieldGateWidth;
		/// \brief An enumerated integer property defining the clamp mode for this camera description.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TClampMode</b>.
		PropertyIClampMode clampMode;
		/// \brief The clamp start position defines where in each line of the video signal the frame grabber
		/// assumes the black level position.
		///
		/// This will only need modification in very rare cases.
		PropertyI clampStart_us;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI							getLineFrequency_Hz( void ) const { return lineFrequency_Hz; }
		PropertyICameraExternalSyncOutput	getVDOutput( void ) const { return VDOutput; }
		PropertyICameraExternalSyncOutput	getHDOutput( void ) const { return HDOutput; }
		PropertyICameraExternalSyncOutput	getSyncOutput( void ) const { return syncOutput; }
		PropertyICameraExternalSyncOutput	getPixelClockOutput( void ) const { return pixelClockOutput; }
		PropertyIFieldGateMode				getFieldGateMode( void ) const { return fieldGateMode; }
		PropertyI							getFieldGateStart( void ) const { return fieldGateStart; }
		PropertyI							getFieldGateWidth( void ) const { return fieldGateWidth; }
		PropertyIClampMode					getClampMode( void ) const { return clampMode; }
		PropertyI							getClampStart_us( void ) const { return clampStart_us; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};

	//-----------------------------------------------------------------------------
	/// \brief Grants access to camera description objects.
	///
	/// This class provides access to the various camera description objects. Each
	/// device recognizes a different set of camera descriptions. E.g. a digital
	/// frame grabber will not be able to work with analogue cameras. Each camera description
	/// class will be derived from <b>mvIMPACT::acquire::CameraDescriptionBase</b>.
	///
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
	///\endxmlonly
	///\htmlinclude code_fragment_start_cpp.html
	///
	/// <b>EXAMPLE</b>(lists all available camera descriptions for a certain device):
	///\code
	/// #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
	/// #include <iostream>
	///
	/// using namespace std;
	/// using namespace mvIMPACT::acquire;
	///
	/// //-----------------------------------------------------------------------------
	/// int main(int argc, char* argv[])
	/// //-----------------------------------------------------------------------------
	/// {
	///   DeviceManager devMgr;
	///   Device* pDev = devMgr[0];
	///   if( !pDev )
	///   {
	///     cout << "No device found" << endl;
	///     return 0;
	///   }
	///
	///   CameraDescriptionManager camMgr(pDev);
	///   unsigned int camCnt = camMgr.getCLCameraDescriptionCount();
	///   cout << "Available CL descriptions: " << camCnt << endl;
	///   for( unsigned int a=0; a<camCnt; a++ )
	///   {
	///     cout << "  " << camMgr.cameraDescriptionCameraLink(a)->name.read() << endl;
	///   }
	///   camCnt = camMgr.getStandardCameraDescriptionCount();
	///   cout << "Available Std descriptions: " << camCnt << endl;
	///   for( unsigned int b=0; b<camCnt; b++ )
	///   {
	///     cout << "  " << camMgr.cameraDescriptionStandard(b)->name.read() << endl;
	///   }
	///   camCnt = camMgr.getNonStandardCameraDescriptionCount();
	///   cout << "Available NonStd descriptions: " << camCnt << endl;
	///   for( unsigned int c=0; c<camCnt; c++ )
	///   {
	///     cout << "  " << camMgr.cameraDescriptionNonStandard(c)->name.read() << endl;
	///   }
	///   return 0;
	/// }
	///\endcode
	///\htmlinclude code_fragment_end.html
	///\xmlonly
	/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
	///\endxmlonly
	///
	/// \note
	/// This class will only be available for frame grabber devices. For other devices
	/// the class constructor will raise an exception.
	class CameraDescriptionManager
	//-----------------------------------------------------------------------------
	{
		typedef std::pair<std::string, unsigned int> StringUIntPair;
		typedef std::map<std::string, unsigned int> StringUIntMap;
		#ifndef DOXYGEN_SHOULD_SKIP_THIS
		//-----------------------------------------------------------------------------
		struct ReferenceCountedData
		//-----------------------------------------------------------------------------
		{
			HDRV												m_hDrv;
			HLIST												m_hListCameraDescriptions;
			mutable unsigned int								m_lastListSize;
			mutable std::vector<CameraDescriptionStandard*>		m_vStdDescriptions;
			mutable std::vector<CameraDescriptionNonStandard*>	m_vNonStdDescriptions;
			mutable std::vector<CameraDescriptionCameraLink*>	m_vCLDescriptions;
			mutable std::vector<CameraDescriptionDigital*>		m_vDigitalDescriptions;
			mutable StringUIntMap								m_mNameToDescription;
			unsigned int										m_refCnt;
			ReferenceCountedData( HDRV hDrv, HLIST hList ) : m_hDrv(hDrv), m_hListCameraDescriptions(hList), m_refCnt(1) {}
			~ReferenceCountedData()
			{
				std::vector<CameraDescriptionStandard*>::size_type vStdSize = m_vStdDescriptions.size();
				for( std::vector<CameraDescriptionStandard*>::size_type a=0; a<vStdSize; a++ )
				{
					delete m_vStdDescriptions[a];
				}
				std::vector<CameraDescriptionStandard*>::size_type vNonStdSize = m_vNonStdDescriptions.size();
				for( std::vector<CameraDescriptionStandard*>::size_type b=0; b<vNonStdSize; b++ )
				{
					delete m_vNonStdDescriptions[b];
				}
				std::vector<CameraDescriptionStandard*>::size_type vCLSize = m_vCLDescriptions.size();
				for( std::vector<CameraDescriptionStandard*>::size_type c=0; c<vCLSize; c++ )
				{
					delete m_vCLDescriptions[c];
				}
				std::vector<CameraDescriptionStandard*>::size_type vDigSize = m_vDigitalDescriptions.size();
				for( std::vector<CameraDescriptionStandard*>::size_type d=0; d<vDigSize; d++ )
				{
					delete m_vDigitalDescriptions[d];
				}
			}
		} *m_pRefData;
		#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
		//-----------------------------------------------------------------------------
		void dealloc( void )
		//-----------------------------------------------------------------------------
		{
			--(m_pRefData->m_refCnt);
			if( m_pRefData->m_refCnt == 0 )
			{
				delete m_pRefData;
			}
		}
		//-----------------------------------------------------------------------------	
		void update( void ) const
		//-----------------------------------------------------------------------------
		{
			ComponentList camDescList(m_pRefData->m_hListCameraDescriptions);
			unsigned int curSize = camDescList.size();
			if( m_pRefData->m_lastListSize != curSize )
			{
				// new cameras at runtime can only appear at the end of the list
				ComponentIterator it(m_pRefData->m_hListCameraDescriptions);
				it = it.firstChild();
				while( it.isValid() )
				{
					ComponentList list(it);
					if( list.contentDescriptor() == "CameraLink" )
					{
						m_pRefData->m_vCLDescriptions.push_back( new CameraDescriptionCameraLink(m_pRefData->m_hDrv, list) );
						m_pRefData->m_mNameToDescription.insert( StringUIntPair( list.name(), static_cast<unsigned int>(m_pRefData->m_vCLDescriptions.size()-1) ) );
					}
					else if( list.contentDescriptor() == "Digital" )
					{
						m_pRefData->m_vDigitalDescriptions.push_back( new CameraDescriptionDigital(m_pRefData->m_hDrv, list) );
						m_pRefData->m_mNameToDescription.insert( StringUIntPair( list.name(), static_cast<unsigned int>(m_pRefData->m_vDigitalDescriptions.size()-1) ) );
					}
					else if( list.contentDescriptor() == "Standard" )
					{
						m_pRefData->m_vStdDescriptions.push_back( new CameraDescriptionStandard(m_pRefData->m_hDrv, list) );
						m_pRefData->m_mNameToDescription.insert( StringUIntPair( list.name(), static_cast<unsigned int>(m_pRefData->m_vStdDescriptions.size()-1) ) );
					}
					else if( list.contentDescriptor() == "NonStandard" )
					{
						m_pRefData->m_vNonStdDescriptions.push_back( new CameraDescriptionNonStandard(m_pRefData->m_hDrv, list) );
						m_pRefData->m_mNameToDescription.insert( StringUIntPair( list.name(), static_cast<unsigned int>(m_pRefData->m_vNonStdDescriptions.size()-1) ) );
					}
					else
					{
						; // NOT recognized....
					}
					++it;
				}
				m_pRefData->m_lastListSize = curSize;
			}
		}
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::CameraDescriptionManager</b> object.
		explicit CameraDescriptionManager(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::>DeviceManager</b> object.
											Device* pDev )
		{
			if( !pDev->isOpen() )
			{
				pDev->open();
			}

			TDMR_ERROR result;
			HLIST hList;
			if( ( result = DMR_FindList( pDev->hDrv(), 0, dmltCameraDescriptions, 0, &hList ) ) != DMR_NO_ERROR )
			{
				ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result, INVALID_ID, "Couldn't find camera description list (is this a frame grabber?)" );
			}
			m_pRefData = new ReferenceCountedData(pDev->hDrv(), hList);
		}
		/// \brief Constructs a new <b>mvIMPACT::acquire::CameraDescriptionManager</b> from
		/// and exisiting one.
		explicit CameraDescriptionManager(	/// A constant reference to the <b>mvIMPACT::acquire::CameraDescriptionManager</b> object, this object shall be created from
											const CameraDescriptionManager& src ) : m_pRefData(src.m_pRefData)
		{
			++(m_pRefData->m_refCnt);
		}
		/// \brief Class destructor
		~CameraDescriptionManager()
		{
			dealloc();
		}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::CameraDescriptionManager</b> objects
	CameraDescriptionManager& operator=( const CameraDescriptionManager& rhs )
	{
		if( this != &rhs )
		{
			dealloc();
			m_pRefData = rhs.m_pRefData;
			// inc. the NEW reference count
			++m_pRefData->m_refCnt;
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
		/// \brief Returns the number of CameraLink&reg; camera descriptions currently available for the device
		/// that constructed this instance of the class.
		unsigned int getCLCameraDescriptionCount( void ) const 
		{ 
			update();
			return static_cast<unsigned int>(m_pRefData->m_vCLDescriptions.size());
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionCameraLink</b> object specifying the camera
		/// description found at the given index in the camera description managers internal list.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html	
		/// If the index is either equal or higher then the number of CameraLink&reg; camera descriptions<br>
		/// detected for this device a STL out_of_range exception will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly		
		CameraDescriptionCameraLink* cameraDescriptionCameraLink(	/// \brief The index of the camera description to return
																	unsigned int index ) const
		{
			update();
			return m_pRefData->m_vCLDescriptions.at( index );
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionCameraLink</b> object specifying the camera
		/// description with the given name in the camera description managers internal list.
		///
		/// \return
		/// - a pointer to a <b>mvIMPACT::acquire::CameraDescriptionCameraLink</b> object specifying the camera
		/// description with the given name in the camera description managers internal list if a camera
		/// description with \a name is available.
		/// - an invalid pointer or reference otherwise.
		CameraDescriptionCameraLink* cameraDescriptionCameraLink( const std::string& name ) const
		{
			update();
			StringUIntMap::const_iterator it = m_pRefData->m_mNameToDescription.find( name );
			return ( ( it != m_pRefData->m_mNameToDescription.end() ) ? m_pRefData->m_vCLDescriptions.at( it->second ) : 0 );
		}
		/// \brief Returns the number of non-standard digital camera descriptions currently available for the device
		/// that constructed this instance of the class.
		unsigned int getDigitalCameraDescriptionCount( void ) const 
		{ 
			update();
			return static_cast<unsigned int>(m_pRefData->m_vDigitalDescriptions.size());
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionDigital</b> object specifying the camera
		/// description found at the given index in the camera description managers internal list.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html	
		/// If the index is either equal or higher then the number of non-standard digital camera descriptions<br>
		/// detected for this device a STL out_of_range exception will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly		
		CameraDescriptionDigital* cameraDescriptionDigital(	/// \brief The index of the camera description to return
															unsigned int index ) const
		{
			update();
			return m_pRefData->m_vDigitalDescriptions.at( index );
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionDigital</b> object specifying the camera
		/// description with the given name in the camera description managers internal list.
		///
		/// \return
		/// - a pointer to a <b>mvIMPACT::acquire::CameraDescriptionDigital</b> object specifying the camera
		/// description with the given name in the camera description managers internal list if a camera
		/// description with \a name is available.
		/// - an invalid pointer or reference otherwise.
		CameraDescriptionDigital* cameraDescriptionDigital( const std::string& name ) const
		{
			update();
			StringUIntMap::const_iterator it = m_pRefData->m_mNameToDescription.find( name );
			return ( ( it != m_pRefData->m_mNameToDescription.end() ) ? m_pRefData->m_vDigitalDescriptions.at( it->second ) : 0 );
		}
		/// \brief Returns the number of standard camera descriptions currently available for the device
		/// that constructed this instance of the class.
		unsigned int getStandardCameraDescriptionCount( void ) const 
		{ 
			update();
			return static_cast<unsigned int>(m_pRefData->m_vStdDescriptions.size());
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionStandard</b> object specifying the camera
		/// description found at the given index in the camera description managers internal list.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html	
		/// If the index is either equal or higher then the number of standard camera descriptions<br>
		/// detected for this device a STL out_of_range exception will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly		
		CameraDescriptionStandard* cameraDescriptionStandard(	/// \brief The index of the camera description to return
																unsigned int index ) const
		{
			update();
			return m_pRefData->m_vStdDescriptions.at( index );
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionStandard</b> object specifying the camera
		/// description with the given name in the camera description managers internal list.
		///
		/// \return
		/// - a pointer to a <b>mvIMPACT::acquire::CameraDescriptionStandard</b> object specifying the camera
		/// description with the given name in the camera description managers internal list if a camera
		/// description with \a name is available.
		/// - an invalid pointer or reference otherwise.
		CameraDescriptionStandard* cameraDescriptionStandard( const std::string& name ) const
		{
			update();
			StringUIntMap::const_iterator it = m_pRefData->m_mNameToDescription.find( name );
			return ( ( it != m_pRefData->m_mNameToDescription.end() ) ? m_pRefData->m_vStdDescriptions.at( it->second ) : 0 );
		}
		/// \brief Returns the number of non-standard camera descriptions currently available for the device
		/// that constructed this instance of the class.
		unsigned int getNonStandardCameraDescriptionCount( void ) const 
		{ 
			update();
			return static_cast<unsigned int>(m_pRefData->m_vNonStdDescriptions.size());
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionNonStandard</b> object specifying the camera
		/// description found at the given index in the camera description managers internal list.
		///
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_start_cpp.html"/></mvWrapperDoc>
		///\endxmlonly
		///\htmlinclude code_fragment_start_cpp.html	
		/// If the index is either equal or higher then the number of non-standard camera descriptions<br>
		/// detected for this device a STL out_of_range exception will be thrown.
		///\htmlinclude code_fragment_end.html
		///\xmlonly
		/// <mvWrapperDoc><htmlinclude ref="code_fragment_end.html"/></mvWrapperDoc>
		///\endxmlonly		
		CameraDescriptionNonStandard* cameraDescriptionNonStandard(	/// \brief The index of the camera description to return
																	unsigned int index ) const
		{
			update();
			return m_pRefData->m_vNonStdDescriptions.at( index );
		}
		/// \brief Returns a pointer to a <b>mvIMPACT::acquire::CameraDescriptionNonStandard</b> object specifying the camera
		/// description with the given name in the camera description managers internal list.
		///
		/// \return
		/// - a pointer to a <b>mvIMPACT::acquire::CameraDescriptionNonStandard</b> object specifying the camera
		/// description with the given name in the camera description managers internal list if a camera
		/// description with \a name is available.
		/// - an invalid pointer or reference otherwise.
		CameraDescriptionNonStandard* cameraDescriptionNonStandard( const std::string& name ) const
		{
			update();
			StringUIntMap::const_iterator it = m_pRefData->m_mNameToDescription.find( name );
			return ( ( it != m_pRefData->m_mNameToDescription.end() ) ? m_pRefData->m_vNonStdDescriptions.at( it->second ) : 0 );
		}
	};
#endif // #ifndef #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

//-----------------------------------------------------------------------------
/// \brief Properties to define the result images format.
///
/// This class provides properties allowing the user to define how the resulting
/// image should be created. Things like the width and height of the captured image
/// can be defined here for example.
class ImageDestination : public ComponentCollection
//-----------------------------------------------------------------------------
{
public:
	/// brief Constructs a new <b>mvIMPACT::acquire::ImageDestination</b> object.
	explicit ImageDestination(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev,
								/// The name of the driver internal setting to access with this instance.
								/// A list of valid setting name can be obtained by a call to
								/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
								/// settings can be created with the function
								/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
								const std::string& settingName = "Base" ) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltSetting, settingName);
		locator.bindSearchBase( locator.searchbase_id(), "ImageDestination" );
		m_hRoot = locator.searchbase_id();
		locator.bindComponent( pixelFormat, "PixelFormat" );
		locator.bindComponent( scalerMode, "ScalerMode" );
		locator.bindComponent( imageWidth, "ImageWidth" );
		locator.bindComponent( imageHeight, "ImageHeight" );
	}
	PYTHON_ONLY(%immutable;)
	/// \brief An enumerated integer property defining the pixel format of the resulting image.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TImageDestinationPixelFormat</b>.
	PropertyIImageDestinationPixelFormat pixelFormat;
	/// \brief An integer property defining whether the image is scaled or not.
	///
	/// \note
	/// This feature is currently not implemented! Modifying or reading this property will have
	/// <b>NO</b> effect.
	PropertyI scalerMode;
	/// \brief An integer property defining the width of the resulting image.
	///
	/// \note
	/// This feature is currently not implemented! Modifying or reading this property will have
	/// <b>NO</b> effect.
	PropertyI imageWidth;
	/// \brief An integer property defining the height of the resulting image.
	///
	/// \note
	/// This feature is currently not implemented! Modifying or reading this property will have
	/// <b>NO</b> effect.
	PropertyI imageHeight;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyIImageDestinationPixelFormat	getPixelFormat( void ) const { return pixelFormat; }
	PropertyI								getScalerMode( void ) const { return scalerMode; }
	PropertyI								getImageWidth( void ) const { return imageWidth; }
	PropertyI								getImageHeight( void ) const { return imageHeight; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief Properties for adjusting the colors during a Bayer conversion.
///
/// This class provides properties to adjust the parameters needed for a
/// Bayer conversion.
///
/// \note
/// Objects of these class can't be constructed directly. It's parameters can
/// be accessed via an instance of a class derived from <b>mvIMPACT::acquire::ImageProcessingBase</b>.
class WhiteBalanceSettings
//-----------------------------------------------------------------------------
{
	// only ImageProcessingBase objects can create these objects, as these objects are
	// fixed parts of that class.
	friend class	ImageProcessingBase;
	explicit		WhiteBalanceSettings( HOBJ hObj )
	{
		ComponentLocator locator( hObj );
		locator.bindComponent( totalGain, "TotalGain" );
		locator.bindComponent( redGain, "RedGain" );
		locator.bindComponent( blueGain, "GreenGain" );
		locator.bindComponent( greenGain, "BlueGain" );
		locator.bindComponent( WBresult, "WBResult" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief An integer property defining the overall gain.
	PropertyI totalGain;
	/// \brief An integer property defining the gain for the red channel.
	PropertyI redGain;
	/// \brief An integer property defining the gain for the green channel.
	PropertyI greenGain;
	/// \brief An integer property defining the gain for the blue channel.
	PropertyI blueGain;
	/// \brief An integer property <b>(read-only)</b> containing the result of the last
	/// white balance calibration.
	///
	/// After the <b>mvIMPACT::acquire::Device</b> has been initialised, the value of this property will be
	/// <b>mvIMPACT::acquire::TBayerWhiteBalanceResult::bwbrUnknown</b>.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBayerWhiteBalanceResult</b>.
	PropertyIBayerWhiteBalanceResult	WBresult;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI							getTotalGain( void ) const { return totalGain; }
	PropertyI							getRedGain( void ) const { return redGain; }
	PropertyI							getGreenGain( void ) const { return greenGain; }
	PropertyI							getBlueGain( void ) const { return blueGain; }
	PropertyIBayerWhiteBalanceResult	getWBresult( void ) const { return WBresult; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief Base class for image processing related properties.
///
/// This class provides access to properties, which define how the image shall
/// be processed after it has been captured but before it will be handed back to
/// the user.
class ImageProcessingBase : public ComponentCollection
//-----------------------------------------------------------------------------
{
	typedef std::vector<WhiteBalanceSettings*> WBSettingVector;
	#ifndef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	struct ReferenceCountedData
	//-----------------------------------------------------------------------------
	{
		HDRV			m_hDrv;
		HLIST			m_hSetting;
		WBSettingVector	m_WBUserSettings;
		unsigned int	m_refCnt;
		ReferenceCountedData( HDRV hDrv, HLIST hSetting ) : m_hDrv(hDrv), m_hSetting(hSetting), m_refCnt(1) {}
		~ReferenceCountedData()
		{
			WBSettingVector::size_type vSize = m_WBUserSettings.size();
			for( WBSettingVector::size_type i=0; i<vSize; i++ )
			{
				delete m_WBUserSettings[i];
			}			
		}
	} *m_pRefData;
	#endif // #ifdef DOXYGEN_SHOULD_SKIP_THIS
	//-----------------------------------------------------------------------------
	void bindPublicProperties( void )
	//-----------------------------------------------------------------------------
	{
		ComponentLocator locator(m_hRoot);
		locator.bindComponent( colorProcessing, "ColorProcessing" );
		locator.bindComponent( whiteBalance, "WhiteBalance" );
		locator.bindComponent( whiteBalanceCalibration, "WhiteBalanceCalibration" );
		locator.bindComponent( filter, "Filter" );
		locator.bindComponent( mirrorMode, "MirrorMode" );
	}
	//-----------------------------------------------------------------------------
	void dealloc( void )
	//-----------------------------------------------------------------------------
	{
		--(m_pRefData->m_refCnt);
		if( m_pRefData->m_refCnt == 0 )
		{
			delete m_pRefData;
		}
	}	
protected:
	explicit ImageProcessingBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal setting to access with this instance.
									/// A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
									/// settings can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
									const std::string& settingName = "Base" ) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltSetting, settingName);
		m_pRefData = new ReferenceCountedData(pDev->hDrv(), locator.searchbase_id());
		locator.bindSearchBase( m_pRefData->m_hSetting, "ImageProcessing" );
		m_hRoot = locator.searchbase_id();
		bindPublicProperties();
		// create the WB user parameter objects for this setting
		std::ostringstream oss;
		int number = 1;
		HOBJ hList = INVALID_ID;
		do
		{
			oss << "WhiteBalanceSettings-" << number++;
			if( ( hList = locator.findComponent( oss.str() ) ) != INVALID_ID )
			{
				m_pRefData->m_WBUserSettings.push_back( new WhiteBalanceSettings( hList ) );
			}
			oss.seekp(0);
		} while( hList != INVALID_ID );
	}
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::ImageProcessingBase</b> from
	/// and exisiting one.
	explicit ImageProcessingBase(	/// A constant reference to the <b>mvIMPACT::acquire::ImageProcessingBase</b> object, this object shall be created from
									const ImageProcessingBase& src ) : ComponentCollection(src), m_pRefData(src.m_pRefData)
	{
		++(m_pRefData->m_refCnt);
		bindPublicProperties();
	}
	/// \brief Class destructor.
	virtual ~ImageProcessingBase()
	{
		dealloc();
	}
#ifndef WRAP_PYTHON
	/// \brief Allows assignments of <b>mvIMPACT::acquire::ImageProcessingBase</b> objects
	ImageProcessingBase& operator=( const ImageProcessingBase& rhs )
	{
		if( this != &rhs )
		{
			ComponentCollection::operator=(rhs);
			dealloc();
			m_pRefData = rhs.m_pRefData;
			++m_pRefData->m_refCnt;
			bindPublicProperties();
		}
		return *this;
	}
#endif // #ifndef WRAP_PYTHON  (In Python, object assignment amounts to just a reference count increment anyhow; you need to call the constructor or possibly some slice operation to make a true copy)
	PYTHON_ONLY(%immutable;)
	/// \brief An enumerated integer property defining what kind of color processing shall be applied to the
	/// raw image data.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TColorProcessingMode</b>.
	PropertyIColorProcessingMode colorProcessing;
	/// \brief An integer property defining the parameter set to be used to perform the white
	/// balance correction.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TWhiteBalanceParameter</b>.
	PropertyIWhiteBalanceParameter whiteBalance;
	/// \brief An enumarated integer property defining the mode used for white balance calibration.
	///
	/// This property can be used to define the way a white balance calibration shall be performed.
	/// Currently only the <b>mvIMPACT::acquire::TWhiteBalanceCalibrationMode::wbcmNextFrame</b> mode is supported,
	/// but new modes might appear in later revisions of the interface.
	///
	/// When this property is set to <b>mvIMPACT::acquire::TWhiteBalanceCalibrationMode::wbcmNextFrame</b> the next
	/// image captured will be used as a reference to calculate the gain factors for the
	/// \e red, \e green and \e blue channel. So make sure when the next image is captured the camera
	/// looks on a plain white or slightly grey surface in order to obtain correct results. After
	/// the calibration has been done, the property will be reset to <b>mvIMPACT::acquire::TWhiteBalanceCalibrationMode::wbcmOff</b>
	/// again.
	///
	/// \note
	/// Performing this kind of white balance calibration will only affect Bayer color sensors and will
	/// only have any visual effect on the image if one of the user definable parameter sets has been
	/// selected before. This can be done by modifying the property <b>mvIMPACT::acquire::ImageProcessingBase::whiteBalance</b>.
	/// Afterwards the calculated factors will be stored in the <b>mvIMPACT::acquire::WhiteBalanceSettings</b> selected.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TWhiteBalanceCalibrationMode</b>.
	PropertyIWhiteBalanceCalibrationMode whiteBalanceCalibration;
	/// \brief An enumerated integer property defining the filter to be applied to the image
	/// before it is transferred to the user.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TImageProcessingFilter</b>.
	PropertyIImageProcessingFilter filter;
	/// \brief An enumerated integer property defining the mirror mode to be applied to the image.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TMirrorMode</b>.
	PropertyIMirrorMode	mirrorMode;
	PYTHON_ONLY(%mutable;)
	/// \brief Currently unsupported.
	///
	/// \note This function currently does nothing and its interface might change in the
	/// next release.
	void defineFilterImageBuffer( TFilterType filtertype, const ImageBufferDesc& image, int imageNumber = 0, int flags = 0, int reserved = 0 )
	{
		TDMR_ERROR result;
		if( ( result = DMR_SetFilterImageBuffer( m_pRefData->m_hDrv, m_pRefData->m_hSetting, filtertype, image.getBuffer(), imageNumber, flags, reserved ) ) != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result );
		}
	}
	/// \brief Currently unsupported.
	///
	/// \note This function currently does nothing and its interface might change in the
	/// next release.
	ImageBufferDesc	queryFilterImageBuffer( TFilterType filtertype, int imageNumber = 0, int flags = 0, int reserved = 0 ) const
	{
		ImageBuffer* pBuf = 0;
		TDMR_ERROR result;
		if( ( result = DMR_GetFilterImageBuffer( m_pRefData->m_hDrv, m_pRefData->m_hSetting, filtertype, &pBuf, imageNumber, flags, reserved ) ) != DMR_NO_ERROR )
		{
			ExceptionFactory::raiseException( __FUNCTION__, __LINE__, result );
		}
		return ImageBufferDesc( true, pBuf );
	}
#ifdef DOTNET_ONLY_CODE
	PropertyIColorProcessingMode			getColorProcessing( void ) const { return colorProcessing; }
	PropertyIWhiteBalanceParameter			getWhiteBalance( void ) const { return whiteBalance; }
	PropertyIWhiteBalanceCalibrationMode	getWhiteBalanceCalibration( void ) const { return whiteBalanceCalibration; }
	PropertyIImageProcessingFilter			getFilter( void ) const { return filter; }
	PropertyIMirrorMode						getMirrorMode( void ) const { return mirrorMode; }
#endif // #ifdef DOTNET_ONLY_CODE
	/// \brief Returns a reference to a set of user definable parameters to perform a white balance correction.
	///
	/// Pass '0' for the setting that is activated by setting the property <b>mvIMPACT::acquire::ImageProcessingBase::whiteBalance</b>
	/// to <b>mvIMPACT::acquire::TWhiteBalanceParameter::wbpUser1</b>, '1' for
	/// <b>mvIMPACT::acquire::TWhiteBalanceParameter::wbpUser2</b> and so on.
	///
	/// \return A reference to one of the parameter set for white balance correction that
	/// can be altered by the user.
	WhiteBalanceSettings& getWBUserSetting(	/// The number of the setting to be returned
											unsigned int settingNr ) const { return *(m_pRefData->m_WBUserSettings.at(settingNr)); }
	/// \brief Returns the number of available user definable parameter sets for white balance correction.
	unsigned int getWBUserSettingsCount( void ) const { return static_cast<unsigned int>(m_pRefData->m_WBUserSettings.size()); }
};

//-----------------------------------------------------------------------------
/// \brief Image processing related properties.
///
/// This class provides general access to properties, which define how the image shall
/// be processed after it has been captured but before it will be handed back to
/// the user.
class ImageProcessing : public ImageProcessingBase
//-----------------------------------------------------------------------------
{
public:
	explicit	ImageProcessing(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal setting to access with this instance.
									/// A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
									/// settings can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
									const std::string& settingName = "Base" ) : ImageProcessingBase( pDev, settingName ) {}
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A helper class to access image processing related properties, that are
	/// unique features of the <b>mvBlueFOX</b>.
	///
	/// This class also provides access to general image processing related properties
	/// and functions.
	class ImageProcessingBlueFOX : public ImageProcessingBase
	//-----------------------------------------------------------------------------
	{
	public:
		explicit	ImageProcessingBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
											Device* pDev,
											/// The name of the driver internal setting to access with this instance.
											/// A list of valid setting name can be obtained by a call to
											/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
											/// settings can be created with the function
											/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
											const std::string& settingName = "Base" ) : ImageProcessingBase( pDev, settingName )
		{
			ComponentLocator locator( m_hRoot, "DefectivePixelsFilter" );
			locator.bindComponent( defectivePixelsFilterMode, "Mode");
			locator.bindComponent( defectivePixelsFilterLeakyPixelDeviation_ADCLimit, "LeakyPixelDeviation_ADCLimit" );
			locator.bindComponent( defectivePixelsFilterColdPixelDeviation_pc, "ColdPixelDeviation_pc" );
			locator.bindSearchBase( m_hRoot, "FlatFieldFilter" );
			locator.bindComponent( flatFieldFilterMode, "Mode" );
			locator.bindComponent( flatFieldFilterCalibrationImageCount, "CalibrationImageCount" );
			locator.bindSearchBase( m_hRoot, "DarkCurrentFilter" );
			locator.bindComponent( darkCurrentFilterMode, "Mode" );
			locator.bindComponent( darkCurrentFilterCalibrationImageCount, "CalibrationImageCount" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the operation mode of the dark current filter.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDarkCurrentFilterMode</b>.
		PropertyIDarkCurrentFilterMode		darkCurrentFilterMode;
		/// \brief An integer property defining the number of consecutive images to take into account
		/// during calibration of the dark current filter.
		PropertyI							darkCurrentFilterCalibrationImageCount;
		/// \brief An enumerated integer property defining the operation mode of the defective pixels filter.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDefectivePixelsFilterMode</b>.
		PropertyIDefectivePixelsFilterMode	defectivePixelsFilterMode;
		/// \brief An integer property defining the max. allowed offset from the average grey value for a pixel
		/// during calibration.
		///
		/// When this filter is calibrated each pixel producing a grey value higher then the average grey value plus
		/// the value of this property will be considered as a leaky pixel and therefore will be replaced by
		/// a value depending on the operation mode of the filter.
		PropertyI							defectivePixelsFilterLeakyPixelDeviation_ADCLimit;
		/// \brief An integer property defining the max. allowed deviation for a pixel in per cent from the
		/// average grey value.
		///
		/// If this filter is active every pixel that during the calibration produces a grey value which is
		/// lower then the average grey value of the image minus the allowed deviation in per cent will be
		/// considered as a cold pixel and therefore will be replaced by a value depending on the operation
		/// mode of the filter.
		PropertyI							defectivePixelsFilterColdPixelDeviation_pc;
		/// \brief An enumerated integer property defining the operation mode of the flat field correction filter.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TFlatFieldFilterMode</b>.
		PropertyIFlatFieldFilterMode		flatFieldFilterMode;
		/// \brief An integer property defining the number of consecutive images to take into account
		/// during the calibration of the flat field filter.
		PropertyI							flatFieldFilterCalibrationImageCount;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIDarkCurrentFilterMode		getDarkCurrentFilterMode( void ) const { return darkCurrentFilterMode; }
		PropertyIDefectivePixelsFilterMode	getDefectivePixelsFilterMode( void ) const { return defectivePixelsFilterMode; }
		PropertyI							getDefectivePixelsFilterLeakyPixelDeviation_ADCLimit( void ) const { return defectivePixelsFilterLeakyPixelDeviation_ADCLimit; }
		PropertyI							getDectivePixelsFilterColdPixelDeviation_pc( void ) const { return defectivePixelsFilterColdPixelDeviation_pc; }
		PropertyIFlatFieldFilterMode		getFlatFieldFilterMode( void ) const { return flatFieldFilterMode;	}
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

//-----------------------------------------------------------------------------
/// \brief A combination of the most important settings.
///
/// This class provides a standard interface to modify all important properties
/// related to the image acquisition. It simply combines some other objects to
/// present these settings 'as a whole' so this is nothing the user has to use
/// but something provided for convenience.
///
/// For most applications this will be the object to use when the caller wants to
/// modify a lot of the acquisition related properties from time to time.
///
/// If you don't need most of the settings embedded in this class you can also
/// use the underlying objects <b>mvIMPACT::acquire::CameraSettings</b>, <b>mvIMPACT::acquire::ImageDestination</b> and
/// <b>mvIMPACT::acquire::ImageProcessing</b>.
///
/// To see a small code example on how you can work with object of this class see
/// the detailed description of the class <b>mvIMPACT::acquire::FunctionInterface</b> as well.
///
/// \note
/// This class is provided for compatibility only and has been declared deprecated! Only
/// the <b>mvBlueFOX</b> supports all the properties declared in this class or its embedded objects.
/// No new properties will be added to this class anymore.<br>
/// Users should use the device specific setting classes derived from
/// <b>mvIMPACT::acquire::FullSettingsBase</b>
/// \if BUILD_MVGRABBER_DOCUMENTATION
/// \note
/// like e.g. <b>mvIMPACT::acquire::SettingsFrameGrabber</b>
/// \elseif BUILD_MVBLUEFOX_DOCUMENTATION
/// \note
/// like e.g. <b>mvIMPACT::acquire::SettingsBlueFOX</b>
/// \endif
class Settings
//-----------------------------------------------------------------------------
{
public:
	explicit		Settings(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev,
								/// The name of the driver internal setting to access with this instance.
								/// A list of valid setting name can be obtained by a call to
								/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
								/// settings can be created with the function
								/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
								const std::string& name = "Base" ) : cameraSetting( pDev, name ),
									imageDestination( pDev, name ),	imageProcessing( pDev, name )
	{
		DeviceComponentLocator locator(pDev, dltSetting, name);
		locator.bindComponent( basedOn, "BasedOn" );
	}
	PYTHON_ONLY(%immutable;)
	/// \brief Camera related settings.
	CameraSettings cameraSetting;
	/// \brief Properties to define the result images format.
	ImageDestination imageDestination;
	/// \brief Image processing related properties.
	ImageProcessing imageProcessing;
	/// \brief A string property <b>(read-only)</b> containing the name of the setting this setting is based on.
	PropertyS basedOn;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	CameraSettings&		getCameraSetting( void ) { return cameraSetting; }
	ImageDestination&	getImageDestination( void ) { return imageDestination; }
	ImageProcessing&	getImageProcessing( void ) { return imageProcessing; }
	PropertyS			getBasedOn( void ) const { return basedOn; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A base class that provides access to the most common settings for a
/// device.
///
/// Use one of the class derived from this class to get access to all the available
/// settings.
class FullSettingsBase
//-----------------------------------------------------------------------------
{
protected:
	explicit FullSettingsBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev,
								/// The name of the driver internal setting to access with this instance.
								/// A list of valid setting name can be obtained by a call to
								/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
								/// settings can be created with the function
								/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
								const std::string& name = "Base" ) : imageDestination( pDev, name )
	{
		DeviceComponentLocator locator(pDev, dltSetting, name);
		locator.bindComponent( basedOn, "BasedOn" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief Properties to define the result images format.
	ImageDestination imageDestination;
	/// \brief A string property <b>(read-only)</b> containing the name of the setting this setting is based on.
	PropertyS basedOn;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	ImageDestination&	getImageDestination( void ) { return imageDestination; }
	PropertyS			getBasedOn( void ) const { return basedOn; }
#endif // #ifdef DOTNET_ONLY_CODE
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief This class provides access to general settings as well as to settings
	/// which are unique for the <b>mvBlueFOX</b>.
	///
	/// To see a small code example on how you can work with object of this class see
	/// the detailed description of the class <b>mvIMPACT::acquire::FunctionInterface</b> as well.
	/// Statements made for the use of the class <b>mvIMPACT::acquire::Settings</b> apply for
	/// this class as well.
	class SettingsBlueFOX : public FullSettingsBase
	//-----------------------------------------------------------------------------
	{
	public:
		explicit SettingsBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev,
									/// The name of the driver internal setting to access with this instance.
									/// A list of valid setting name can be obtained by a call to
									/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
									/// settings can be created with the function
									/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
									const std::string& name = "Base" ) : FullSettingsBase(pDev, name),
			cameraSetting(pDev, name), imageProcessing(pDev, name) {}
		PYTHON_ONLY(%immutable;)
		/// \brief Camera related settings.
		CameraSettingsBlueFOX	cameraSetting;
		/// \brief Image processing related properties.
		ImageProcessingBlueFOX	imageProcessing;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		CameraSettingsBlueFOX&	getCameraSetting( void ) { return cameraSetting; }
		ImageProcessingBlueFOX&	getImageProcessing( void ) { return imageProcessing; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief This class provides access to general settings as well as to settings
	/// which are unique for frame grabber devices.
	///
	/// To see a small code example on how you can work with object of this class see
	/// the detailed description of the class <b>mvIMPACT::acquire::FunctionInterface</b> as well.
	/// Statements made for the use of the class <b>mvIMPACT::acquire::Settings</b> apply for
	/// this class as well.
	class SettingsFrameGrabber : public FullSettingsBase
	//-----------------------------------------------------------------------------
	{
	public:
		explicit SettingsFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
										Device* pDev,
										/// The name of the driver internal setting to access with this instance.
										/// A list of valid setting name can be obtained by a call to
										/// <b>mvIMPACT::acquire::FunctionInterface::getAvailableSettings</b>, new
										/// settings can be created with the function
										/// <b>mvIMPACT::acquire::FunctionInterface::createSetting</b>
										const std::string& name = "Base" ) : FullSettingsBase(pDev, name), cameraSetting(pDev, name), connector(pDev, name), imageProcessing(pDev, name) {}
		PYTHON_ONLY(%immutable;)
		/// \brief Camera related settings.
		CameraSettingsFrameGrabber cameraSetting;
		/// \brief Input channel related properties.
		ConnectorFrameGrabber connector;
		/// \brief Image processing related properties.
		ImageProcessing imageProcessing;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		CameraSettingsFrameGrabber&	getCameraSetting( void ) { return cameraSetting; }
		ConnectorFrameGrabber&		getConnector( void ) { return connector; }
		ImageProcessing&			getImageProcessing( void ) { return imageProcessing; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
//-----------------------------------------------------------------------------
/// \brief Contains basic statistical information
///
/// This class contains basic statistical information about the <b>mvIMPACT::acquire::Device</b> and the
/// the current image acquisition progress.
class StatisticsBase : public ComponentCollection
//-----------------------------------------------------------------------------
{
protected:
	explicit StatisticsBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a 
								/// <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev) : ComponentCollection(pDev)
	{
		DeviceComponentLocator locator(pDev, dltStatistics);
		locator.bindComponent( errorCount, "ErrorCount" );
		locator.bindComponent( framesPerSecond, "FramesPerSecond" );
		locator.bindComponent( frameCount, "FrameCount" );
		locator.bindComponent( imageProcTime_s, "ImageProcTime_s" );
		locator.bindComponent( captureTime_s, "CaptureTime_s" );
		locator.bindComponent( queueTime_s, "QueueTime_s" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief An float property <b>(read-only)</b> containing the average time needed to capture an image.
	///
	/// This time is <b>NOT</b> the reciprocal of the frame rate, but usually a longer period of time as it includes the time
	/// elapsed from the trigger signal to the end of the image processing time. Typically more images can be captured
	/// as the processing can run in parallel to the sensor readout for example.
	PropertyF		captureTime_s;
	/// \brief An integer property <b>(read-only)</b> containing the overall count of image requests which returned with an error since the <b>mvIMPACT::acquire::Device</b> has been opened.
	PropertyI		errorCount;
	/// \brief An float property <b>(read-only)</b> containing the current number of frames captures per second.
	PropertyF		framesPerSecond;
	/// \brief An integer property <b>(read-only)</b> containing the overall count of images captured since the <b>mvIMPACT::acquire::Device</b> has been opened.
	PropertyI		frameCount;
	/// \brief An integer property <b>(read-only)</b> containing the time (in seconds) needed to process the image data
	/// internally.
	///
	/// This time e.g. might be interesting if the (for Bayer mosaic cameras) the image data is transformed into a color
	/// image by the driver or if any other processing function is applied to the image before it is transferred to the user.
	PropertyF		imageProcTime_s;
	/// \brief An float property <b>(read-only)</b> containing the average time (in seconds) a <b>mvIMPACT::acquire::Request</b> object
	/// spends in the request queue of the device.
	PropertyF		queueTime_s;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyF		getCaptureTime_s( void ) const { return captureTime_s; }
	PropertyI		getErrorCount( void ) const { return errorCount; }
	PropertyF		getFramesPerSecond( void ) const { return framesPerSecond; }
	PropertyI		getFrameCount( void ) const { return frameCount; }
	PropertyF		getImageProcTime_s( void ) const { return imageProcTime_s; }
	PropertyF		getQueueTime_s( void ) const { return queueTime_s; }
#endif // #ifdef DOTNET_ONLY_CODE	
};

//-----------------------------------------------------------------------------
/// \brief Contains statistical information
///
/// This class contains general statistical information about the <b>mvIMPACT::acquire::Device</b> and the
/// the current image acquisition progress.
class Statistics : public StatisticsBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::Statistics</b> object.
	explicit		Statistics(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
								Device* pDev ) : StatisticsBase(pDev) {}
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class providing access to <b>mvBlueFOX</b> specific statistical information.
	class StatisticsBlueFOX : public StatisticsBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::StatisticsBlueFOX</b> object.
		explicit StatisticsBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev ) : StatisticsBase(pDev)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( USBRetransmitCount, "USBRetransmitCount" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property <b>(read-only)</b> containing the number retransmitted USB packets via
		/// the USB bus.
		///
		/// This value can be an indicator for USB transaction problems in the current system.
		/// Normally it should stay 0 all the time.
		PropertyI	USBRetransmitCount;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI	getUSBRetransmitCount( void ) const { return USBRetransmitCount; }
	#endif // #ifdef DOTNET_ONLY_CODE	
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class providing access to <b>MATRIX VISION GmbH</b> frame grabber specific
	/// statistical information.
	class StatisticsFrameGrabber : public StatisticsBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::StatisticsFrameGrabber</b> object.
		explicit StatisticsFrameGrabber(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
										Device* pDev ) : StatisticsBase(pDev)
		{
			ComponentLocator locator(m_hRoot);
			locator.bindComponent( lostImagesCount, "LostImagesCount" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An integer property <b>(read-only)</b> containing the number of images that have been
		/// lost from a continuous image stream coming from the camera.
		///
		/// \note
		/// This value is based on an assumption so it's by no means absolutely accurate, but when this
		/// value starts to increase problems might be present.
		///
		/// Possible causes (among others) might be:
		/// - the frame grabber can't cope with the amount of data the camera delivers in the current mode
		/// - the frame grabber can't transfer all the data to the host PC because of frame grabber to PC
		/// bus bandwidth shortages
		/// - the frame grabbers image request queue ran low because the system is busy doing other things
		PropertyI	lostImagesCount;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyI	getLostImagesCount( void ) const { return lostImagesCount; }
	#endif // #ifdef DOTNET_ONLY_CODE	
	};
#endif // #ifndef IGNORE_MVGRABBER_SPECIFIC_DOCUMENTATION

//-----------------------------------------------------------------------------
/// \brief A base class for accessing settings that control the overall behaviour of a device driver.
///
/// Instances of this class can't be constructed directly. Use one of the derived types.
class SystemBase : public ComponentCollection
//-----------------------------------------------------------------------------
{
protected:
	/// \brief Constructs a new <b>mvIMPACT::acquire::SystemBase</b> object.
	explicit SystemBase(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a 
							/// <b>mvIMPACT::acquire::DeviceManager</b> object.
							Device* pDev ) : ComponentCollection(pDev)	
	{
		DeviceComponentLocator locator( pDev, dltSystemSettings );
		locator.bindComponent( requestCount, "RequestCount" );
		locator.bindComponent( workerPriority, "WorkerPriority" );
	}
public:
	PYTHON_ONLY(%immutable;)
	/// \brief An integer property defining the number of requests to process image requests allocated
	/// by the driver.
	///
	/// \sa
	/// <b>mvIMPACT::acquire::FunctionInterface::requestCount,<br>
	///	   mvIMPACT::acquire::FunctionInterface::ensureRequests</b>
	PropertyI					requestCount;
	/// \brief An enumerated integer property defining the thread priority of the drivers
	/// internal worker thread.
	///
	/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TThreadPriority</b>.
	PropertyIThreadPriority	workerPriority;
	PYTHON_ONLY(%mutable;)
#ifdef DOTNET_ONLY_CODE
	PropertyI				getRequestCount( void ) const { return requestCount; }
	PropertyIThreadPriority	getWorkerPriority( void ) const { return workerPriority; }
#endif // #ifdef DOTNET_ONLY_CODE
};

//-----------------------------------------------------------------------------
/// \brief A class for accessing general settings that control the overall behaviour of a device driver.
class SystemSettings : public SystemBase
//-----------------------------------------------------------------------------
{
public:
	/// \brief Constructs a new <b>mvIMPACT::acquire::SystemSettings</b> object.
	explicit SystemSettings( /// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
							 Device* pDev ) : SystemBase(pDev) {}
};

#ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION
	//-----------------------------------------------------------------------------
	/// \brief A class containing <b>mvBlueFOX</b> specific settings to control the overall
	/// behaviour of the driver.
	class SystemBlueFOX : public SystemBase
	//-----------------------------------------------------------------------------
	{
	public:
		/// \brief Constructs a new <b>mvIMPACT::acquire::SystemBlueFOX</b> object.
		explicit SystemBlueFOX(	/// A pointer to a <b>mvIMPACT::acquire::Device</b> object obtained from a <b>mvIMPACT::acquire::DeviceManager</b> object.
									Device* pDev ) : SystemBase( pDev )
		{
			DeviceComponentLocator locator(pDev, dltSystemSettings);
			locator.bindComponent( powerMode, "PowerMode" );
			locator.bindSearchBase( locator.searchbase_id(), "Camera" );
			locator.bindComponent( transferSize, "TransferSize" );
			locator.bindComponent( footerMode, "FooterMode" );
		}
		PYTHON_ONLY(%immutable;)
		/// \brief An enumerated integer property defining the block size of the
		/// image data blocks transferred from the device.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueFOXTransferSize</b>.
		PropertyIBlueFOXTransferSize transferSize;
		/// \brief An enumerated integer property defining the footer mode of the
		/// device.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TBlueFOXFooterMode</b>.
		PropertyIBlueFOXFooterMode footerMode;
		/// \brief An enumerated integer property defining the power mode of the
		/// device.
		///
		/// \note
		/// This property requires at least firmware version 39! See <b>mvIMPACT::acquire::Device::firmwareVersion</b> to find
		/// out which firmware is currently running on the device or use <b>mvIMPACT::acquire::Device::updateFirmware()</b>
		/// to update the firmware to the state compiled into the driver.
		///
		/// Valid values for this property are defined by the enumeration <b>mvIMPACT::acquire::TDevicePowerMode</b>.
		PropertyIDevicePowerMode powerMode;
		PYTHON_ONLY(%mutable;)
	#ifdef DOTNET_ONLY_CODE
		PropertyIBlueFOXTransferSize	getTransferSize( void ) const { return transferSize; }
		PropertyIBlueFOXFooterMode		getFooterMode( void ) const { return footerMode; }
		PropertyIDevicePowerMode		getPowerMode( void ) const { return powerMode; }
	#endif // #ifdef DOTNET_ONLY_CODE
	};
#endif // #ifndef IGNORE_MVBLUEFOX_SPECIFIC_DOCUMENTATION

#ifndef WRAP_DOTNET
	inline void ExceptionFactory::raiseException( const char* pFunctionName, int lineNumber, int errorCode, HOBJ objectHandle /* = INVALID_ID*/, const std::string& additionalInfo /*= ""*/ )
	{
		std::ostringstream oss;
		oss << pFunctionName << " (line: " << lineNumber << ")";
		switch( errorCode )
		{
		case PROPHANDLING_NOT_A_LIST:
			throw ENotAList(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NOT_A_PROPERTY:
			throw ENotAProperty(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NOT_A_METHOD:
			throw ENotAMethod(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NO_READ_RIGHTS:
			throw ENoReadRights(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NO_WRITE_RIGHTS:
			throw ENoWriteRights(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NO_MODIFY_SIZE_RIGHTS:
			throw ENoModifySizeRights(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_INCOMPATIBLE_COMPONENTS:
			throw EIncompatibleComponents(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_NO_USER_ALLOCATED_MEMORY:
			throw ENoUserAllocatedMemory(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_UNSUPPORTED_PARAMETER:
			throw EUnsupportedParameter(oss.str());
		case PROPHANDLING_SIZE_MISMATCH:
			throw ESizeMismatch("Size mismatch during query of values for " + Component(objectHandle).name(), oss.str());
		case PROPHANDLING_INVALID_PROP_VALUE:
			throw EInvalidValue(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_PROP_TRANSLATION_TABLE_CORRUPTED:
			throw ETranslationTableCorrupted(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_PROP_VAL_ID_OUT_OF_BOUNDS:
			throw EValIDOutOfBounds(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_PROP_TRANSLATION_TABLE_NOT_DEFINED:
			throw ETranslationTableNotDefined(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_INVALID_PROP_VALUE_TYPE:
			throw EInvalidValueType(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_PROP_VAL_TOO_LARGE:
			{
				Property p(objectHandle);
				throw EValTooLarge(additionalInfo + oss.str(), p.readS( plMaxValue ), p.name(), oss.str());
			}
		case PROPHANDLING_PROP_VAL_TOO_SMALL:
			{
				Property p(objectHandle);
				throw EValTooSmall(additionalInfo, p.readS( plMinValue ), p.name(), oss.str());
			}
		case PROPHANDLING_LIST_ID_INVALID:
			throw EInvalidListID(oss.str());
		case PROPHANDLING_COMPONENT_ID_INVALID:
			throw EComponentIDInvalid(oss.str());
		case PROPHANDLING_LIST_ENTRY_OCCUPIED:
			throw EListEntryOccupied(oss.str());
		case PROPHANDLING_LIST_CANT_ACCESS_DATA:
			throw ECantAccessData(additionalInfo, oss.str());
		case PROPHANDLING_METHOD_PTR_INVALID:
			throw EMethodPtrInvalid(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_METHOD_INVALID_PARAM_LIST:
			throw EInvalidParameterList(oss.str());
		case PROPHANDLING_IMPLEMENTATION_MISSING:
			throw EImplementationMissing(oss.str());
		case PROPHANDLING_INVALID_INPUT_PARAMETER:
			throw EInvalidInputParameter(oss.str());
		case PROPHANDLING_INPUT_BUFFER_TOO_SMALL:
			throw EInputBufferTooSmall(oss.str());
		case PROPHANDLING_WRONG_PARAM_COUNT:
			throw EWrongParamCount(oss.str());
		case PROPHANDLING_UNSUPPORTED_OPERATION:
			throw EUnsupportedOperation(oss.str());
		case PROPHANDLING_CANT_SERIALIZE_DATA:
			throw ECantSerializeData(Component(objectHandle).name(), oss.str());
		case PROPHANDLING_INVALID_FILE_CONTENT:
			throw EInvalidFileContent(additionalInfo, oss.str());
		case PROPHANDLING_CANT_REGISTER_COMPONENT:
			throw ECantRegisterComponent(oss.str());
		case PROPHANDLING_CANT_ALLOCATE_LIST:
			throw ECantAllocateNewList(oss.str());
		// unsupported:
		//PROPHANDLING_ACCESSTOKEN_CREATION_FAILED			= -2011
		//PROPHANDLING_COMPONENT_NOT_FOUND					= -2019,
		//PROPHANDLING_COMPONENT_HAS_OWNER_ALREADY			= -2023,
		//PROPHANDLING_COMPONENT_ALREADY_REGISTERED			= -2024,
		//PROPHANDLING_SWIG_ERROR							= -2028,
		//PROPHANDLING_COMPONENT_NO_CALLBACK_REGISTERED		= -2030,
		case DMR_DEV_NOT_FOUND:
		case DMR_INIT_FAILED:
		case DMR_DRV_ALREADY_IN_USE:
		case DMR_DEV_CANNOT_OPEN:
		case DMR_NOT_INITIALIZED:
		case DMR_DRV_CANNOT_OPEN:
		case DMR_DEV_REQUEST_QUEUE_EMPTY:
		case DMR_DEV_REQUEST_CREATION_FAILED:
		case DMR_INVALID_PARAMETER:
		case DMR_EXPORTED_SYMBOL_NOT_FOUND:
		case DEV_UNKNOWN_ERROR:
		case DEV_HANDLE_INVALID:
		case DEV_INPUT_PARAM_INVALID:
		case DEV_WRONG_INPUT_PARAM_COUNT:
		case DEV_CREATE_SETTING_FAILED:
		case DEV_REQUEST_CANT_UNLOCKED:
		case DEV_INVALID_REQUEST_NUMBER:
		case DEV_LOCKED_REQUEST_IN_QUEUE:
		case DEV_NO_FREE_REQUEST_AVAILABLE:
		case DEV_WAIT_FOR_REQUEST_FAILED:
		case DEV_UNSUPPORTED_PARAMETER:
		case DEV_INVALID_RTC_NUMBER:
		case DMR_INTERNAL_ERROR:
		case DMR_INPUT_BUFFER_TOO_SMALL:
		case DEV_INTERNAL_ERROR:
		case DMR_LIBRARY_NOT_FOUND:
		case DMR_FUNCTION_NOT_IMPLEMENTED:
		case DMR_FEATURE_NOT_AVAILABLE:
		case DMR_EXECUTION_PROHIBITED:
		case DMR_FILE_NOT_FOUND:
		case DMR_INVALID_LICENCE:
		case DEV_SENSOR_TYPE_ERROR:
		case DMR_CAMERA_DESCRIPTION_INVALID:
		case DMR_NEWER_LIBRARY_REQUIRED:
			throw EDeviceManager(additionalInfo, oss.str(), static_cast<TDMR_ERROR>(errorCode));
		default:
			throw ImpactAcquireException( "Unknown error( " + additionalInfo + ")", oss.str(), errorCode );
		}
	}
#endif // #ifndef WRAP_DOTNET

#ifndef WRAP_PYTHON
		} // namespace acquire
	} // namespace mvIMPACT
	#if !defined(WRAP_ANY) && !defined(DOXYGEN_SHOULD_SKIP_THIS)
		//-----------------------------------------------------------------------------
		// this function has been declared deprecated! Don't use it anymore it's only provided for
		// downward compatibility.
		inline std::ostream& operator<<( std::ostream& out, const mvIMPACT::acquire::Device& dev )
		//-----------------------------------------------------------------------------
		{
			out << "DevName: " << dev.serial.read()
				<< ", device handle: " << dev.hDev()
				<< ", driver handle: " << dev.hDrv()
				<< ", deviceID: " << dev.deviceID.read()
				<< ", family: " << dev.family.read()
				<< ", firmware version: " << dev.firmwareVersion.read()
				<< ", load settings: " << dev.loadSettings.readS()
				<< ", product: " << dev.product.read()
				<< ", serial: " << dev.serial.read()
				<< ", state: " << dev.state.read();
			return out;
		}
	#endif // #if !defined(WRAP_ANY) && !defined(DOXYGEN_SHOULD_SKIP_THIS)
#endif // #ifdef WRAP_PYTHON

// restore Borland compiler switch 'force enums to the size of integer'
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
#	ifdef _WIN32
#		ifdef __BORLANDC__
#			pragma option pop
#		endif
#	endif // _WIN32
#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)

#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_PYTHON)
#	ifndef MVIMPACT_USE_NAMESPACES
		using namespace mvIMPACT::acquire;
#	endif // #ifndef MVIMPACT_USE_NAMESPACES
#endif // DOXYGEN_SHOULD_SKIP_THIS && WRAP_PYTHON

#ifdef _MSC_VER	// is Microsoft compiler?
	// restore old warning level
#	pragma warning( pop )
#endif // #ifdef _MSC_VER

#endif // MVIMPACT_ACQUIRE_H_
