/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/
#ifndef mitkIPersistenceService_h
#define mitkIPersistenceService_h

// mitk
#include <mitkPropertyListReplacedObserver.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <usServiceReference.h>
// for microservices
#include <mitkDataStorage.h>
#include <mitkServiceInterface.h>

namespace mitk
{
  /**
   * \ingroup MicroServices_Interfaces
   *
   * \brief The central service for the persistence module.
   *
   * Basic idea is to create PropertyLists with a unique id using GetPropertyList(). A consumer
   * of this interface can write arbitrary information into this PropertyList.
   * Calling Save() and Load() will cause the service to save and load the current set of PropertyLists from
   * a file in the user directory.
   * Using SetAutoLoadAndSave(true) will cause the service to load/save the PropertyLists at application
   * start/stop.
   * Moreover, depending on the backend type, the service is connected to the SceneSerialization module, i.e.
   * the user will be asked whether to save/load the PropertyLists in/from the current ".mitk" file that is selected
   * by the user.
   *
   * \sa PropertyList
   * \sa PropertyListReplacedObserver
   */
  class MITKCORE_EXPORT IPersistenceService
  {
  public:
    /**
     * \brief Get or create a PropertyList with the given id.
     *
     * If a PropertyList with the given id exists, returns it. Otherwise creates a new one and returns it.
     * If id is empty, a UUID will be created and set on the variable.
     * If existed was passed, it is set to \c true if the PropertyList with that id existed, \c false otherwise.
     *
     * \param id The unique identifier for the PropertyList. May be modified if empty.
     * \param existed Optional output parameter indicating whether the PropertyList already existed.
     * \return A valid PropertyList with a StringProperty "Id" containing the passed id.
     */
    virtual mitk::PropertyList::Pointer GetPropertyList(std::string &id, bool *existed = nullptr) = 0;

    /**
     * \brief Remove the PropertyList with the given id.
     *
     * \param id The identifier of the PropertyList to remove.
     * \return \c true if the PropertyList existed and could be removed, \c false otherwise.
     */
    virtual bool RemovePropertyList(std::string &id) = 0;

    /**
     * \brief Get the default name of the persistence file (the one that is loaded at startup).
     *
     * \return The default persistence file path.
     */
    virtual std::string GetDefaultPersistenceFile() = 0;

    /**
     * \brief Get the name of the BoolProperty that marks persistence DataNodes.
     *
     * \return The property name string.
     */
    virtual std::string GetPersistenceNodePropertyName() = 0;

    /**
     * \brief Create DataNodes containing all PropertyLists.
     *
     * The DataNodes will have the property name set to the PropertyList's id and a BoolProperty equal to
     * GetPersistenceNodePropertyName() set to \c true. If \p ds is set, the returned DataNodes will also
     * be added to that DataStorage.
     *
     * \param ds Optional DataStorage to add the nodes to.
     * \return A set of DataNodes with the described attributes.
     */
    virtual DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage *ds = nullptr) = 0;

    /**
     * \brief Restore PropertyLists from persistent DataNodes in the given storage.
     *
     * Searches the storage for persistent DataNodes, extracts and inserts the appended
     * PropertyLists to this service.
     *
     * \param storage The DataStorage to search for persistent DataNodes.
     * \return \c true if at least one node was found from which a PropertyList could be restored.
     */
    virtual bool RestorePropertyListsFromPersistentDataNodes(const DataStorage *storage) = 0;

    /**
     * \brief Save the current PropertyLists to a file.
     *
     * If \p fileName is empty, a special file in the user's home directory will be used.
     * If \p appendChanges is \c true, the file will not be replaced but first loaded, then
     * overwritten and then replaced.
     *
     * \param fileName The file path to save to. Empty for the default location.
     * \param appendChanges If \c true, merge changes with the existing file contents.
     * \return \c false if an error occurred (cannot write to file), \c true otherwise.
     */
    virtual bool Save(const std::string &fileName = "", bool appendChanges = false) = 0;

    /**
     * \brief Load PropertyLists from a file.
     *
     * If \p fileName is empty, a special file in the user's home directory will be used.
     * If \p enforeReload is \c false, the service will take care of modified time flags, i.e. it will not load a file
     * that was loaded before and did not change in the meantime or that was modified by the service itself.
     *
     * \warning If there are PropertyLists with the same id contained in the file, existing PropertyLists will be
     * overwritten!
     *
     * \param fileName The file path to load from. Empty for the default location.
     * \param enforeReload If \c true, reload regardless of modification timestamps.
     * \return \c false if an error occurred (cannot load from file), \c true otherwise.
     *
     * \sa AddPropertyListReplacedObserver()
     */
    virtual bool Load(const std::string &fileName = "", bool enforeReload = true) = 0;

    /**
     * \brief Enable or disable automatic loading/saving of PropertyLists at application start/stop.
     *
     * \param autoLoadAndSave If \c true, enable automatic load and save.
     */
    virtual void SetAutoLoadAndSave(bool autoLoadAndSave) = 0;

    /**
     * \brief Check whether automatic loading/saving is activated.
     *
     * \return \c true if auto-load and auto-save are enabled, \c false otherwise.
     */
    virtual bool GetAutoLoadAndSave() = 0;

    /**
     * \brief Add an observer that is notified when a PropertyList is replaced during Load().
     *
     * \param observer The observer to add.
     */
    virtual void AddPropertyListReplacedObserver(PropertyListReplacedObserver *observer) = 0;

    /**
     * \brief Remove a previously added PropertyList replacement observer.
     *
     * \param observer The observer to remove.
     */
    virtual void RemovePropertyListReplacedObserver(PropertyListReplacedObserver *observer) = 0;

    /** \brief Destructor. */
    virtual ~IPersistenceService();
  };
}

// MACROS FOR AUTOMATIC SAVE FUNCTION
#define PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION us::GetModuleContext()

#define PERSISTENCE_GET_SERVICE_MACRO                                                                                  \
  mitk::IPersistenceService *persistenceService = 0;                                                                   \
  us::ModuleContext *context = PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION;                                                \
  if (context)                                                                                                         \
  {                                                                                                                    \
    us::ServiceReference<mitk::IPersistenceService> persistenceServiceRef =                                            \
      context->GetServiceReference<mitk::IPersistenceService>();                                                       \
    if (persistenceServiceRef)                                                                                         \
    {                                                                                                                  \
      persistenceService = dynamic_cast<mitk::IPersistenceService *>(                                                  \
        context->GetService<mitk::IPersistenceService>(persistenceServiceRef));                                        \
    }                                                                                                                  \
  }

#define PERSISTENCE_GET_SERVICE_METHOD_MACRO                                                                           \
  mitk::IPersistenceService *GetPersistenceService() const                                                             \
  {                                                                                                                    \
    PERSISTENCE_GET_SERVICE_MACRO                                                                                      \
    return persistenceService;                                                                                         \
  }

#define PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                   \
                                                                                                                       \
public:                                                                                                                \
  bool Save(const std::string &fileName = "", bool appendChanges = false)                                              \
  {                                                                                                                    \
    mitk::IPersistenceService *persistenceService = this->GetPersistenceService();                                     \
    bool noError = persistenceService != 0;                                                                            \
    if (noError)                                                                                                       \
      this->ToPropertyList();                                                                                          \
    if (noError)                                                                                                       \
      noError = persistenceService->Save(fileName, appendChanges);                                                     \
    return noError;                                                                                                    \
  }                                                                                                                    \
  bool Load(const std::string &fileName = "", bool enforeReload = true)                                                \
  {                                                                                                                    \
    mitk::IPersistenceService *persistenceService = this->GetPersistenceService();                                     \
    bool noError = persistenceService != 0 && persistenceService->Load(fileName, enforeReload);                        \
    if (noError)                                                                                                       \
    {                                                                                                                  \
      this->FromPropertyList();                                                                                        \
    }                                                                                                                  \
    return noError;                                                                                                    \
  }                                                                                                                    \
  void ToPropertyList()                                                                                                \
  {                                                                                                                    \
    mitk::IPersistenceService *persistenceService = this->GetPersistenceService();                                     \
    this->InitializePropertyListReplacedObserver(persistenceService);                                                  \
    if (!persistenceService)                                                                                           \
      return;                                                                                                          \
    mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME);

#define PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                  \
  }                                                                                                                    \
  void FromPropertyList()                                                                                              \
  {                                                                                                                    \
    mitk::IPersistenceService *persistenceService = this->GetPersistenceService();                                     \
    this->InitializePropertyListReplacedObserver(persistenceService);                                                  \
    if (!persistenceService)                                                                                           \
      return;                                                                                                          \
    mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME);

#define PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)                                                     \
  }                                                                                                                    \
                                                                                                                       \
  std::string GetId() const { return ID_MEMBER_NAME; }                                                                 \
private:                                                                                                               \
  PERSISTENCE_GET_SERVICE_METHOD_MACRO                                                                                 \
  struct MyPropertyListReplacedObserver : public mitk::PropertyListReplacedObserver                                    \
  {                                                                                                                    \
    MyPropertyListReplacedObserver() : m_##THE_CLASS_NAME(0), m_PersistenceService(0) {}                               \
    ~MyPropertyListReplacedObserver()                                                                                  \
    {                                                                                                                  \
      if (m_PersistenceService)                                                                                        \
        m_PersistenceService->RemovePropertyListReplacedObserver(this);                                                \
    }                                                                                                                  \
    void AfterPropertyListReplaced(const std::string &id, mitk::PropertyList *)                            \
    {                                                                                                                  \
      if (m_##THE_CLASS_NAME && m_##THE_CLASS_NAME->GetId() == id)                                                     \
        m_##THE_CLASS_NAME->FromPropertyList();                                                                        \
    }                                                                                                                  \
    void Initialize(THE_CLASS_NAME *_##THE_CLASS_NAME, mitk::IPersistenceService *persistenceService)                  \
    {                                                                                                                  \
      m_##THE_CLASS_NAME = _##THE_CLASS_NAME;                                                                          \
      m_PersistenceService = persistenceService;                                                                       \
      if (m_PersistenceService)                                                                                        \
        m_PersistenceService->AddPropertyListReplacedObserver(this);                                                   \
    }                                                                                                                  \
                                                                                                                       \
  private:                                                                                                             \
    THE_CLASS_NAME *m_##THE_CLASS_NAME;                                                                                \
    mitk::IPersistenceService *m_PersistenceService;                                                                   \
  };                                                                                                                   \
  MyPropertyListReplacedObserver m_MyPropertyListReplacedObserver;                                                     \
  void InitializePropertyListReplacedObserver(mitk::IPersistenceService *persistenceService)                           \
  {                                                                                                                    \
    static bool observerInitialized = false;                                                                           \
    if (observerInitialized == false && persistenceService)                                                            \
    {                                                                                                                  \
      m_MyPropertyListReplacedObserver.Initialize(this, persistenceService);                                           \
      observerInitialized = true;                                                                                      \
    }                                                                                                                  \
  }

#define PERSISTENCE_CREATE(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME)                                          \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE2(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME)                     \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE3(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME) \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE4(                                                                                           \
  THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME)       \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Set(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Get(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE5(THE_CLASS_NAME,                                                                            \
                            ID_MEMBER_NAME,                                                                            \
                            PARAM_MEMBER_NAME,                                                                         \
                            PARAM2_MEMBER_NAME,                                                                        \
                            PARAM3_MEMBER_NAME,                                                                        \
                            PARAM4_MEMBER_NAME,                                                                        \
                            PARAM5_MEMBER_NAME)                                                                        \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Set(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Set(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Get(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Get(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE6(THE_CLASS_NAME,                                                                            \
                            ID_MEMBER_NAME,                                                                            \
                            PARAM_MEMBER_NAME,                                                                         \
                            PARAM2_MEMBER_NAME,                                                                        \
                            PARAM3_MEMBER_NAME,                                                                        \
                            PARAM4_MEMBER_NAME,                                                                        \
                            PARAM5_MEMBER_NAME,                                                                        \
                            PARAM6_MEMBER_NAME)                                                                        \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Set(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Set(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Set(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Get(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Get(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Get(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE7(THE_CLASS_NAME,                                                                            \
                            ID_MEMBER_NAME,                                                                            \
                            PARAM_MEMBER_NAME,                                                                         \
                            PARAM2_MEMBER_NAME,                                                                        \
                            PARAM3_MEMBER_NAME,                                                                        \
                            PARAM4_MEMBER_NAME,                                                                        \
                            PARAM5_MEMBER_NAME,                                                                        \
                            PARAM6_MEMBER_NAME,                                                                        \
                            PARAM7_MEMBER_NAME)                                                                        \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Set(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Set(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Set(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  propList->Set(#PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Get(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Get(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Get(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  propList->Get(#PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

#define PERSISTENCE_CREATE8(THE_CLASS_NAME,                                                                            \
                            ID_MEMBER_NAME,                                                                            \
                            PARAM_MEMBER_NAME,                                                                         \
                            PARAM2_MEMBER_NAME,                                                                        \
                            PARAM3_MEMBER_NAME,                                                                        \
                            PARAM4_MEMBER_NAME,                                                                        \
                            PARAM5_MEMBER_NAME,                                                                        \
                            PARAM6_MEMBER_NAME,                                                                        \
                            PARAM7_MEMBER_NAME,                                                                        \
                            PARAM8_MEMBER_NAME)                                                                        \
  PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)                                                                         \
  propList->Set(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Set(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Set(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Set(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Set(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Set(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  propList->Set(#PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME);                                                              \
  propList->Set(#PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)                                                                        \
  propList->Get(#PARAM_MEMBER_NAME, PARAM_MEMBER_NAME);                                                                \
  propList->Get(#PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME);                                                              \
  propList->Get(#PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME);                                                              \
  propList->Get(#PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME);                                                              \
  propList->Get(#PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME);                                                              \
  propList->Get(#PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME);                                                              \
  propList->Get(#PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME);                                                              \
  propList->Get(#PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME);                                                              \
  PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)

MITK_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService")

#endif
