
#ifndef _NETWORK_INTERFACE_H_
#define _NETWORK_INTERFACE_H_

#include <Client/ClientUtils/AreaLimiter.hpp>
#include <Client/ClientUtils/DynamicColorScaleStructs.h>
#include <Client/ClientUtils/MoMaPropertyDesc.h>
#include <Client/ClientUtils/MoMaPropertyValue.h>
#include <Client/ClientUtils/MoMaStructs.h>
#include <Client/ClientUtils/Network/ColorMapDesc.hpp>
#include <Client/ClientUtils/Network/FeatureClassDetailedDesc.h>
#include <Client/ClientUtils/Network/NetworkInterfaceStructs.h>
#include <Client/ClientUtils/Network/TableAttributeDesc.h>
#include <Client/ClientUtils/Network/TableAttributeVal.h>
#include <Client/ClientUtils/Network/TableConstrainedAttributeDesc.h>
#include <Client/ClientUtils/Network/constrained_color_value_desc.hpp>
#include <Client/ClientUtils/QueryFilter.hpp>
#include <Client/ClientUtils/color_scheme.hpp>
#include <GSTenums.h>
#include <Geometry/IGeometry.h>
#include <Geometry/SRSItem.h>
#include <Geometry/StreamableGeometry.h>
#include <Utils/GSTVersion.h>
#include <Utils/IPartCountProgress.h>
#include <buildspec.h>
#include <exceptions/GSTRuntimeException.h>

#include <boost/lexical_cast.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
#include <cstdint>
#include <map>
#include <string>

#include <boost/thread.hpp>

namespace GST
{
namespace ClientUtils
{

class BoreHoleImageParameters;
class SectionImageParameters;
class MapImageParameters;
class OutputImageParameters;
class OutputShapeParameters;
class BoreholeGridImageParameters;
class SectionGridImageParameters;
class MapGridImageParameters;
class CorrelationPlotParameters;
class ProfileDownloadParameters;

class NetworkInterface;
typedef boost::shared_ptr<NetworkInterface> NetworkPtr;

const int maxNumConnections = 10;
const std::string NO_LOCK_IDENT = "-1";

/**
 * Technique independ interface to get information from network resources.
 */
class GST_API_EXPORT NetworkInterface
{
protected:
	Utils::PCProgressPtr progress;
	Utils::GSTVersionPtr backend_version;
	bool checkFeatureNameIsUnique;
	std::string ident;

	static boost::mutex numConnectionsMutex;
	static boost::condition_variable cond;
	static int numConnections;

public:
	/// some dictionary typedefs
	typedef std::pair<std::string, std::string> pair_t;
	typedef std::list<pair_t> dic_t;

	enum BackendType
	{
		BackendTypePG,
		BackendTypeOCCI,
		BackendTypeMSSQL,
		BackendTypeGRPC
	};
	enum Module
	{
		ModuleCore,
		ModuleWorkflow,
		ModuleSection
	};

	///@name c'tors / d'tors
	//@{
	NetworkInterface();
	virtual ~NetworkInterface();
	//@}

	///@name About Connection
	//@{
	/**
	 * @returns true if the connection is established.
	 */
	virtual bool isConnected() const = 0;

	/**
	 * Starts a connection and check if the backend is working with this client
	 * version. This methods calls RetreiveAndCheckBackendVersion, so it will
	 * throw the same exceptions.
	 *
	 * @throws exceptions::ClientDepreciated if client is to old. (GST Desktop
	 * needs to be updated.)
	 * @throws exceptions::BackendDepreciated if backend is to old. (GST Storage
	 * needs to be updated.)
	 *
	 * @see \ref compatibility Module Compatibility Check
	 * @see RetreiveAndCheckBackendVersion()
	 */
	virtual void connect() = 0;

	/**
	 * Ends up a connection safe.
	 */
	virtual void disconnect() = 0;

	/**
	 * @returns checks if the connection is encrypted using SSL.
	 *
	 * (This is currently supported by PGAccess only.)
	 */
	virtual bool isSSLUsed() const = 0;

	/**
	 * Copies the actual connection. The copied one is independent of the forked
	 * one. The copied connection is not connected. Call fork()->connect() to
	 * start.
	 */
	virtual NetworkPtr fork() const = 0;

	/**
	 * Uses the actual connection to reconnect with different account details.
	 * The connection endpoint keeps the same.
	 */
	virtual NetworkPtr reconnect(const std::string &user,
								 const std::string &pwd,
								 const std::string &db = "") const
		= 0;

	/**
	 * Verifies if the current connection is a connection with "admin"
	 * privileges (that are required for User Handling see below, e.g.
	 * CreateUser() ).
	 */
	virtual bool isSuperUserConnection() const = 0;

	/**
	 * @returns The GST User that is currently logged on. This pointer is null
	 * (bool operator of boost::shared_ptr), if the current user is not a
	 * registered GST User.
	 *
	 * If you want to get the Account name, of logged on user use getUserName().
	 */
	virtual UserPtr getCurrentGSTUser() const = 0;

	/**
	 * @returns The IP address or name of the target machine.
	 */
	virtual std::string getEndPointName() const = 0;

	/**
	 * @returns The account name that are used to connect.
	 */
	virtual std::string getUserName() const = 0;

	/**
	 * @returns Information about the target machine
	 */
	virtual EndPointPtr getEndPoint() const = 0;

	/**
	 * Sets a progress watching class (prints progress for long operations)
	 */
	virtual void SetProgressController(Utils::PCProgressPtr progress);

	/**
	 * Getter for Option: CheckFeatureNameIsUnique
	 *
	 * @see GST::ClienUtils::NetworkInterface::getCheckFeatureNameIsUnique()
	 */
	bool getCheckFeatureNameIsUnique() const;

	/**
	 * Setter for Option: CheckFeatureNameIsUnique
	 *
	 * If this is set to true (by default), uploading methods
	 * (UploadNewFeature() and UpdateFeature()) are checking if the feature name
	 * is unique and throws an GST::exceptions::NameAlreadyExists suggesting new
	 * feature names. Set this option to false to suppress this behavior.
	 *
	 * @see GST::ClienUtils::NetworkInterface::UploadNewFeature()
	 * @see GST::ClienUtils::NetworkInterface::UpdateFeature()
	 */
	void setCheckFeatureNameIsUnique(bool val);

	/**
	 * Queries the backend (=GST Storage) version and  sets to member
	 * backend_version. This method perfoms a version check, to find out if this
	 * client version works properly with the backend version.
	 *
	 * @throws exceptions::ClientDepreciated if client is to old. (GST Desktop
	 * needs to be updated.)
	 * @throws exceptions::BackendDepreciated if backend is to old. (GST Storage
	 * needs to be updated.)
	 */
	virtual void RetreiveAndCheckBackendVersion();

	/**
	 * Returns the underlying backend type
	 */
	virtual BackendType GetBackendType() const = 0;
	//@}

	///@name Requests
	//@{
	/**
	 * @returns A list with server information (table gst.server_information)
	 * @throws ServerInformationNotFound if not server_information table found.
	 *
	 * @deprecated Use GetServerInformationTable() instead!
	 */
	virtual ServerInfoPtr GetServerInformation() = 0;

	/**
	 * @returns A list with server information (table gst.server_information)
	 * @throws ServerInformationNotFound if not server_information table found.
	 */
	virtual DataTablePtr GetServerInformationTable() const = 0;

	/**
	 * @returns true if fullTableName is accessable and select is allowed
	 */
	virtual bool TableIsSelectable(const std::string &fullTableName) const = 0;

	/**
	 * @return true if fullTableName has a column named columnName
	 */
	virtual bool ColumnExistInTable(const std::string &fullTableName,
									const std::string &columnName) const
		= 0;

	/**
	 * @returns A list of all tables of all databases which consist of
	 * references permission on the table or at least on PK column in the table
	 * for connected user
	 */
	virtual NamesListPtr ListAllTables() const = 0;
	virtual std::vector<TableDescription> ListAllTablesEx() const = 0;

	/**
	 * @returns A list of all columns of a table which consist of references
	 * permission for connected user on
	 * @param tablename includes name of database, name of schema and name of
	 * table separated by '.'. In Postgres is database part of name not
	 * applicable
	 */
	virtual NamesListPtr ListAllColumns(const std::string &tablename) const = 0;
	virtual std::vector<ColumnDescription> ListAllColumnsEx(
		const std::string &tablename) const
		= 0;
	/**
	 * @returns A list of all PK columns of a table
	 * @param tablename includes name of database, name of schema and name of
	 * table separated by '.'. In Postgres is database part of name not
	 * applicable
	 */
	virtual NamesListPtr ListPrimaryKeyColumns(
		const std::string &tablename) const
		= 0;
	/**
	 * @returns true if
	 * 1. a view (viewname) consists of a column (columns) that represents a
	 * primary key (keys) in the table tablename
	 * 2. that column (columns) is "unique" and doesn't have identical values
	 * @param tablename includes name of database, name of schema and name of
	 * table separated by '.'.
	 * @param viewname includes name of database, name of schema and name of
	 * view separated by '.'. In Postgres is database part of name not
	 * applicable
	 */
	virtual bool ViewRefersTable(const std::string &tablename,
								 const std::string &viewname) const
		= 0;
	/**
	 * @returns list of all views that refers  the table tablename
	 * and consists of a column that represents a primary key in the table
	 * tablename. Columns representing primary keys don't  have identical values
	 * @param tablename includes name of database, name of schema and name of
	 * table separated by '.'. In Postgres is database part of name not
	 * applicable
	 */
	virtual NamesListPtr ListAllViewsRefersTable(
		const std::string &tablename) const
		= 0;

	/**
	 * @returns datatype of a column as string.
	 * Column name has to consist of full name, including schema name, table
	 * name, by some DBMS also db name to get a DType of a column call
	 * GetColumnDType
	 * @throws GSTDatamodelCorruption if table or column doesn't exist.
	 */
	virtual std::string GetExactColumnDataType(
		const std::string &columnname) const
		= 0;

	/**
	 * @returns datatype as DType for a column
	 * Column name has to consist of full name, including schema name, table
	 * name, by some DBMS also db name
	 * @throws GSTDatamodelCorruption if table or column doesn't exist.
	 */
	virtual ClientUtils::TableAttributeDesc::DType GetColumnDType(
		const std::string &columnname) const
		= 0;

	/**
	 * @returns list of possible values of a column with corresponding values of
	 * primary key columns
	 */
	virtual ConstrainedTableAttributeValArrayPtr GetConstrainedPropertyValues(
		const TableAttributeDesc &cp)
		= 0;

	/**
	 * @returns values of primary keys for a value of given column
	 */
	// virtual KeyValueList GetKeyValuesForColumnValue(std::string columnname,
	// std::string value) const=0;

	virtual FeatureClassDescListPtr ListFeatureClasses() = 0;
	virtual FeatureClassDetailedDescListPtr ListFeatureClassesDetailed() const
		= 0;

	/**
	 * @returns number of features in that class
	 */
	virtual int CountFeatures(const FeatureClassDesc &featureClass) const = 0;

	/**
	 * @returns A list of all (assignable) features of the feature class
	 * featureClass that are visible for the logged in user.
	 */
	virtual AssignableFeatureDescListPtr ListAllFeatures(
		const FeatureClassDesc &featureClass) const
		= 0;

	/**
	 * Update the given cp to the database.
	 *
	 * @param cp should be a valid and persistent ConstrainedObjectPropertyDesc
	 * or ConstrainedSimplexPropertyDesc
	 *
	 * The values that are allowed to update are
	 * -# Property name of ConstrainedObjectPropertyDesc resp.
	 * ConstrainedSimplexPropertyDesc (set via
	 * ConstrainedObjectPropertyDesc::setName())
	 * -# cp.GetSourceColumnName() (set via
	 * TableConstrainedAttributeDesc::setSourceColumnName)
	 * -# cp.GetSourceViewName() (set via
	 * TableConstrainedAttributeDesc::setSourceViewName() )
	 */
	virtual TableConstrainedAttributeDescPtr UpdateConstrainedPropertyDesc(
		const TableConstrainedAttributeDesc &cp) const
		= 0;

	/**
	 * @returns A Detailed Description of a feature class
	 *
	 * @params hideSystemProperties if false, m_* columns (like m_shape,
	 * m_orient, etc) will be returned. By default they will be hidden.
	 */
	virtual FeatureClassDetailedDescPtr GetFeatureClassDetailedDesc(
		const FeatureClassDesc &featureClass,
		bool hideSystemProperties = true) const;

	/**
	 * @returns A the description of the geometry column of a feature class.
	 */
	virtual GeoColumnDescPtr GetGeoColumnDesc(
		const FeatureClassDesc &featureClass) const
		= 0;

	/**
	 * @returns A Feature description by a geometry id.
	 *
	 * @throws GeometryIdUnknown
	 */
	virtual FeatureDescPtr GetFeatureDescByGeomId(const long &idgeo) const = 0;

	/**
	 * @returns A Feature description by it's lockid or throws.
	 *
	 * @throws GSTRuntimeException	if no geometry locked with the given key
	 */
	virtual FeatureDescPtr GetFeatureDescByLockId(
		const std::string &lockid) const
		= 0;

	/**
	 * @returns A list of the simplex properties (inside geometry) for a feature
	 * class.
	 *
	 * The returned list contains SimplexPropertyDescPtr (pointers to
	 * SimplexPropertyDesc). You can get the property alignment trough
	 * SimplexPropertyDesc::getAlignment()
	 *
	 * @note If the feature class does not have simplex properties (no property
	 * table defined), this method returns a list with size of 0.
	 */
	virtual SimplexPropertyDescListPtr GetSimplexPropertyList(
		const FeatureClassDesc &featureClass) const
		= 0;

	/**
	 * @returns A list of the object properties (whole geometry, like name) for
	 * a feature class. result can include both ObjectPropertyListDesc as well
	 * as ConstrainedObjectPropertyDesc
	 *
	 * @param filterMemberProperties if true, properties with the prefix "m_"
	 * are not returned
	 */
	virtual ObjectPropertyDescListPtr GetObjectPropertyList(
		const FeatureClassDesc &featureClass,
		bool filterMemberProperties = true) const
		= 0;

	virtual ObjectPropertyDescListBySubFeatureKind
	GetObjectPropertyListBySubfeatureKind(
		const FeatureClassDesc &featureClass) const
		= 0;

	virtual SimplexPropertyDescListBySubFeatureKind
	GetSimplexPropertyListBySubfeatureKind(
		const FeatureClassDesc &featureClass) const
		= 0;

	/**
	 * @returns A list of constrained object/ constrained simplex (depends on
	 * second parameter) properties for a feature class. result is empty list if
	 * feature class doesn't contain any constrained object/simplex properties.
	 * @param IsObject has to be true to request list of constrained object
	 * properties and false for list of constrained simplex properties
	 */

	virtual NamesListPtr ListConstrainedProperties(
		const FeatureClassDesc &featureClass,
		bool IsObject) const
		= 0;

	/**
	 * @returns Returns constrained object property called propertyName for a
	 * feature class.
	 * @throws GSTDatamodelCorruption if constrained property with this name
	 * doesn't exist.
	 */
	virtual ConstrainedObjectPropertyDescPtr GetConstrainedObjectProperty(
		const FeatureClassDesc &featureClass,
		const std::string propertyName) const
		= 0;

	/**
	 * @returns Returns constrained simplex property called propertyName for a
	 * feature class.
	 * @throws GSTDatamodelCorruption if constrained property with this name
	 * doesn't exist.
	 */

	virtual ConstrainedSimplexPropertyDescPtr GetConstrainedSimplexProperty(
		const FeatureClassDesc &featureClass,
		const std::string propertyName) const
		= 0;

	/**
	 * @returns A list of object properties (including their values) for each
	 * feature of a given featureclass.
	 */
	virtual ObjectPropertiesByIdgeoMapPtr GetObjectPropertyValuesOfFeatureClass(
		const FeatureClassDesc &feature) const
		= 0;

	/**
	 * @returns A list of object properties (including their values) of a given
	 * feature.
	 */
	virtual TableAttributeValListPtr GetObjectPropertyValues(
		const FeatureDesc &feature,
		long commitKey = -1) const
		= 0;

	/**
	 * @returns A list of versioned object property values for a given feature.
	 */
	virtual VersionedObjectPropertyValueList ListObjectPropertyValueHistory(
		const FeatureDesc &feature) const
		= 0;
	/**
	 * @returns A listversioned object property values for a given object
	 * property.
	 */
	virtual VersionedObjectPropertyValueList ListObjectPropertyValueHistory(
		const ObjectPropertyDesc &objectProperty) const
		= 0;

	/**
	 * Creates a create table statement and executes it. (creates table in
	 * database). If the attributes list contains a TableAttributeKeyDescPtr it
	 * automatic creates the primary keys in the table. Otherwise a warning
	 * message will be generated, because a table without a primary key is
	 * created.
	 */
	virtual void CreateTable(
		const GST::ClientUtils::TableAttributeDescList &attributes,
		bool quoteTablename = true)
		= 0;

	/**
	 * Drops table from db
	 */
	virtual void DropTable(const std::string &tableName,
						   bool quoteTablename = true)
		= 0;

	/**
	 * Inserts new data into table.
	 */
	virtual void InsertRecord(
		const GST::ClientUtils::TableAttributeValList &attributes,
		bool quoteTablename = true)
		= 0;

	/**
	 * Deletes the record referenced by the supplied attribute.
	 *
	 * This will execute something equivalent to `DELETE FROM attribute_table
	 * WHERE attribute_column = attribute_value`.
	 */
	virtual void DeleteRecord(
		const GST::ClientUtils::TableAttributeVal &attribute,
		bool quoteTablename = true) const
		= 0;

	/**
	 * @returns Values of a table.
	 */
	virtual DataTablePtr GetTableValues(const std::string &tablename,
										const TableAttributeDescList &selection
										= TableAttributeDescList(),
										const std::string &filter
										= std::string()) const
		= 0;

	/**
	 * Updates one record of a table. (ecord::m_data::description::tablename
	 * tells which table.) Use this method to update a record which you get from
	 * GetTableValues().
	 *
	 * Only Attribute values where record->isModified(column) is true are
	 * getting updated. The primary key columns are used to generate the where
	 * clause in the update statement. So only records with with columns where
	 * record->isPrimaryKey() is true for at least one column. Otherwise this
	 * mehtods throws an exception.
	 */
	virtual void UpdateTableValues(RecordPtr record) = 0;

	/**
	 * Sets a new object property value for a given feature.
	 */
	virtual void UpdateObjectPropertyValue(const FeatureDesc &feature,
										   const TableAttributeVal &value)
		= 0;

	/**
	 * Sets a new constrained object property value for a given feature.
	 */
	virtual void UpdateObjectPropertyValue(
		const FeatureDesc &feature,
		const ConstrainedTableAttributeVal &value)
		= 0;

	/**
	 * @see UpdateObjectPropertyValue()
	 */
	virtual void UpdateObjectPropertyValues(
		const FeatureDesc &feature,
		const TableAttributeValList &values);

	/**
	 * Creates a feature class with default object properties (id:TypeSerial,
	 *oname:TypeText, color_red:TypeFloat, color_green:TypeFloat,
	 *color_blue:TypeFloat, style_transparency:TypeFloat). Compares with object
	 *properties of featureClassDesc, and if the default properties are not
	 *existent, it will creates them.
	 *
	 * To create a private class FeatureClassDetailedDesc::groupName needs to be
	 *an empty string (default by its default c'tor). To create a public class,
	 *say for group "groupA", call it with
	 *FeatureClassDetailedDesc::groupName="groupA".
	 *
	 * If FeatureClassDetailedDesc::srs is a NULL pointer, then EmptySRS will be
	 *set.
	 *
	 *	@throws GSTRuntimeException If SRS is not NULL, EmptySRS or GSTSRSRef.
	 */
	virtual FeatureClassDescPtr CreateFeatureClass(
		const FeatureClassDetailedDesc &featureClassDesc);

	/**
	  * Renames the given feature class with the specified newName.
	  * Note: newName mustn't consist of owner name.
	  * This is just a rename. It does not change the ownership of the class.
	  *
	  *	@parameter newName	The new name for the class without owner (e.g.
	  newclass).It is assumed that it's a class of the local user. *	@throws
	  GSTRuntimeException if a class with this name doesn't exist. *	@throws
	  GSTRuntimeException if a class with this name already exists. *	@throws
	  GSTRuntimeException if a newName consists of ".". *	@throws
	  GSTRuntimeException if a newName is longer than 30 characters by working
	  with Oracle.
	  * @throws GeometryIsLocked if a geometry in the feature class is locked
	  */
	virtual FeatureClassDescPtr RenameFeatureClass(
		FeatureClassDetailedDesc &featureClassDesc,
		const std::string &newName)
		= 0;
	/**
	 * Changes the ownership of the feature class.
	 *
	 * @parameter newOwner The new owner of the feature class.
	 * @parameter newName  The new name of the feature class. Useful to
	 *                     prevent name conflicts. Optional. If supplied
	 *                     empty, keeps the current name.
	 * @throws GSTRuntimeException if the owner already owns a feature
	 *          class with the same name
	 * @throws GeometryIsLocked if a geometry in the feature class is
	 *         locked
	 */
	virtual FeatureClassDescPtr ChownFeatureClass(
		const FeatureClassDesc &featureClassDesc,
		const Owner &newOwner,
		const std::string &newName = std::string()) const
		= 0;
	/**
	 * Create a snapshot of an existing feature class.
	 *
	 * After a successful operation, creates a new feature class with the
	 * following properties:
	 *
	 *   - Has given owner and name.
	 *   - Has the same feature attributes and properties as the source.
	 *   - Has the same SRS as the source.
	 *   - Has a feature copy for each source feature.
	 *
	 * The feature copies will have the following properties:
	 *
	 *   - Has one version, the most recent from source.
	 *   - Has feature attribute and property values from source.
	 *
	 * The new feature class is an independent feature class, which means it
	 * will act like any other feature class.
	 *
	 * @param sourceFeatureClass The source feature class to take the
	 *        snapshot from.
	 * @param owner The owner of the new snapshot feature class.
	 * @param name The name of the new snapshot feature class.
	 * @param commitMessage The commit message for creating the features.
	 *
	 * @return The description for the new snapshot feature class.
	 **/
	virtual FeatureClassDescPtr CreateFeatureClassSnapshot(
		const FeatureClassDesc &sourceFeatureClass,
		const Owner &onwer,
		const std::string &name,
		const std::string &commitMessage) const
		= 0;
	/**
	 * Create a snapshot of a list of features.
	 *
	 * After a successful operation, creates a new feature class with the
	 * following properties:
	 *
	 *   - Has given owner and name.
	 *   - Has the same feature attributes and properties as the source.
	 *   - Has the same SRS as the source.
	 *   - Has a feature copy for each feature in the features list.
	 *
	 * The feature copies will have the following properties:
	 *
	 *   - Has one version, the most recent from source.
	 *   - Has feature attribute and property values from source.
	 *   - Is limited by area limiter.
	 *
	 * The new feature class is an independent feature class, which means it
	 * will act like any other feature class.
	 *
	 * @param features
	 * @parblock
	 * The list of features.
	 *
	 * @note Features have to belong to the same feature class!
	 * @endparblock
	 * @param owner The owner of the new snapshot feature class.
	 * @param name The name of the new snapshot feature class.
	 * @param commitMessage The commit message for creating the features.
	 * @param areaLimiter
	 * @parblock
	 * Defines the area in which features are loaded and how selected
	 * features will be loaded.
	 *
	 * Optional.
	 *
	 * If not set, features are loaded completely without restrictions.
	 * @endparblock
	 *
	 * @throw GST::exceptions::GSTInvalidArgument If not all features belong
	 *        to the same feature class.
	 *
	 * @return The description for the new snapshot feature class and a list
	 *         of rejected features.
	 **/
	virtual std::pair<FeatureClassDescPtr, FeatureDescListPtr>
	CreateFeatureSelectionSnapshot(
		const FeatureDescListPtr &features,
		const Owner &owner,
		const std::string &name,
		const std::string &commitMessage,
		const boost::optional<AreaLimiter> &areaLimiter = boost::none) const
		= 0;

	/*
	 * Protect a feature class from any changes.
	 *
	 * A protected feature class becomes readonly. Any changes to itself or
	 * to its features will be rejected and will result in an error.
	 *
	 * @note This method requires admin rights!
	 * @throws NoAdminConnection if a connection without admin rights is
	 * used.
	 */
	virtual void ProtectFeatureClass(const FeatureClassDesc &featureClass) const
		= 0;

	/*
	 * Remove feature class change protection.
	 *
	 * @note This method requires admin rights!
	 * @throws NoAdminConnection if a connection without admin rights is
	 * used.
	 */
	virtual void DeprotectFeatureClass(
		const FeatureClassDesc &featureClass) const
		= 0;

	/**
	 * Creates a property table for the current class. The created table is
	 * named geocolumn.getGeometryTable and has no properties.
	 * @throws CreatePropertyTableException If a) Class already has a property
	 * table. b) An error occurred while creating property table.
	 */
	virtual void CreatePropertyTable(const FeatureClassDesc &featureClass,
									 const GeoColumnDesc &geocolumn)
		= 0;

	/**
	 * @see CreatePropertyTable(const FeatureClassDesc&, const GeoColumnDesc &)
	 */
	virtual void CreatePropertyTable(
		const FeatureClassDetailedDesc &featureClassDesc);

	/**
	 * Creates an object property for a given feature class (do an alter table).
	 * If @param `subFeatureKind` is provided the attribute will only be created
	 * for the specified sub kind.
	 */
	virtual ObjectPropertyDescPtr AppendObjectProperty(
		const FeatureClassDesc &featureClass,
		const TableAttributeDesc &attribute,
		const std::string &subFeatureKind = "")
		= 0;

	/**
	 * Creates an simplex property for a given feature class (do an alter
	 * table).
	 * @throw FeatureHasNoPropertyTable if the feature class has no property
	 * table. In this case create one first by calling CreatePropertyTable()!
	 */
	virtual SimplexPropertyDescPtr AppendSimplexProperty(
		const FeatureClassDesc &featureClass,
		const TableAttributeDesc &attribute,
		const std::string &subFeatureKind = "")
		= 0;
	/**
	 * Creates an constrained object property for a given feature class (do an
	 * alter table).
	 */
	virtual ObjectPropertyDescPtr AppendConstrainedObjectProperty(
		const FeatureClassDesc &featureClass,
		const ConstrainedObjectPropertyDesc &attribute,
		const std::string &subFeatureKind = "")
		= 0;

	/**
	 * Creates an constrained simplex property for a given feature class (do an
	 * alter table).
	 * @throw FeatureHasNoPropertyTable if the feature class has no property
	 * table. In this case create one first by calling CreatePropertyTable()!
	 */
	virtual void AppendConstrainedSimplexProperty(
		const FeatureClassDesc &featureClass,
		const ConstrainedSimplexPropertyDesc &attribute)
		= 0;

	/**
	 * Renames a property for a given feature class with the specified newName.
	 * Note: newName mustn't consist of "."
	 *
	 *	@parameter newName	The new name for property.
	 *	@throws GSTRuntimeException if property with this name already exists in
	 *the class
	 *	@throws GSTRuntimeException if a newName consists of ".".
	 *	@throws GSTRuntimeException if a newName is longer than 30 characters by
	 *working with Oracle or 50 characters for other DBMS.
	 */
	virtual void RenameProperty(const FeatureClassDesc &featureClass,
								TableAttributeDescPtr attribute,
								const std::string &newName) const
		= 0;

	/**
	 *   remove property column from feature class table (or feature class
	 * property table if simplex property)
	 *   @pre no geometry of the feature class can be locked
	 *   @pre property must not be a source column of a constrained property
	 *   @throws GSTRuntimeException if property doesn't exist, or is  a default
	 * property
	 */
	virtual void DeleteProperty(const ObjectPropertyDesc &objectProperty) const
		= 0;
	virtual void DeleteProperty(
		const SimplexPropertyDesc &simplexProperty) const
		= 0;

	/**
	 * Remove external table information from a constrained object property.
	 *
	 * The constrained object property will become a normal object property,
	 * stored key values remain. Drops any alias information setup for the
	 * external table.
	 *
	 * @param objectProperty constrained object property to remove external
	 * table information from
	 */
	virtual ObjectPropertyDescPtr RemoveConstrainedInformation(
		const ConstrainedObjectPropertyDesc &objectProperty)
		= 0;

	/**
	 * Set external table information for an existing object property.
	 *
	 * The data type of the object property must match the one of the key
	 * column in the external table. Any existing object property values
	 * must have a matching entry in the key column values.
	 *
	 * Can be used on a constrained object property to change its external
	 * link information. Can be used on a normal object property to make it
	 * a constrained object property.
	 *
	 * @param objectProperty object property to link to an external table
	 * @param externalTableIdentifier external table to link to
	 * @param columns columns from external table to link to
	 *
	 * @note Drops any existing alias information setup for the external
	 * table.
	 */
	virtual ObjectPropertyDescPtr SetConstrainedInformation(
		const ObjectPropertyDesc &objectProperty,
		const ExternalTableIdentifier &externalTableIdentifier,
		const TableAttributeDescList &columns)
		= 0;

	/**
	 * Start the geometric processing procedure to generalize a geometry. This
	 * increases the available level of details by one.
	 */
	virtual void SimplifyFeature(const FeatureDesc &feature) = 0;

	/**
	 *	@see SimplifyFeature()
	 */
	virtual void SimplifyFeatures(const FeatureDescList &features);

	/**
	 * Drops the feature with id id.
	 * @pre Feature must not be linked to anymore
	 * @throws NodeStillLinkedTo exception if the feature still is linked to
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_Delete_ByShapeID.dox
	 */
	virtual void DeleteFeature(long id) const = 0;

	/**
	 * Drops a feature from the database by geometry id
	 * @see DeleteFeature(long)
	 */
	virtual void DeleteFeature(const FeatureDesc &feature);

	/**
	 * @see DeleteFeature()
	 */
	virtual void DeleteFeatures(const FeatureDescList &features);

	/**
	 * Deletes a FeatureDesc class by name.
	 * To delete a public class call with featureClassName like
	 * "groupname_pool.classname" or "groupname.classname" To delete a private
	 * class (of current user that currently logged in) call with featureClass
	 * like "user.classname" or "classname"
	 */
	virtual void DeleteFeatureClass(const std::string &featureClassName) = 0;

	/**
	 * @see DeleteFeatureClass(const std::string &)
	 */
	virtual void DeleteFeatureClass(const FeatureClassDesc &featureClass);

	/**
	 * @returns a Feature instance, that can be parsed / converted or simply
	 *stored to a file.
	 *		@param geometryformat	Requesting text format
	 *		@param lock				If true no other user can modify the
	 *requested feature, until it is unlocked. In this case CrudeFeaturePtr will
	 *include a lock key needed to unlock the geometry again by UnlockByKey() or
	 *UpdateFeature()
	 *		@param queryBox			Specify a box, if you want to get a subset
	 *of a geometry. The returned CrudeFeaturePtr will be inside this box. If
	 *look is true, queryBox's parameter borderSize will be used to determine
	 *the locking boundary around the box. In this case the returned Geometry
	 *will have extent of box+borderSize. For more information please refer to
	 *SeamlessTiles in the documentation!
	 *
	 * @see Geometry::FileWrappingGeometry
	 * @see UnlockByKey
	 * @see UpdateFeature
	 *
	 * The following exception might be thrown by GST Storage call:
	 * If queryBox  unset (= QueryBoxPtr()):
	 *     @include GSTAPI_exceptions_Select_Geometry.dox
	 *
	 * If queryBox set and lock = false:
	 *     @include GSTAPI_exceptions_Select_Inside.dox
	 *
	 * * If queryBox set and lock = true:
	 * @include GSTAPI_exceptions_Select_InsideWithLock.dox
	 *
	 *
	 * @deprecated Missing SRS parameter. This method returns the feature in SRS
	 *of its feature class (no coordinate transformation). Use GetFeature(const
	 *FeatureDesc &, const IGeometry::RequestFormat &, SRSDescPtr, bool,
	 *QueryBoxPtr ) instead!
	 */
	virtual CrudeFeaturePtr GetFeature(
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1);

	/**
	 * @returns a Feature instance, that can be parsed / converted or simply
	 *stored to a file.
	 *		@param geometryformat	Requesting text format
	 *		@param srs				Requesting SRS. If not a NULL pointer, do a
	 *real time coordinate transformation into specified SRS. (Pass SRSPtr() or
	 *a NoSRS object if you want to get the object in default SRS of the class.)
	 *		@param lock				If true no other user can modify the
	 *requested feature, until it is unlocked. In this case CrudeFeaturePtr will
	 *include a lock key needed to unlock the geometry again by UnlockByKey() or
	 *UpdateFeature()
	 *		@param queryBox			Specify a box, if you want to get a subset
	 *of a geometry. The returned CrudeFeaturePtr will be inside this box. If
	 *look is true, queryBox's parameter borderSize will be used to determine
	 *the locking boundary around the box. In this case the returned Geometry
	 *will have extent of box+borderSize. For more information please refer to
	 *SeamlessTiles in the documentation!
	 *
	 * @see Geometry::FileWrappingGeometry
	 * @see UnlockByKey
	 * @see UpdateFeature
	 *
	 * The following exception might be thrown by GST Storage call:
	 * If queryBox  unset (= QueryBoxPtr()):
	 *     @include GSTAPI_exceptions_Select_Geometry.dox
	 *
	 * If queryBox set and lock = false:
	 *     @include GSTAPI_exceptions_Select_Inside.dox
	 *
	 * * If queryBox set and lock = true:
	 * @include GSTAPI_exceptions_Select_InsideWithLock.dox
	 */
	virtual CrudeFeaturePtr GetFeature(
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1)
		= 0;
	virtual CrudeFeaturePtr GetFeature(
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		const boost::optional<AreaLimiter> &areaLimiter,
		bool lock = false,
		long commitKey = -1)
		= 0;

	/**
	 * @returns a Feature instance, that can be parsed / converted or simply
	 * stored to a file in binary representation.
	 * @see Geometry::BinFileWrappingGeometry
	 *
	 * @deprecated Missing SRS parameter. This method returns the feature in SRS
	 * of its feature class (no coordinate transformation). Use
	 * GetFeatureBinary(const FeatureDesc&,SRSDescPtr) instead!
	 */
	virtual CrudeFeaturePtr GetFeatureBinary(const FeatureDesc &feature,
											 long commitKey = -1);

	/**
	 * @brief	Gets feature binary.
	 *
	 * @param	feature  	The feature.
	 * @param	srs		 	Requesting SRS. If not a NULL pointer, do a real
	 * time coordinate transformation into specified SRS. (Pass SRSPtr() or a
	 * NoSRS object if you want to get the object in default SRS of the class.)
	 * @param	queryBox 	(Optional) Specify a box, if you want to get a
	 * subset of a geometry. The returned CrudeFeaturePtr will be inside this
	 * box.
	 * @param	commitKey	(Optional) Specify to get the feature in the version
	 * 						of that commit. Leave default/Use -1 to get the
	 * 						latest version.
	 *
	 * @return	a Feature instance, that can be parsed / converted or simply
	 * 			stored to a file in binary representation.
	 *
	 * @see		Geometry::BinFileWrappingGeometry
	 * @see		Geometry::SRS
	 * @see		QueryBox
	 */
	virtual CrudeFeaturePtr GetFeatureBinary(const FeatureDesc &feature,
											 Geometry::SRSPtr srs,
											 QueryBoxPtr queryBox
											 = QueryBoxPtr(),
											 long commitKey = -1)
		= 0;

	/**
	 * Inserts a new geometry into a given class.
	 *
	 * @return A description to the new created feature.
	 *
	 * @throws GST::exceptions::NameAlreadyExists If name of the feature is not
	 * unique (this can be disabled by setting Option CheckFeatureNameIsUnique
	 * to false, see
	 * GST::ClienUtils::NetworkInterface::setCheckFeatureNameIsUnique())
	 *
	 * If Geometry::ClientGeometry::srs is a NULL pointer, the feature class SRS
	 * is assumed.
	 *
	 * If commitKey is default (-1) then a single commit is automatic created.
	 * This is not recommended, because it ends up in many autocreated commits.
	 * Better group your objects into one commit by bracket this methods by
	 * GST::ClienUtils::NetworkInterface::BeginCommit() and
	 * GST::ClienUtils::NetworkInterface::EndCommit()
	 *
	 * @see GST::ClienUtils::NetworkInterface::BeginCommit()
	 * @see GST::ClienUtils::NetworkInterface::EndCommit()
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_InserGeometry.dox
	 */
	virtual FeatureDescPtr UploadNewFeature(
		const Geometry::StreamableGeometry &feature,
		const FeatureClassDesc &target,
		long commitKey = -1,
		bool updateStats = true)
		= 0;

	/**
	 * Inserts a new geometry into a given class, as an update of an existing
	 * object in this class. This is only possible if the geometry is locked and
	 * the given lockid (=key) is valid for this lock. The Geometry will be
	 * updated and the lock will be released. If the object was selected as
	 * SeamlessTile the database takes care for model consistency (=border
	 * check). For more information please refer to SeamlessTiles in the
	 * documentation!
	 *
	 * @throws GST::exceptions::InsertFailed If update failed. The message tells
	 * what happens.
	 * @throws GST::exceptions::NameAlreadyExists If name of the feature is not
	 * unique (this can be disabled by setting Option CheckFeatureNameIsUnique
	 * to false, see
	 * GST::ClienUtils::NetworkInterface::setCheckFeatureNameIsUnique())
	 *
	 * If Geometry::ClientGeometry::srs is a NULL pointer, the feature class SRS
	 * is assumed.
	 *
	 * If commitKey is default (-1) then a single commit is automatic created.
	 * This is not recommended, because it ends up in many autocreated commits.
	 * Better group your objects into one commit by bracket this methods by
	 * GST::ClienUtils::NetworkInterface::BeginCommit() and
	 * GST::ClienUtils::NetworkInterface::EndCommit()
	 *
	 * @see GST::ClienUtils::NetworkInterface::BeginCommit()
	 * @see GST::ClienUtils::NetworkInterface::EndCommit()
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_UpdateGeometry.dox
	 */
	virtual void UpdateFeature(const Geometry::StreamableGeometry &feature,
							   const std::string &lockid,
							   const FeatureClassDesc &target,
							   long commitKey = -1,
							   bool updateStats = true)
		= 0;
	virtual void InstantUpdateFeature(
		const Geometry::StreamableGeometry &feature,
		const long &idgeo,
		const FeatureClassDesc &target,
		long commitKey = -1,
		bool updateStats = true)
		= 0;
	virtual void UpdateFeatureKeepLock(
		const Geometry::StreamableGeometry &feature,
		const std::string &lockid,
		const FeatureClassDesc &target,
		long commitKey = -1,
		bool updateStats = true)
		= 0;

	/**
	 * Moves feature to target feature class
	 * @param	feature 	feature to be moved
	 * @param	target 		feature class feature has to be moved into
	 * @param	targetfeaturename 	(optional) name of the feature in target.
	 *								If this name is empty and feature name is
	 *not unique in target, new feature name is created automatically. If
	 *targetfeaturename is not empty, targetfeaturename is used instead of
	 *feature name.
	 * @throws GST::exceptions::GSTFeatureIncompatibleToFeatureclass if simplex
	 *propeties of feature are not a subset of simplex properties of target
	 *feature class.
	 * @throws GST::exceptions::NameAlreadyExists If targetfeaturename was not
	 *empty and name of the feature is not unique in the target feature class
	 * @throws GST::exceptions::GSTRuntimeException If srs transformation was
	 *not possible
	 */
	virtual void MoveFeature(const FeatureDesc &feature,
							 const FeatureClassDesc &target,
							 const std::string &targetfeaturename = "")
		= 0;

	/**
	 * To unlock a geometry without updating, use this function. It will release
	 * the lock of Feature by a given lockid (=key).
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_releaseLock.dox
	 */
	virtual void UnlockByKey(const std::string &key) = 0;

	/**
	 * locks the geometry identified by idgeo
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_lock_geometry.dox
	 */
	virtual std::string LockGeometry(long idgeo) = 0;

	/**
	 * Returns information about a lock.
	 *
	 * @see LockInfo
	 */
	virtual LockInfoListPtr GetLockInfo(const FeatureDesc &feature);
	virtual LockInfoListPtr GetLockInfo(long idgeo) const = 0;

	/**
	 * Runs an custom SQL script on the database.
	 *
	 * @param script	PL/SQL script to be run. Take care this has valid syntax
	 * and the connected user has all needed privileges to run your custom
	 * script.
	 */
	virtual void ExecuteScript(const std::string &script) = 0;

	/**
	 * Opens a (text) file by given filename. It replaces all string given by
	 * dic::key with the corresponding values of dic::val.
	 * @see ExecuteScript()
	 */
	virtual void ExecuteScriptF(const std::string &filename,
								const dic_t &dic = dic_t());

	/**
	 * @brief returns a valid table name that does not exists
	 *
	 * Returns a table name that does not exists and is valid to be generated
	 * (e.g. on Oracle the length is limited to 30 chars).
	 *
	 * @params suffix to be added to stump
	 * @params quoteTableName if the complete table name shall be quoted before
	 * the check
	 * @params randomChars in case of tableNameStump_suffix is already in use,
	 * this method extents tableNameStump<chars>_suffix
	 *
	 * @throws GSTRuntimeException in case no table name can be generated
	 */
	virtual std::string MakeValidTableName(const std::string tableNameStump,
										   const std::string &suffix
										   = std::string(""),
										   bool quoteTableName = true,
										   int randomChars = 3) const
		= 0;

	/**
	 * @returns a JSON representation of a computed histogram.
	 *
	 * @param idgeo the id of the geometry
	 * @param property name of the property
	 * @param numberOfBins number of bins to be computed
	 */
	virtual std::string compute_histogram(const long &idgeo,
										  const std::string &property,
										  const std::string &ranges) const
		= 0;

	/**
	 * @brief returns all simplex properties of feature with version from
	 * commitKey as a CSV file
	 *
	 * The CSV format follows RFC 4180 [1].
	 * This means line endings are dos-style, field separator is , (comma)
	 * and quote character is " (double quotes).
	 *
	 * Further specifications apply:
	 *
	 * - there will always be a header line that lists the property names
	 * - text properties will always be quoted
	 * - quote characters in text properties will be escaped with an
	 *   additional quote character
	 * - number properties will never be quoted
	 * - floating point numbers will be in c-locale format, this means:
	 *     - floating point is . (dot)
	 *     - no thousand separator
	 *     - might be in scientific notation
	 *
	 * @note write the string as binary [2], to preserve the line ending
	 *       format
	 *
	 * @param feature description of the requested feature
	 * @param commitKey determines version of the geometry, -1 for latest
	 * @throws GST::exceptions::GeometryIdUnknown if geometry doesn't exist
	 * @throws GST::exceptions::GSTInvalidArgument if feature class of
	 *         geometry doesn't have any simplex properties
	 * @returns the CSV, encoded as string stored in a shared_ptr
	 * @see [1] https://tools.ietf.org/html/rfc4180
	 * @see [2] http://www.cplusplus.com/reference/ios/ios_base/openmode/
	 */
	virtual boost::shared_ptr<std::string> GetSimplexPropertiesAsCsv(
		const FeatureDesc &feature,
		long commitKey = -1) const
		= 0;

	/**
	 * @returns a JSON representation of all property values at a position
	 * x,y,z
	 *
	 * @param idgeo the id of the geometry
	 * @param x the x position
	 * @param y the y position
	 * @param z the z position
	 * @param property a JSON array for the list of requested properties
	 */
	virtual std::string getSimplexPropertyValueAtXYZ(
		const long &idgeo,
		const double &x,
		const double &y,
		const double &z,
		const std::string &property) const
		= 0;
	//@}

	///@name User Handling (requires an admin connection see
	/// isSuperUserConnection() )
	//@{
	/**
	 * Create a User. The User will be added to initialgroupName as first
	 * membership.
	 *
	 * @note User's name is not allow to end with "_pool" (Naming convention).
	 * @throws ViolateConvention
	 */
	virtual void CreateUser(const User &user,
							const std::string &initialgroupName)
		= 0;

	/**
	 * Drops user by name.
	 */
	virtual void DropUser(const std::string &name) = 0;

	/**
	 * Creates a group.
	 */
	virtual void CreateGroup(const Group &group) = 0;

	/**
	 * Drops a group by name.
	 */
	virtual void DropGroup(const std::string &name) = 0;

	/**
	 * Lists all users that are registered in GST.
	 */
	virtual UserListPtr GetAllGSTUsers() const = 0;

	/**
	 * Lists all groups that are registered in GST.
	 */
	virtual GroupListPtr GetAllGSTGroups() const = 0;

	/**
	 * Lists all users of a current group by groupName.
	 */
	virtual UserListPtr GetUsersByGroup(const std::string &groupName) const = 0;

	/**
	 * Lists all Groups that a current user is member of.
	 * @note If you want to do GetGroupsByUser( getCurrentGSTUser() ) to get all
	 * groups of current user use GetGroupsByCurrentUser() instead, which does
	 * that in one query.
	 */
	virtual GroupListPtr GetGroupsByUser(const std::string &userName) const = 0;

	/**
	 * Lists all GST registered Groups of the current user.
	 */
	virtual GroupListPtr GetGroupsByCurrentUser() const = 0;

	/**
	 * Assign a User a specific group by name.
	 */
	virtual void AddUserToGroup(const std::string &userName,
								const std::string &groupName)
		= 0;

	/**
	 * Deassign a User from a group. So the user is not a member anymore
	 */
	virtual void DropUserFromGroup(const std::string &userName,
								   const std::string &groupName)
		= 0;

	virtual void ChangeUserPassword(const std::string &userName,
									const std::string &newPassword,
									const std::string &oldPassword) const
		= 0;
	virtual void ChangeUserPasswordAsAdmin(const User &user,
										   const std::string &newPassword) const
		= 0;
	//@}

	///@name Version check
	//@{
	/**
	 * * Reads the version information from the db
	 */
	virtual Utils::GSTVersionPtr GetStorageVersion() const;

	/**
	 * Reads the revision number from connected backend. (result of
	 * gst.version())
	 */
	virtual std::string GetStorageRevision() const = 0;

	/**
	 *  @returns 1 (==true) if the backend is compatible with the specified
	 * client version.
	 */
	virtual int CheckCompatibility(const std::string &client_version) const = 0;

	/**
	 * Checks module availability on GST Storage
	 *
	 * Checks whether a valid license of the specified license string and
	 * version is available.
	 *
	 * @returns An error code that is 0 in case of success and not equal 0
	 * in case of an error.
	 *
	 * @param errorMessage provides some information about the error
	 * @param license valid values are "gst", "gst-workflow", "gst-section"
	 * @param version typically this is "2.0"
	 * @see CheckStorageModuleLicense for a wrapper
	 */
	virtual ServerLicenseListPtr CheckStorageLicense() = 0;
	//@}

	///@name SRS Handling
	//@{
	/**
	 * Inserts a new SRS into GST.	It also updates the id in the parameter
	 * new_srs.
	 * @returns The id of the new created SRS.
	 *
	 * @throws DuplicateName if the pair code_type:code is already existent
	 */
	virtual Geometry::GSTSRSRefPtr InsertSRS(Geometry::SRSItemVal &new_srs);

	/**
	  * Inserts a new SRS into GST and returns a ref to it. With it you can
	  create an SRS from various encodings. *		@param label		Name of
	  the created SRS *		@param code_type	A key type identifier *
	  @param code_value	A value for the key (should be a valid value for the
	  specified code_type).
	  *
		\code
		//This sample code creates a wgs reference system in GST, specifying a
	  label and the correct EPGS code. std::string wkt = "GEOGCS["WGS
	  84",DATUM["WGS_1984",SPHEROID["WGS
	  84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]";
		network->InsertSRS(*GST::Geometry::SRS::FromWKT(wkt), "WGS84", "EPSG",
	  "4326" ); \endcode
	  *
	  * More info about SRS Handling see Module \ref refSRS "Spatial Reference
	  Handling".
	  *
	  * @return The id of the new created SRS.
	  *
	  * @throws GST::exceptions::GSTRuntimeException If new_srs is of type NoSRS
	  or GSTSRSRef (not allowed, because they just refers to SRS's).
	  * @throws GST::exceptions::ViolateConvention If optional parameter
	  code_type is set, but code_value is empty.
	  * @throws DuplicateName if the pair code_type:code is already existent
	  *
	  * The following exception might be thrown by GST Storage call:
	  * @include GSTAPI_exceptions_create_srs.dox
	  */
	virtual Geometry::GSTSRSRefPtr InsertSRS(const Geometry::SRS &new_srs,
											 const std::string &label,
											 const std::string &code_type
											 = std::string(),
											 const std::string &code_value
											 = std::string())
		= 0;

	/**
	 * Updates an existing SRS of GST. (SRSItemVal.desc.id is used as key.)
	 * @throws DuplicateName if the pair code_type:code is already existent
	 */
	virtual void UpdateSRS(const Geometry::SRSItemVal &new_srs) = 0;

	/**
	 * Deletes an existing SRS from GST.
	 *
	 * @throws SRSStillInUseException if the SRS is still in use by a feature
	 * class (SRSStillInUseException::featureClassList contains the list of
	 * feature classes)
	 */
	virtual void DeleteSRS(const Geometry::GSTSRSRef &srsref) = 0;

	/**
	 * @returns A list of all SRS. This may take some time until the list can
	 * become large. List entries can be accessed by multi_index_map see
	 * SRSDescList.
	 */
	virtual Geometry::SRSItemDescListPtr ListAllSRS() const = 0;

	/**
	 * @brief	Gets srs detail by key.
	 *
	 * @return	The srs detail by key.
	 *
	 * @throws GST::exceptions::NotFound, if there is no entry found with
	 * srsKey
	 */
	virtual Geometry::SRSItemDescPtr GetSRSDetailByKey(long srsKey) const = 0;

	/**
	 * @brief	Returns the srs definition (including the PROJ4 encoding)
	 *
	 * @throws GST::exceptions::NotFound, if there is no entry found with
	 * srsKey
	 */
	virtual Geometry::SRSItemValPtr GetSRSDefinition(long srsKey) const = 0;

	/**
	 * Sets a SRS of the class fclass. (Requires that the feature class has no
	 * srs yet.)
	 *
	 * @throws GSTRuntimeException if no class matching the specified class
	 * without a SRS found or if a matching class already has a SRS.
	 */
	virtual void SetSRSForFeatureClass(const Geometry::GSTSRSRef &new_srs,
									   const FeatureClassDesc &fclass)
		= 0;

	/**
	 * Unsets the SRS of a given class.
	 */
	virtual void UnsetSRSForFeatureClass(const FeatureClassDesc &fclass) = 0;
	/**
	 * Sets a new SRS for the class fclass. (Requires that the feature class has
	 * a srs.)
	 *
	 * @throws GSTRuntimeException if no class matching the specified class with
	 * a SRS found or if a matching class has no SRS.
	 *
	 * @throws FeatureIsLocked if feature class has features that are locked
	 */
	virtual void ChangeSRSForFeatureClass(const Geometry::GSTSRSRef &new_srs,
										  const FeatureClassDesc &fclass,
										  bool transformExistingFeatures = true)
		= 0;

	/**
	 * Return the proj4 param for the given srs
	 */
	virtual std::string GetProj4ParamFromSRS(const Geometry::SRS &srs) const
		= 0;
	//@}

	///@name Services
	//@{
	/**
	 * @returns A list of all AccessLevels.
	 */
	virtual AccessLevelListPtr ListAccessLevels() const = 0;

	/**
	 * @returns accessLevel identified by accessLevelId
	 * @throws GST::exceptions::GSTInvalidArgument if there exists no
	 * accesslevel with this id
	 */
	virtual AccessLevelPtr GetAccessLevelById(long accessLevelId) const = 0;

	/**
	 * @returns A description of the newly created service information
	 * @throws GST::exceptions::GSTInvalidArgument if there exists no
	 * accesslevel with this id or if any of the other parameters is empty
	 */
	virtual ServiceDescriptionPtr CreateService(const std::string &name,
												const std::string &url,
												long accessLevelId,
												const std::string &user,
												const std::string &secret) const
		= 0;

	/**
	 * @returns The service information identified by serviceId
	 * @throws GST::exceptions::GSTInvalidArgument if there exists no service
	 * with this serviceId
	 */
	virtual ServiceDescriptionPtr GetServiceDescriptionById(
		long serviceId) const
		= 0;

	/**
	 * @brief Deletes the service identified by serviceId
	 */
	virtual void DropService(long serviceId) const = 0;

	/**
	 * @brief Updates information of a service
	 *
	 * Provide the following values to say that a particular parameter should
	 * not be updated:
	 * - Provide empty values (e.g. "" or std::string()) for the string
	 * parameters to *not* update the particular parameter.
	 * - Provide a negative value (e.g. -1) for accessLevelId to *not* update
	 * accessLevelId.
	 *
	 * @returns A description of the updated service information
	 * @throws GST::exceptions::GSTInvalidArgument if there exists no service
	 * with the serviceId
	 * @throws GST::exceptions::GSTInvalidArgument if accessLevelId >= 0 and
	 * there exists no accesslevel with this id
	 */
	virtual ServiceDescriptionPtr UpdateService(long serviceId,
												const std::string &name,
												const std::string &url,
												long accessLevelId,
												const std::string &user,
												const std::string &secret) const
		= 0;

	/**
	 * @returns A list of all services.
	 */
	virtual ServiceDescrionListPtr ListServices() const = 0;

	/**
	 * @returns A list of all services where accessLevel == accessLevelId
	 * @throws GST::exceptions::GSTInvalidArgument if there exists no
	 * accesslevel with this id
	 */
	virtual ServiceDescrionListPtr ListServicesByAccessLevel(
		long accessLevelId) const
		= 0;
	//@}

	///@name Product Version Handling
	//@{
	// virtual bool BackendIsGSTStorage() const = 0;
	//@}

	///@name Model Management
	//@{
	/**
	 * @returns A list of all children from parent that are visible for the
	 * logged in user. Children of type element also inherit the colorScales
	 * from parent
	 */
	virtual LinkAdjacencyListPtr GetChilds(LinkAdjacency::LinkId parent) const
		= 0;
	/**
	 * @returns A list of all link adjacencies which the logged in user has
	 * access rights to.
	 */
	virtual LinkAdjacencyListPtr GetAllLinkAdjacencies() const = 0;
	virtual LinkAdjacencyListPtr GetAllElementLinkAdjacencies() const = 0;
	virtual LinkAdjacencyListPtr GetAllFeatureLinkAdjacencies() const = 0;
	/**
	 * Sort nodes by an object property recursively.
	 */
	virtual LinkAdjacencyListPtr SortLinkAdjacenciesByObjectPropertyRecursively(
		LinkAdjacency::LinkId parent,
		const std::string &objectPropertyName,
		SortOrder sortOrder = SortOrder::Ascending) const
		= 0;

	/**
	 * Sort nodes by a dynamic color scale recursively.
	 */
	virtual LinkAdjacencyListPtr
	SortLinkAdjacenciesByDynamicColorScaleRecursively(
		LinkAdjacency::LinkId parent,
		const DynamicColorScale::ID dyncsId,
		SortOrder sortOrder = SortOrder::Ascending) const
		= 0;

	/**
	 * Set auto sort for nodes by an object property recursively.
	 *
	 * Note: requires admin connection!
	 */
	virtual AutoSortCriteria AutoSortLinkAdjacenciesByObjectPropertyRecursively(
		LinkAdjacency::LinkId parent,
		const std::string &objectPropertyName,
		SortOrder sortOrder = SortOrder::Ascending) const
		= 0;

	/**
	 * Set auto sort for nodes by a dynamic color scale recursively.
	 *
	 * Note: requires admin connection!
	 */
	virtual AutoSortCriteria
	AutoSortLinkAdjacenciesByDynamicColorScaleRecursively(
		LinkAdjacency::LinkId parent,
		const DynamicColorScale::ID dyncsId,
		SortOrder sortOrder = SortOrder::Ascending) const
		= 0;
	/**
	 * Removes a previously set auto sort option from the supplied node.
	 *
	 * Note: requires admin connection!
	 */
	virtual void RemoveAutoSortLinkAdjacencies(
		LinkAdjacency::LinkId parent) const
		= 0;
	/**
	 * @returns A list of all parents of the given feature that are visible for
	 * the logged in user.
	 *
	 */
	virtual LinkAdjacencyListPtr GetParentsForFeature(
		LinkAdjacency::LinkId featureId) const
		= 0;
	/**
	 * @returns A list of all (assignable) elements accessible for the logged in
	 * user.
	 */
	virtual AssignableElementListPtr GetElements() const = 0;
	/**
	 * @returns A list of all elements which the logged in user has access
	 * rights to.
	 */
	virtual ElementListPtr GetAllElements() const = 0;
	/**
	 * @returns A list of all users and groups for which the logged in user has
	 * access rights to.
	 */
	virtual OwnerListPtr GetOwners() const = 0;
	/**
	 * @returns A list of all user and groups available in GST.
	 */
	virtual OwnerListPtr GetAllOwners() const = 0;

	/**
	 * Add a MoMaProperty description to MoMaModel.
	 *
	 * @param name is the name of MoMaproperty
	 * @param dtype is the datatype of MoMaproperty
	 * @param owner is the id of the user or group is creating the property
	 *
	 * @returns created MoMaPropertyDesc
	 * @throws GSTDatamodelCorruption
	 */
	virtual MoMaPropertyDescPtr CreateMoMaPropertyDesc(
		const std::string &name,
		TableAttributeDesc::DType dtype,
		Owner::OwnerId owner) const
		= 0;

	/**
	 *
	 * @param propertyid is the id of MoMaproperty
	 *
	 * @returns MoMaPropertyDesc for given id
	 * @throws GSTDatamodelCorruption if no property with given id exists
	 */
	virtual MoMaPropertyDescPtr GetMoMaPropertyDesc(
		MoMaPropertyDesc::PROPERTYID propertyid) const
		= 0;
	/**
	 *
	 * @returns a list of MoMaPropertyDesc for connected user
	 *
	 */
	virtual MoMaPropertyDescListPtr ListMoMaPropertyDesc() const = 0;

	/**
	 * Update existing MoMaProperty with new property name
	 * @throws GSTDatamodelCorruption if no property with given id exists
	 *
	 */
	virtual void RenameMoMaPropertyDesc(
		const MoMaPropertyDesc::PROPERTYID propertyid,
		const std::string &newname) const
		= 0;
	/**
	 * Update existing MoMaProperty with new owner id
	 * @throws GSTDatamodelCorruption if no property with given id exists
	 *
	 */
	virtual void ChownMoMaPropertyDesc(
		const MoMaPropertyDesc::PROPERTYID propertyid,
		const long &newownerid) const
		= 0;

	/**
	 * Remove existing MoMaProperty from database
	 * @throws GSTDatamodelCorruption if no property with given id exists
	 *
	 */
	virtual void DeleteMoMaPropertyDesc(
		const MoMaPropertyDesc::PROPERTYID propertyid) const
		= 0;
	/**
	 * Create a MoMaPropertyValue for a given MoMaProperty description and a
	 * LinkedElement. Returned MoMaPropertyValuePtr is attached to element.
	 * @returns created MoMaPropertyValue
	 * @throws GSTRuntimeException if either linked element or MoMaProperty
	 * description doesn't exist
	 * @throws GSTRuntimeException if value can not be casted to datatype of the
	 * description
	 */
	virtual MoMaPropertyValuePtr CreateMoMaPropertyValue(
		LinkedElement &element,
		const MoMaPropertyDesc &desc,
		TableAttributeValPtr value) const
		= 0;
	/**
	 * Remove a MoMaPropertyValue from database.
	 * @throws GSTRuntimeException if  MoMaPropertyValue doesn't not exist
	 */
	virtual void DeleteMoMaPropertyValue(const MoMaPropertyValue &value) const
		= 0;

	/**
	 * Reset the value of a MoMaPropertyValue
	 * @throws GSTRuntimeException if either linked element or MoMaProperty
	 * description doesn't exist
	 * @throws GSTRuntimeException if value can not be casted to datatype of the
	 * description
	 */
	virtual void SetMoMaPropertyValue(MoMaPropertyValue &value,
									  const TableAttributeValPtr newvalue) const
		= 0;

	/**
	 *
	 * @returns a list of MoMaPropertyValues for a linked element inclusive its
	 * parent elements (model and/or unit)
	 * @throws GSTRuntimeException if linked element or MoMaProperty description
	 * doesn't exist
	 *
	 */
	virtual MoMaPropertyValueListPtr ListMoMaPropertyValues(
		const LinkedElement &element) const
		= 0;
	/**
	 *
	 * @returns a list of MoMaPropertyValues for a property description
	 * @throws GSTRuntimeException if MoMaProperty description for that id
	 * doesn't exist
	 *
	 */
	virtual MoMaPropertyValueListPtr ListMoMaPropertyValues(
		const MoMaPropertyDesc::PROPERTYID propertyid) const
		= 0;

	/**
	 * Creates a LinkAdjacency from the parameters (adding item to MoMa tree).
	 *
	 * @param parent is the link id of the parent in the MoMa tree
	 * @param refId can be an ElementId (Element::id) or a geometry id
	 * (FeatureDesc::geometryId) if the item you want to link (depending on
	 * refTarget)
	 * @param refTarget describing whether to link a Element or a Feature
	 * (meaning of refId)
	 * @param owner tells the owner of the item
	 *
	 * @returns The created LinkAdjacency
	 * @throws GSTRuntimeException if either parent or reference do not exist in
	 * the database
	 */
	virtual LinkAdjacencyPtr CreateLinkAdjacency(
		LinkAdjacency::LinkId parent,
		LinkAdjacency::ReferId refId,
		LinkAdjacency::TargetType refTarget,
		Owner::OwnerId owner) const
		= 0;
	/**
	 * Creates a LinkAdjacency with starting sibling rank.
	 *
	 * @param parent is the link id of the parent in the MoMa tree
	 * @param refId can be an ElementId (Element::id) or a geometry id
	 *        (FeatureDesc::geometryId) if the item you want to link
	 *        (depending on refTarget)
	 * @param refTarget describing whether to link a Element or a Feature
	 *        (meaning of refId)
	 * @param owner tells the owner of the item
	 * @param siblingRank the rank this node has between its siblings
	 *
	 * @returns The created LinkAdjacency
	 * @throws GSTRuntimeException if either parent or reference do not
	 *         exist in the database
	 */
	virtual LinkAdjacencyPtr CreateLinkAdjacency(
		LinkAdjacency::LinkId parent,
		LinkAdjacency::ReferId refId,
		LinkAdjacency::TargetType refTarget,
		Owner::OwnerId owner,
		int64_t siblingRank) const;
	/**
	 * Updates the sibling rank the link.
	 *
	 * @param linkId the link id of the link to update.
	 * @param newSiblingRank the new sibling rank of the link.
	 * @throws GSTInvalidArgument if link not found.
	 */
	virtual void UpdateLinkAdjacencySiblingRank(LinkAdjacency::LinkId linkId,
												int64_t newSiblingRank) const
		= 0;
	/**
	 * Drops the link with id linkId.
	 * @throws LinkHasChildren if the link to drop still has children.
	 */
	virtual void DropLinkAdjacency(LinkAdjacency::LinkId linkId) const = 0;
	/**
	 * Creates an element from the parameters.
	 * The id of the new Element will written into parameter Element.id.
	 * @param uniqueName if true, performs a pre check whether this name is in
	 * use
	 * @throws DuplicateName if uniqueName==true and name is in use
	 */
	virtual void CreateElement(ElementPtr Element,
							   bool uniqueName = false) const
		= 0;
	/**
	 * Renames an element. The Element->id is used to identify the element,
	 * which gets renamed. The new name is used from Element->label.
	 * @param uniqueName if true, performs a pre check whether this name is in
	 * use
	 * @throws DuplicateName if uniqueName==true and name is in use
	 */
	virtual void RenameElement(ElementPtr Element,
							   bool uniqueName = false) const
		= 0;
	/**
	 * Drops the element with id id.
	 * @pre Link must not be linked to anymore
	 * @throws NodeStillLinkedTo exception if the element still is linked to
	 */
	virtual void DropElement(Element::ElementId id) const = 0;
	/**
	 * Changes the owner of an element.
	 *
	 * @parameter newOwner The new owner of the element.
	 * @parameter newName  The new name of the element. Useful to
	 *                     prevent name conflicts. Optional. If supplied
	 *                     empty, keeps the current name.
	 * @throws GSTRuntimeException if the owner already owns an element
	 *         class with the same name
	 */
	virtual ElementPtr ChownElement(const Element &element,
									const Owner &newOwner,
									const std::string &newName
									= std::string()) const
		= 0;

	/**
	 * @returns A list of all color scales.
	 */
	virtual ColorScaleListPtr GetColorScales() const = 0;
	/**
	 * @returns A list of all color values to color scale with id colorscale.
	 */
	virtual ColorValueListPtr GetColorValues(
		ColorScale::ColorScaleId colorscale) const
		= 0;
	/**
	 * @returns The color value to link with id lId in the color scale with id
	 * cId
	 * @throws NotAssigned if a color value is not assigned for the given link
	 * and color scale
	 */
	virtual ColorValuePtr GetColorValue(LinkAdjacency::LinkId lId,
										ColorScale::ColorScaleId cId) const
		= 0;
	/**
	 * Writes the color scale cs to the database if cs->id == -1
	 * Updates the color scale if cs->id != -1
	 * @returns The id of the inserted color scale
	 */
	virtual ColorScale::ColorScaleId AddColorScale(ColorScalePtr cs) const = 0;
	/**
	 * Writes the color value cv to the database if cv->id == -1
	 * Updates the color value if cv->id != -1
	 * @returns The id of the inserted color value
	 */
	virtual ColorValue::ColorValueId AddColorValue(ColorValuePtr cv) const = 0;
	/**
	 * Deletes the colorscale with id csId.
	 */
	virtual void DeleteColorScale(ColorScale::ColorScaleId csId) const = 0;
	/**
	 * Deletes the colorvalue with id cvId.
	 */
	virtual void DeleteColorValue(ColorValue::ColorValueId cvId) const = 0;
	/**
	 * Assigns the colorscale with id csId to the link with id lId
	 * @throws ConstraintViolation if csId or lId don't refer to an actual
	 * colorscale or link respectively in the database.
	 */
	virtual void AssignColorScale(ColorScale::ColorScaleId csID,
								  Element::ElementId eId) const
		= 0;
	/**
	 * Assigns the colorvalue with id cvId to the element with id eId
	 * @throws ConstraintViolation if cvId or eId don't refer to an actual
	 * colorvalue or link respectively in the database.
	 */
	virtual void AssignColorValue(ColorValue::ColorValueId cvId,
								  LinkAdjacency::LinkId lId) const
		= 0;
	/**
	 * Unassigns the colorscale with id csId from the link with id lId
	 * @throws ConstraintViolation if csId or lId don't refer to an actual
	 * colorscale or link respectively in the database.
	 */
	virtual void UnAssignColorScale(ColorScale::ColorScaleId csID,
									Element::ElementId eId) const
		= 0;
	/**
	 * Unassigns the colorvalue with id cvId from the element with id eId
	 * @throws ConstraintViolation if cvId or eId don't refer to an actual
	 * colorvalue or link respectively in the database.
	 */
	virtual void UnAssignColorValue(ColorValue::ColorValueId cvId,
									LinkAdjacency::LinkId lId) const
		= 0;
	/**
	 * @return a list of features (featurelinkid, geometryid) that are childs of
	 *the rootElement (LinkId from MoMa item). If parameter csRootElement and
	 *csRootScale are passed, this list is filtered by assigned elements only in
	 *the specified scale.
	 *
	 *		@note	The csRootScale id has to be assigned to csRootElement item.
	 *csRootElement has to be the same as rootElement or some of it's parents.
	 *Otherwise an exception will be thrown.
	 *
	 */
	virtual FeatureLinkIdGeometryIdPairListPtr ResolveGeometries(
		LinkAdjacency::LinkId rootElement,
		LinkAdjacency::LinkId csRootElement = ROOT_NODE_LINKID,
		ColorScale::ColorScaleId csRootScale = -1) const
		= 0;
	/**
	 * @returns The desired feature class of a given geometry id.
	 */
	virtual FeatureClassDescPtr ResolveFeatureClassFromGeometryId(
		const long &geometryId) const
		= 0;
	/**
	  * Downloads a feature specified by MoMa link flid. The flid has to
	  reference a feature link id, e.g. by retrieving one from
	  ResolveGeometries().
	  * Otherwise an exceptions::GSTRuntimeException will be thrown.
	  *
	  *		@parameter ResolveGeometries	specifies the format
	  *		@parameter srs					specifies the spatial reference
	  encoding encoding (no conversion if it's the same than the srs of the
	  feature's feature class) *		@parameter csRootElement		a link
	  to a MoMa item that is a parent of flid and has an assigned color scale
	  (if set you need to set csRootScale, too). *		@parameter csRootScale
	  if csRootElement set, specify a scale that is assigned to csRootElement.
	  The downloaded feature gets coded in that scale. *		@parameter lock
	  if true the feature gets locked (see GetFeature(), UnlockByKey()) *
	  @parameter queryBox				downloads the feature only inside the
	  box  (see GetFeature())
	  */
	virtual CrudeFeaturePtr GetFeatureFromMoMa(
		LinkAdjacency::LinkId flid,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		LinkAdjacency::LinkId csRootElement = ROOT_NODE_LINKID,
		ColorScale::ColorScaleId csRootScale = -1,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1) const
		= 0;

	/**
	 * @brief	returns bbox of all features referenced by momakey in the
	 * 			SRS targetSrs.
	 *
	 * @param	momakey  	the key that references one or more features.
	 * @param	targetSrs	specifies the SRS of the resulting box.
	 *
	 * @return	The bounding box from moma.
	 *
	 * @see	MoMaKey
	 * @see	Geometry::SRS
	 *
	 * @details	if targetSrs is empty: uses the srs of the first feature
	 * 			found with the momakey and applies it to the rest.\n if
	 * 			targetSrs is defined: applies provided srs to all referenced
	 * 			features.
	 * @throws	GSTRuntimeException	if targetSrs was empty and not all
	 * 									feature srs were the same.
	 * @throws	GSTRuntimeException	   	if targetSrs was defined and one (or
	 * 									more) feature's srs was empty.
	 * @throws	GSTRuntimeException	   	if no feature was found for the
	 * 									given momakey.
	 */
	virtual QueryBoxPtr GetBboxFromMoma(const MoMaKey &momakey,
										Geometry::SRSPtr targetSrs) const
		= 0;

	/**
	 * @brief	returns bbox of feature in SRS targetSrs
	 *
	 * @param	fcDesc  	description of requested feature
	 * @param	targetSrs	specifies the SRS of the resulting box.
	 *
	 * @return	The bounding box from idgeo.
	 *
	 * @see	FeatureDesc
	 * @see	Geometry::SRS
	 *
	 * @throws	GSTRuntimeException	if targetSrs is set but feature has no
	 *          SRS information
	 */
	virtual GSTbox GetFeatureBboxTransformed(const FeatureDesc &fDesc,
											 Geometry::SRSPtr targetSrs) const
		= 0;

	/**
	 * Removes all(!) links of the geometry from Model Management no matter
	 * to which user this links belongs to.
	 *
	 * @note	This is an admin method. If you like to drop a geometry
	 *			link from the current user please use DropLinkAdjacency()
	 *			instead!
	 *
	 * @param	geometryId	idgeo of the geometry that shall be unlinked
	 *
	 * @pre		This must be an admin connection (isSuperUserConnection()
	 *			returns true)
	 *
	 * @throws	exceptions::InsufficientAccess if precondition not valid.
	 */
	virtual void ForceUnlinkGeometry(long geometryId) = 0;
	//@}

	///@name Dynamic Color Values
	//@{
	/**
	 * Generates a colorscale
	 *
	 * If dyncs.getId() points to a valid color scale id, the color scale
	 * including values getting updated (simply calling
	 * UpdateDynamicColorScale).
	 *
	 * If the dyncs.getId() points to DynamicColorScale::NewId (which is
	 * the default value set by DynamicColorScale's default constructor)
	 * a new color scale will be created and the new id will be set.
	 *
	 * @throws GSTRuntimeException if
	 *               1) the update failed due to an invalid id
	 *               2) the update failed to to an empty dyncs
	 *               3) the dyncs to insert is empty
	 *
	 * @note DynamicColorScaleCurator encapsulate the DynamicColorScales
	 * handling/fetching from NetworkInterface in a efficient way.
	 */
	virtual void CreateUpdateDynamicColorScale(DynamicColorScalePtr dyncs) = 0;

	/**
	 * Removes a dynamic color scale from the database.
	 *
	 * @throws GSTRuntimeException if the dyncs_id is an unknown id
	 *
	 * @note DynamicColorScaleCurator encapsulate the DynamicColorScales
	 * handling/fetching from NetworkInterface in a efficient way.
	 */
	virtual void DropDynamicColorScale(const DynamicColorScale::ID &dyncs_id)
		= 0;

	/**
	 * Returns a list with all dynamic color scales. The returned color scales
	 * are empty. If you want to obtain the values from a certain scale use
	 * GetDynamicColorScale() the the certain id.
	 *
	 * @note DynamicColorScaleCurator encapsulate the DynamicColorScales
	 * handling/fetching from NetworkInterface in a efficient way.
	 */
	virtual DynamicColorScaleListPtr ListDynamicColorScales() const = 0;

	/**
	 * Loads DyanmicColorValue's by a color scale id
	 * (Use this method to fetch a DynamicColorScale from a list returend by
	 * ListDynamicColorScales() )
	 *
	 * @note DynamicColorScaleCurator encapsulate the DynamicColorScales
	 * handling/fetching from NetworkInterface in a efficient way.
	 */
	virtual DynamicColorScalePtr GetDynamicColorScale(
		const DynamicColorScale::ID &dyncs_id) const
		= 0;
	//@}

	///@name Versioning
	//@{
	/**
	 * Creates a new CommitKey with supplied commit message
	 *
	 *		@returns the newly created CommitKey
	 *		@parameter message				commit message
	 */
	virtual long BeginCommit(const std::string &message) const = 0;
	/**
	 * Finalizes the commit with key commitKey
	 *
	 *		@returns error code from db if any. (0 for no error, error code < 0
	 *for error)
	 *		@parameter commitKey			commit to finish
	 */
	virtual int EndCommit(long commitKey) const = 0;
	/**
	 * Retrieves a list of the current commits
	 *
	 *		@returns pointer to the commit list
	 */
	virtual CommitListPtr ListCommits() const = 0;
	/**
	 *  Retrieves a list of the commits that changed the current feature.
	 */
	virtual CommitListPtr ListCommitsByFeature(long geometryId) = 0;
	/**
	 * Retrieves the list of CommitVersions specified by key
	 * Each CommitVersion has information about the version of a geometry that
	 *got changed by the commit
	 *
	 *		@returns pointer to the CommitVersion list
	 *		@parameter key				key of the commit
	 *		@throws GSTRuntimeException if there is not commit for the key
	 */
	virtual CommitVersionListPtr ShowCommit(Commit::CommitKey key) const = 0;
	/**
	 * Edit the message of an existing commit
	 *
	 *		@parameter key		the commit key
	 *		@parameter message	the new commit message
	 */
	virtual void EditCommitMessage(const Commit::CommitKey key,
								   const std::string &message) const
		= 0;
	//@}

	///@name Slices/Sections
	//@{

	/**
	 * @brief	Saves the borehole image resulting from the intersection of the
	 * 			features selected by momakey with the feature from
	 * 			intersectionGeometry.
	 *
	 * @param	boreholeParams   	defines intersection specific input
	 * 								parameters.
	 * @param	outputImageParams	defines parameters of the resulting image.
	 *
	 * @return	IntersectionInfoPtr info of result
	 *
	 * @see		BoreHoleImageParameters for further information
	 * @see		OutputImageParameters for further information
	 * @see     IntersectionInfo
	 *
	 * @throws	GSTRuntimeException	on error.
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_virtualBorderhole.dox
	 */
	virtual IntersectionInfoPtr SaveBoreholeImage(
		const BoreHoleImageParameters &boreholeParams,
		const OutputImageParameters &outputImageParams) const
		= 0;

	/**
	 * @brief	Saves the section image resulting from the intersection of the
	 * 			features selected by momakey with the feature from
	 * 			intersectionGeometry.
	 *
	 * @param	sectionParams	 	defines intersection specific input
	 * 								parameters.
	 * @param	outputImageParams	defines parameters of the resulting image.
	 *
	 * @return	IntersectionInfoPtr info of result
	 *
	 * @see		SectionImageParameters for further information
	 * @see		OutputImageParameters for further information
	 * @see     IntersectionInfo
	 *
	 * @throws	GSTRuntimeException	on error.

	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_crossSection.dox
	 */
	virtual IntersectionInfoPtr SaveSectionImage(
		const SectionImageParameters &sectionParams,
		const OutputImageParameters &outputImageParams) const
		= 0;

	/**
	 * @brief	Saves the map image resulting from the intersection of the
	 * 			features selected by momakey with the feature from
	 * 			intersectionGeometry.
	 *
	 * @param	mapParams		 	defines intersection specific input
	 * 								parameters.
	 * @param	outputImageParams	defines parameters of the resulting image.
	 *
	 * @return	IntersectionInfoPtr info of result
	 *
	 * @see		MapImageParameters for further information
	 * @see		OutputImageParameters for further information
	 * @see     IntersectionInfo
	 *
	 * @throws	GSTRuntimeException	on error.
	 *
	 * The following exception might be thrown by GST Storage call:
	 * @include GSTAPI_exceptions_horizontalSection.dox
	 */
	virtual IntersectionInfoPtr SaveMapImage(
		const MapImageParameters &mapParams,
		const OutputImageParameters &outputImageParams) const
		= 0;
	/**
	 * @brief	Saves the correlation plot image of the selected boreholes
	 *          queried from the borehole service.
	 *
	 * @param	params		 	    correlation plot input parameters.
	 * @param	outputImageParams	defines parameters of the resulting image.
	 *
	 * @return	IntersectionInfoPtr info of result
	 *
	 * @see		CorrelationPlotParameters for further information
	 * @see		OutputImageParameters for further information
	 * @see     IntersectionInfo
	 *
	 * @throws	GSTRuntimeException	on error.
	 */
	virtual IntersectionInfoPtr SaveCorrelationPlotImage(
		const CorrelationPlotParameters &params,
		const OutputImageParameters &outputImageParams) const
		= 0;

	virtual std::string SaveBoreholeAsShapefileZip(
		const BoreHoleImageParameters &boreholeParams,
		const OutputShapeParameters &outputShapeParams) const
		= 0;
	virtual std::string SaveSectionAsShapefileZip(
		const SectionImageParameters &sectionParams,
		const OutputShapeParameters &outputShapeParams) const
		= 0;
	virtual std::string SaveMapAsShapefileZip(
		const MapImageParameters &mapParams,
		const OutputShapeParameters &outputShapeParams) const
		= 0;
	virtual std::string SaveCorrelationPlotAsShapefileZip(
		const CorrelationPlotParameters &params,
		const OutputShapeParameters &outputShapeParams) const
		= 0;

	virtual IntersectionInfoPtr SaveBoreholeGridImage(
		const BoreholeGridImageParameters &boreholeParams,
		const OutputImageParameters &outputImageParams) const
		= 0;
	virtual IntersectionInfoPtr SaveSectionGridImage(
		const SectionGridImageParameters &sectionParams,
		const OutputImageParameters &outputImageParams) const
		= 0;
	virtual IntersectionInfoPtr SaveMapGridImage(
		const MapGridImageParameters &mapParams,
		const OutputImageParameters &outputImageParams) const
		= 0;

	/**
	 * Create a Colormap in GST Storage. (Used e.g. by simplex property value
	 * coloring in section images). A valid color scale has at least
	 * segments.size() >= 2.
	 * @returns the key of the new created map
	 */
	virtual ColorMap::Id CreateColorMap(
		const std::string &name,
		const ColorMapSegmentList &segments,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false)
		= 0;

	virtual ColorMap::Id CreateDiscreteColorMap(
		const std::string &name,
		const ColorMapDiscreteValueList &values,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false)
		= 0;

	virtual ColorMap::Id CreateConstrainedColorMap(
		const std::string &name,
		const ConstrainedColorValueDesc &constrainedDesc,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false)
		= 0;

	/**
	 * Updates a Colormap by id. Updates all given arguments (name, segments,
	 * nodataColor, nodataValue).
	 */
	virtual void UpdateColorMap(const ColorMap::Id &id,
								const std::string &name,
								const ColorMapSegmentList &segments,
								const Geometry::IGeometry::Color &nodataColor,
								const std::string &regex,
								long accessLevelId,
								bool nodataTransparentForGrids = false)
		= 0;

	virtual void UpdateDiscreteColorMap(
		const ColorMap::Id &id,
		const std::string &name,
		const ColorMapDiscreteValueList &values,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false)
		= 0;

	virtual void UpdateConstrainedColorMap(
		const ColorMap::Id &id,
		const std::string &name,
		const ConstrainedColorValueDesc &constrainedDesc,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false)
		= 0;

	/**
	 * Deletes a Colormap by id.
	 */
	virtual void DeleteColorMap(const ColorMap::Id &id) = 0;

	/**
	 * @returns a list of all available Colormaps. The list contains (map,
	 * key)-pairs.
	 * @see GetColorMap() to get ful info about a map
	 */
	virtual ColorMapDescListPtr ListColorMaps() const = 0;

	/**
	 * @returns a detailed colormap. given a key the colormap is loaded
	 * including segments
	 */
	virtual ColorMapPtr GetColorMap(const ColorMap::Id &id) const = 0;
	//@}

	// color schemes
	virtual ColorSchemePtr CreateContinuousColorScheme(
		const std::string &name,
		const std::vector<ContinuousColorSchemeValue> &values) const
		= 0;
	virtual ColorSchemePtr CreateDiscreteColorScheme(
		const std::string &name,
		const std::vector<Utils::ColorRGB> &values) const
		= 0;
	virtual ColorSchemePtr UpdateContinuousColorScheme(
		int64_t id,
		const std::string &name,
		const std::vector<ContinuousColorSchemeValue> &values) const
		= 0;
	virtual ColorSchemePtr UpdateDiscreteColorScheme(
		int64_t id,
		const std::string &name,
		const std::vector<Utils::ColorRGB> &values) const
		= 0;
	virtual void DeleteColorScheme(int64_t id) const = 0;
	virtual ColorSchemePtr GetColorScheme(int64_t id) const = 0;
	virtual ColorSchemeList ListColorSchemes() const = 0;

	///@name LOD Handling
	//@{
	/**
	 *	@returns all direct LODs of the feature
	 */
	virtual AssignableFeatureDescListPtr GetLODs(
		const FeatureDesc &feature) const
		= 0;
	/**
	 *	Adds a level of details connection from fineLevel to parentLevel.
	 * @throws GSTRuntimeException if the connection still exists
	 */
	virtual void AddLOD(const FeatureDesc &parentLevel,
						const FeatureDesc &fineLevel)
		= 0;
	/**
	 *	Drops the level of details connection between fineLevel to parentLevel.
	 * @throws GSTRuntimeException if the is no LOD connection between
	 *parentLevel and fineLevel
	 */
	virtual void RemoveLOD(const FeatureDesc &parentLevel,
						   const FeatureDesc &fineLevel)
		= 0;
	//@}

	virtual void CreateRtreeIndex(long idgeo) const = 0;
	virtual bool HasRtreeIndex(long idgeo) const = 0;
	virtual void DropRtreeIndex(long idgeo) const = 0;
	virtual PropertyAliasPtr GetObjectPropertyAlias(
		const ObjectPropertyDesc &opDesc) const
		= 0;
	virtual PropertyAliasPtr GetSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc) const
		= 0;
	virtual void CreateUpdateObjectPropertyAlias(
		const ObjectPropertyDesc &opDesc,
		const std::map<int, PropertyAliasPtr> &propertyAlias) const
		= 0;
	virtual void CreateUpdateSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc,
		const std::map<int, PropertyAliasPtr> &propertyAlias) const
		= 0;
	virtual void DropObjectPropertyAlias(const ObjectPropertyDesc &opDesc) const
		= 0;
	virtual void DropSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc) const
		= 0;
	virtual void DropConstrainedColumnAlias(long mappedColumnId) const = 0;
	virtual PropertyAliasMapPtr GetObjectPropertyAliasList(
		const FeatureClassDesc &featureClass) const
		= 0;
	virtual PropertyAliasMapBySubFeatureKind GetSubKindObjectPropertyAliasList(
		const FeatureClassDesc &featureClass) const
		= 0;
	virtual PropertyAliasMapPtr GetSimplexPropertyAliasList(
		const FeatureClassDesc &featureClass) const
		= 0;
	virtual PropertyAliasMapBySubFeatureKind GetSubKindSimplexPropertyAliasList(
		const FeatureClassDesc &featureClass) const
		= 0;

	///@name web user handling
	virtual void createWebUser(const std::string &name,
							   const std::string &secret,
							   const std::string &linkedGstUser,
							   long accesslevel,
							   const std::string &allowedActionsJson) const
		= 0;
	virtual void updateWebUser(const std::string &oldName,
							   const std::string &newName,
							   const std::string &newPassword,
							   const std::string &newLinkedGstUser,
							   long newAccessLevel,
							   const std::string &allowedActionsJson) const
		= 0;
	virtual void dropWebUser(const std::string &) const = 0;
	virtual WebuserDescListPtr listWebUsers() const = 0;
	virtual void changeWebUserPassword(const std::string &currentPassword,
									   const std::string &newPassword) const
		= 0;

	///@name Geometry hulls
	//@{
	/**
	 * @brief	get the geometry hull as geojson
	 * @param	idgeo the id of the geometry
	 * @returns	the geometry hull as geojson
	 */
	virtual std::string getLatestGeoJSONHullGeometry(const long &idgeo) const
		= 0;
	/**
	 * @brief	delete the geometry hull
	 * @param	idgeo the id of the geometry
	 */
	virtual void deleteLatestGeometryHull(const long &idgeo) const = 0;
	/**
	 * @brief	calculate the geometry hull
	 * @param	idgeo the id of the geometry
	 * @returns	the id of the geometry hull
	 */
	virtual long calculateConcaveHull(const long &idgeo) const = 0;
	/**
	 * @brief	upload a custom geometry hull
	 * @details	this currently supports only line type formats. We use the
	 *			first linestring found and and close it to a polygon if not
	 *			already closed.
	 * @param	file_path the path where the file resides
	 * @param	file_name the name of the file
	 * @param	file_type the type of the file
	 * @param	idgeo the id of the geometry
	 * @returns	the id of the geometry hull
	 */
	virtual long uploadLatestHullForGeometry(
		const std::string &file_path,
		const std::string &file_name,
		const Geometry::IFileSerialisable::FileType &file_type,
		const long &idgeo) const
		= 0;
	/**
	 * @brief	checks existence a geometry hull
	 * @param	idgeo the id of the geometry
	 */
	virtual bool hasGeometryHull(const long &idgeo) const = 0;
	//@}

	// query filter
	virtual QueryFilterSummaryList listQueryFilterSummaries() const = 0;
	virtual QueryFilter getQueryFilter(int64_t id) const = 0;
	virtual QueryFilter createQueryFilter(NewQueryFilter queryFilter) const = 0;
	virtual QueryFilter updateQueryFilter(int64_t id,
										  NewQueryFilter queryFilter) const
		= 0;
	virtual void deleteQueryFilter(int64_t id) const = 0;
	virtual std::vector<long> applySpatialFilter(
		const std::vector<long> &idgeos,
		const AreaLimiter &spatialFilter) const
		= 0;

	// profile download
	virtual std::string ProfileDownloadShape(
		const ProfileDownloadParameters &profileDownloadParameters,
		const OutputShapeParameters &outputShapeParameters)
		= 0;

	// access rights
	virtual void grantAccessRightOnFeatureClass(const FeatureClassDesc &item,
												const Owner &owner,
												AccessRight accessRight) const
		= 0;
	virtual void revokeAccessRightFromFeatureClass(const FeatureClassDesc &item,
												   const Owner &owner) const
		= 0;
	virtual std::vector<AssignedAccessRight> listAccessRightsOfFeatureClass(
		const FeatureClassDesc &item) const
		= 0;
	virtual void grantAccessRightOnElement(const Element &item,
										   const Owner &owner,
										   AccessRight accessRight) const
		= 0;
	virtual void revokeAccessRightFromElement(const Element &item,
											  const Owner &owner) const
		= 0;
	virtual std::vector<AssignedAccessRight> listAccessRightsOfElement(
		const Element &item) const
		= 0;
	virtual void grantAccessRightOnMoMaProperty(const MoMaPropertyDesc &item,
												const Owner &owner,
												AccessRight accessRight) const
		= 0;
	virtual void revokeAccessRightFromMoMaProperty(const MoMaPropertyDesc &item,
												   const Owner &owner) const
		= 0;
	virtual std::vector<AssignedAccessRight> listAccessRightsOfMoMaProperty(
		const MoMaPropertyDesc &item) const
		= 0;

#ifdef generate_with_GSTR
	/**
	 * @brief	get the GRPC/GST3 interface, which has different function
	 * available
	 * @returns a shared_ptr to the GRPC Access interface
	 */
	GRPCAccess *getGRPCAccess();
#endif

#ifdef WITH_GST_TESTS
	struct Params
	{
		int p_int32;
		long p_int64;
		float p_float4;
		double p_float8;
		std::string p_varchar;
		std::string p_text;
		std::vector<unsigned char> p_binary;
	};
	virtual void test_sproc(const Params &in, Params &out) const = 0;

#endif // WITH_GST_TESTS

protected:
	///@name progressAccessors
	//@{
	void ResetProgress();
	void OnePartFinished(int partsWeight = 1);
	//@}

	/**
	 * Creates a feature class.
	 */
	virtual void CreateFeatureClass_Impl(
		const FeatureClassDetailedDesc &featureClassDesc)
		= 0;

	/**
	 * Checks if GST Storage backed is above or equal the given version
	 * (minimalRequiredVersion). If this is not true this methods throws an
	 * exceptions::BackendAboveOrEqualRequired exception.
	 */
	void MethodRequiresBackendVersion(
		const Utils::GSTVersion &minimalRequiredVersion,
		const std::string &missingFunctionalityText = std::string()) const;
};

} // namespace ClientUtils
} // namespace GST

#endif /* _NETWORK_INTERFACE_H_ */
