diff --git a/source/Lib/CommonLib/ParameterSetManager.cpp b/source/Lib/CommonLib/ParameterSetManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1760f7dec2964fc160f556e327d7888e2784a75
--- /dev/null
+++ b/source/Lib/CommonLib/ParameterSetManager.cpp
@@ -0,0 +1,230 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2020, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "CommonDef.h"
+#include "ParameterSetManager.h"
+
+ParameterSetManager::ParameterSetManager()
+: m_spsMap(MAX_NUM_SPS)
+, m_ppsMap(MAX_NUM_PPS)
+, m_apsMap(MAX_NUM_APS * MAX_NUM_APS_TYPE)
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+, m_dpsMap(MAX_NUM_DPS)
+#endif
+, m_vpsMap(MAX_NUM_VPS)
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+, m_activeDPSId(-1)
+#endif
+, m_activeSPSId(-1)
+, m_activeVPSId(-1)
+{
+}
+
+
+ParameterSetManager::~ParameterSetManager()
+{
+}
+
+// activate a PPS and depending on isIRAP parameter also SPS
+// returns true, if activation is successful
+bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
+{
+  PPS *pps = m_ppsMap.getPS(ppsId);
+  if (pps)
+  {
+    int spsId = pps->getSPSId();
+#if !ENABLING_MULTI_SPS
+    if (!isIRAP && (spsId != m_activeSPSId ))
+    {
+      msg( WARNING, "Warning: tried to activate a PPS referring to an inactive SPS at non-IDR.");
+    }
+    else
+#endif
+    {
+      SPS *sps = m_spsMap.getPS(spsId);
+
+      if (sps)
+      {
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+        int dpsId = sps->getDecodingParameterSetId();
+        if ((m_activeDPSId!=-1) && (dpsId != m_activeDPSId ))
+        {
+          msg( WARNING, "Warning: tried to activate a DPS with different ID than the currently active DPS. This should not happen within the same bitstream!");
+        }
+        else
+        {
+          if (dpsId != 0)
+          {
+            DPS *dps =m_dpsMap.getPS(dpsId);
+            if (dps)
+            {
+              m_activeDPSId = dpsId;
+              m_dpsMap.setActive(dpsId);
+            }
+            else
+            {
+              msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing DPS.");
+            }
+          }
+          else
+          {
+            // set zero as active DPS ID (special reserved value, no actual DPS)
+            m_activeDPSId = dpsId;
+            m_dpsMap.setActive(dpsId);
+          }
+        }
+#endif
+        int vpsId = sps->getVPSId();
+        if(vpsId != 0)
+        {
+          VPS *vps = m_vpsMap.getPS(vpsId);
+          if(vps)
+          {
+            m_activeVPSId = vpsId;
+            m_vpsMap.setActive(vpsId);
+          }
+          else
+          {
+            msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing VPS." );
+          }
+        }
+        else
+        {
+          m_vpsMap.clear();
+          m_vpsMap.allocatePS(0);
+          m_activeVPSId = 0;
+          m_vpsMap.setActive(0);
+        }
+
+        m_spsMap.clear();
+        m_spsMap.setActive(spsId);
+        m_activeSPSId = spsId;
+        m_ppsMap.clear();
+        m_ppsMap.setActive(ppsId);
+        return true;
+      }
+      else
+      {
+        msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing SPS.");
+      }
+    }
+  }
+  else
+  {
+    msg( WARNING, "Warning: tried to activate a non-existing PPS.");
+  }
+
+  // Failed to activate if reach here.
+  m_activeSPSId=-1;
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+  m_activeDPSId=-1;
+#endif
+  return false;
+}
+
+bool ParameterSetManager::activateAPS(int apsId, int apsType)
+{
+  APS *aps = m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType));
+  if (aps)
+  {
+    m_apsMap.setActive(apsId + (MAX_NUM_APS * apsType));
+    return true;
+  }
+  else
+  {
+    msg(WARNING, "Warning: tried to activate a non-existing APS.");
+  }
+  return false;
+}
+
+template <>
+void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId)
+{
+  parameterSet->setAPSId(psId);
+}
+template <>
+void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId)
+{
+  parameterSet->setPPSId(psId);
+}
+
+template <>
+void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId)
+{
+  parameterSet->setSPSId(psId);
+}
+
+template <>
+void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId)
+{
+  parameterSet->setVPSId(psId);
+}
+
+ProfileTierLevel::ProfileTierLevel()
+  : m_tierFlag        (Level::MAIN)
+  , m_profileIdc      (Profile::NONE)
+  , m_numSubProfile(0)
+  , m_subProfileIdc(0)
+  , m_levelIdc        (Level::NONE)
+{
+  ::memset(m_subLayerLevelPresentFlag,   0, sizeof(m_subLayerLevelPresentFlag  ));
+  ::memset(m_subLayerLevelIdc, Level::NONE, sizeof(m_subLayerLevelIdc          ));
+}
+
+void calculateParameterSetChangedFlag(bool &changed, const std::vector<uint8_t> *oldData, const std::vector<uint8_t> *newData)
+{
+  if (!changed)
+  {
+    if ((oldData==0 && newData!=0) || (oldData!=0 && newData==0))
+    {
+      changed=true;
+    }
+    else if (oldData!=0 && newData!=0)
+    {
+      // compare the two
+      if (oldData->size() != newData->size())
+      {
+        changed=true;
+      }
+      else
+      {
+        const uint8_t *pNewDataArray=&(*newData)[0];
+        const uint8_t *pOldDataArray=&(*oldData)[0];
+        if (memcmp(pOldDataArray, pNewDataArray, oldData->size()))
+        {
+          changed=true;
+        }
+      }
+    }
+  }
+}
diff --git a/source/Lib/CommonLib/ParameterSetManager.h b/source/Lib/CommonLib/ParameterSetManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce63f798a68d838da22a4f41e5166d778408ffb6
--- /dev/null
+++ b/source/Lib/CommonLib/ParameterSetManager.h
@@ -0,0 +1,287 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#ifndef __PARAMETERSETMANAGER__
+#define __PARAMETERSETMANAGER__
+
+#include "Slice.h"
+#include <map>
+
+void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData);
+
+template <class T> class ParameterSetMap
+{
+public:
+  template <class Tm>
+  struct MapData
+  {
+    bool                  bChanged;
+    std::vector<uint8_t>   *pNaluData; // Can be null
+    Tm*                   parameterSet;
+  };
+
+  ParameterSetMap(int maxId)
+  :m_maxId (maxId)
+  ,m_lastActiveParameterSet(NULL)
+  {
+    m_activePsId.clear();
+  }
+
+  ~ParameterSetMap()
+  {
+    for (typename std::map<int,MapData<T> >::iterator i = m_paramsetMap.begin(); i!= m_paramsetMap.end(); i++)
+    {
+      delete (*i).second.pNaluData;
+      delete (*i).second.parameterSet;
+    }
+    delete m_lastActiveParameterSet; m_lastActiveParameterSet = NULL;
+  }
+
+  T *allocatePS(const int psId)
+  {
+    CHECK( psId >= m_maxId, "Invalid PS id" );
+    if ( m_paramsetMap.find(psId) == m_paramsetMap.end() )
+    {
+      m_paramsetMap[psId].bChanged = true;
+      m_paramsetMap[psId].pNaluData=0;
+      m_paramsetMap[psId].parameterSet = new T;
+      setID(m_paramsetMap[psId].parameterSet, psId);
+    }
+    return m_paramsetMap[psId].parameterSet;
+  }
+
+  void clearMap()
+  {
+    m_paramsetMap.clear();
+  }
+
+  void storePS(int psId, T *ps, const std::vector<uint8_t> *pNaluData)
+  {
+    CHECK( psId >= m_maxId, "Invalid PS id" );
+    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
+    {
+      MapData<T> &mapData=m_paramsetMap[psId];
+
+      // work out changed flag
+      calculateParameterSetChangedFlag(mapData.bChanged, mapData.pNaluData, pNaluData);
+
+      if( ! mapData.bChanged )
+      {
+        // just keep the old one
+        delete ps;
+        return;
+      }
+
+      if (find(m_activePsId.begin(), m_activePsId.end(), psId) != m_activePsId.end())
+      {
+        std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet );
+      }
+      delete m_paramsetMap[psId].pNaluData;
+      delete m_paramsetMap[psId].parameterSet;
+
+      m_paramsetMap[psId].parameterSet = ps;
+    }
+    else
+    {
+      m_paramsetMap[psId].parameterSet = ps;
+      m_paramsetMap[psId].bChanged = false;
+    }
+    if (pNaluData != 0)
+    {
+      m_paramsetMap[psId].pNaluData=new std::vector<uint8_t>;
+      *(m_paramsetMap[psId].pNaluData) = *pNaluData;
+    }
+    else
+    {
+      m_paramsetMap[psId].pNaluData=0;
+    }
+  }
+
+  void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals )
+  {
+    int apsId = ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + (int)aps->getAPSType();
+
+    if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() )
+    {
+      CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exist" );
+      APS* existedAPS = m_paramsetMap[apsId].parameterSet;
+
+      if( aps->getAPSType() == LMCS_APS )
+      {
+        CHECK( aps->getReshaperAPSInfo() != existedAPS->getReshaperAPSInfo(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
+      }
+      else if( aps->getAPSType() == ALF_APS )
+      {
+        CHECK( aps->getAlfAPSParam() != existedAPS->getAlfAPSParam(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
+      }
+      else if( aps->getAPSType() == SCALING_LIST_APS )
+      {
+        CHECK( aps->getScalingList() != existedAPS->getScalingList(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
+      }
+      else
+      {
+        CHECK( true, "Wrong APS type" );
+      }
+    }
+    else
+    {
+      accessUnitApsNals.push_back( apsId );
+    }
+  }
+
+
+  void setChangedFlag(int psId, bool bChanged=true)
+  {
+    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
+    {
+      m_paramsetMap[psId].bChanged=bChanged;
+    }
+  }
+
+  void clearChangedFlag(int psId)
+  {
+    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
+    {
+      m_paramsetMap[psId].bChanged=false;
+    }
+  }
+
+  bool getChangedFlag(int psId) const
+  {
+    const typename std::map<int,MapData<T> >::const_iterator constit=m_paramsetMap.find(psId);
+    if ( constit != m_paramsetMap.end() )
+    {
+      return constit->second.bChanged;
+    }
+    return false;
+  }
+
+  T* getPS(int psId)
+  {
+    typename std::map<int,MapData<T> >::iterator it=m_paramsetMap.find(psId);
+    return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet;
+  }
+
+  const T* getPS(int psId) const
+  {
+    typename std::map<int,MapData<T> >::const_iterator it=m_paramsetMap.find(psId);
+    return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet;
+  }
+
+  T* getFirstPS()
+  {
+    return (m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet;
+  }
+
+  void setActive(int psId) { m_activePsId.push_back(psId); }
+  void clear() { m_activePsId.clear(); }
+
+private:
+  std::map<int,MapData<T> > m_paramsetMap;
+  int                       m_maxId;
+  std::vector<int>          m_activePsId;
+  T*                        m_lastActiveParameterSet;
+  static void setID(T* parameterSet, const int psId);
+};
+
+class ParameterSetManager
+{
+public:
+                 ParameterSetManager();
+  virtual        ~ParameterSetManager();
+
+  void           storeVPS(VPS *vps, const std::vector<uint8_t> &naluData)    { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); }
+  VPS*           getVPS( int vpsId )                                         { return m_vpsMap.getPS( vpsId ); };
+
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+  void           storeDPS(DPS *dps, const std::vector<uint8_t> &naluData)    { m_dpsMap.storePS( dps->getDecodingParameterSetId(), dps, &naluData); };
+  // get pointer to existing video parameter set
+  DPS*           getDPS(int dpsId)                                           { return m_dpsMap.getPS(dpsId); };
+  bool           getDPSChangedFlag(int dpsId) const                          { return m_dpsMap.getChangedFlag(dpsId); }
+  void           clearDPSChangedFlag(int dpsId)                              { m_dpsMap.clearChangedFlag(dpsId); }
+  DPS*           getFirstDPS()                                               { return m_dpsMap.getFirstPS(); };
+#endif
+  // store sequence parameter set and take ownership of it
+  void           storeSPS(SPS *sps, const std::vector<uint8_t> &naluData)    { m_spsMap.storePS( sps->getSPSId(), sps, &naluData); };
+  // get pointer to existing sequence parameter set
+  SPS*           getSPS(int spsId)                                           { return m_spsMap.getPS(spsId); };
+  bool           getSPSChangedFlag(int spsId) const                          { return m_spsMap.getChangedFlag(spsId); }
+  void           clearSPSChangedFlag(int spsId)                              { m_spsMap.clearChangedFlag(spsId); }
+  SPS*           getFirstSPS()                                               { return m_spsMap.getFirstPS(); };
+
+  // store picture parameter set and take ownership of it
+  void           storePPS(PPS *pps, const std::vector<uint8_t> &naluData)    { m_ppsMap.storePS( pps->getPPSId(), pps, &naluData); };
+  // get pointer to existing picture parameter set
+  PPS*           getPPS(int ppsId)                                           { return m_ppsMap.getPS(ppsId); };
+  bool           getPPSChangedFlag(int ppsId) const                          { return m_ppsMap.getChangedFlag(ppsId); }
+  void           clearPPSChangedFlag(int ppsId)                              { m_ppsMap.clearChangedFlag(ppsId); }
+  PPS*           getFirstPPS()                                               { return m_ppsMap.getFirstPS(); };
+
+  // activate a PPS and depending on isIRAP parameter also SPS
+  // returns true, if activation is successful
+  bool           activatePPS(int ppsId, bool isIRAP);
+  APS**          getAPSs() { return &m_apss[0]; }
+  ParameterSetMap<APS>* getApsMap() { return &m_apsMap; }
+  void           storeAPS(APS *aps, const std::vector<uint8_t> &naluData)    { m_apsMap.storePS(aps->getAPSId() + (MAX_NUM_APS * aps->getAPSType()), aps, &naluData); };
+  APS*           getAPS(int apsId, int apsType)                              { return m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); };
+  bool           getAPSChangedFlag(int apsId, int apsType) const             { return m_apsMap.getChangedFlag(apsId + (MAX_NUM_APS * apsType)); }
+  void           clearAPSChangedFlag(int apsId, int apsType)                 { m_apsMap.clearChangedFlag(apsId + ( MAX_NUM_APS * apsType)); }
+  APS*           getFirstAPS()                                               { return m_apsMap.getFirstPS(); };
+  bool           activateAPS(int apsId, int apsType);
+  const SPS*     getActiveSPS()const                                         { return m_spsMap.getPS(m_activeSPSId); };
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+  const DPS*     getActiveDPS()const                                         { return m_dpsMap.getPS(m_activeDPSId); };
+#endif
+  void           checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) { m_apsMap.checkAuApsContent( aps, accessUnitApsNals ); }
+
+protected:
+  ParameterSetMap<SPS> m_spsMap;
+  ParameterSetMap<PPS> m_ppsMap;
+  ParameterSetMap<APS> m_apsMap;
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+  ParameterSetMap<DPS> m_dpsMap;
+#endif
+  ParameterSetMap<VPS> m_vpsMap;
+
+  APS* m_apss[ALF_CTB_MAX_NUM_APS];
+#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
+  int m_activeDPSId; // -1 for nothing active
+#endif
+  int m_activeSPSId; // -1 for nothing active
+  int m_activeVPSId; // -1 for nothing active
+};
+
+
+#endif
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index cea3e294a3a189ddd45b71fb8646a6adcc4eb092..01eae73096e4b78917976d4ef093c43fc8aff906 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -3604,231 +3604,6 @@ bool ScalingList::isLumaScalingList( int scalingListId) const
 }
 #endif
 
-ParameterSetManager::ParameterSetManager()
-: m_spsMap(MAX_NUM_SPS)
-, m_ppsMap(MAX_NUM_PPS)
-, m_apsMap(MAX_NUM_APS * MAX_NUM_APS_TYPE)
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-, m_dpsMap(MAX_NUM_DPS)
-#endif
-, m_vpsMap(MAX_NUM_VPS)
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-, m_activeDPSId(-1)
-#endif
-, m_activeSPSId(-1)
-, m_activeVPSId(-1)
-{
-}
-
-
-ParameterSetManager::~ParameterSetManager()
-{
-}
-
-//! activate a SPS from a active parameter sets SEI message
-//! \returns true, if activation is successful
-//bool ParameterSetManager::activateSPSWithSEI(int spsId)
-//{
-//  SPS *sps = m_spsMap.getPS(spsId);
-//  if (sps)
-//  {
-//    int vpsId = sps->getVPSId();
-//    VPS *vps = m_vpsMap.getPS(vpsId);
-//    if (vps)
-//    {
-//      m_activeVPS = *(vps);
-//      m_activeSPS = *(sps);
-//      return true;
-//    }
-//    else
-//    {
-//     msg( WARNING, "Warning: tried to activate SPS using an Active parameter sets SEI message. Referenced VPS does not exist.");
-//    }
-//  }
-//  else
-//  {
-//    msg( WARNING, "Warning: tried to activate non-existing SPS using an Active parameter sets SEI message.");
-//  }
-//  return false;
-//}
-
-//! activate a PPS and depending on isIDR parameter also SPS
-//! \returns true, if activation is successful
-bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
-{
-  PPS *pps = m_ppsMap.getPS(ppsId);
-  if (pps)
-  {
-    int spsId = pps->getSPSId();
-#if !ENABLING_MULTI_SPS
-    if (!isIRAP && (spsId != m_activeSPSId ))
-    {
-      msg( WARNING, "Warning: tried to activate PPS referring to a inactive SPS at non-IDR.");
-    }
-    else
-#endif
-    {
-      SPS *sps = m_spsMap.getPS(spsId);
-
-      if (sps)
-      {
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-        int dpsId = sps->getDecodingParameterSetId();
-        if ((m_activeDPSId!=-1) && (dpsId != m_activeDPSId ))
-        {
-          msg( WARNING, "Warning: tried to activate DPS with different ID than the currently active DPS. This should not happen within the same bitstream!");
-        }
-        else
-        {
-          if (dpsId != 0)
-          {
-            DPS *dps =m_dpsMap.getPS(dpsId);
-            if (dps)
-            {
-              m_activeDPSId = dpsId;
-              m_dpsMap.setActive(dpsId);
-            }
-            else
-            {
-              msg( WARNING, "Warning: tried to activate PPS that refers to a non-existing DPS.");
-            }
-          }
-          else
-          {
-            // set zero as active DPS ID (special reserved value, no actual DPS)
-            m_activeDPSId = dpsId;
-            m_dpsMap.setActive(dpsId);
-          }
-        }
-#endif
-        int vpsId = sps->getVPSId();
-        if(vpsId != 0)
-        {
-          VPS *vps = m_vpsMap.getPS(vpsId);
-          if(vps)
-          {
-            m_activeVPSId = vpsId;
-            m_vpsMap.setActive(vpsId);
-          }  
-          else
-          {
-            msg( WARNING, "Warning: tried to activate PPS that refers to non-existing VPS." );
-          }
-        }
-        else
-        {
-          m_vpsMap.clear();
-          m_vpsMap.allocatePS(0);
-          m_activeVPSId = 0;
-          m_vpsMap.setActive(0);
-        }
-
-        m_spsMap.clear();
-        m_spsMap.setActive(spsId);
-        m_activeSPSId = spsId;
-        m_ppsMap.clear();
-        m_ppsMap.setActive(ppsId);
-        return true;
-      }
-      else
-      {
-        msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing SPS.");
-      }
-    }
-  }
-  else
-  {
-    msg( WARNING, "Warning: tried to activate non-existing PPS.");
-  }
-
-  // Failed to activate if reach here.
-  m_activeSPSId=-1;
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-  m_activeDPSId=-1;
-#endif
-  return false;
-}
-
-bool ParameterSetManager::activateAPS(int apsId, int apsType)
-{
-  APS *aps = m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType));
-  if (aps)
-  {
-    m_apsMap.setActive(apsId + (MAX_NUM_APS * apsType));
-    return true;
-  }
-  else
-  {
-    msg(WARNING, "Warning: tried to activate non-existing APS.");
-  }
-  return false;
-}
-
-template <>
-void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId)
-{
-  parameterSet->setAPSId(psId);
-}
-template <>
-void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId)
-{
-  parameterSet->setPPSId(psId);
-}
-
-template <>
-void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId)
-{
-  parameterSet->setSPSId(psId);
-}
-
-template <>
-void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId)
-{
-  parameterSet->setVPSId(psId);
-}
-
-ProfileTierLevel::ProfileTierLevel()
-  : m_tierFlag        (Level::MAIN)
-  , m_profileIdc      (Profile::NONE)
-  , m_numSubProfile(0)
-  , m_subProfileIdc(0)
-  , m_levelIdc        (Level::NONE)
-{
-  ::memset(m_subLayerLevelPresentFlag,   0, sizeof(m_subLayerLevelPresentFlag  ));
-  ::memset(m_subLayerLevelIdc, Level::NONE, sizeof(m_subLayerLevelIdc          ));
-}
-
-
-void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData)
-{
-  if (!bChanged)
-  {
-    if ((pOldData==0 && pNewData!=0) || (pOldData!=0 && pNewData==0))
-    {
-      bChanged=true;
-    }
-    else if (pOldData!=0 && pNewData!=0)
-    {
-      // compare the two
-      if (pOldData->size() != pNewData->size())
-      {
-        bChanged=true;
-      }
-      else
-      {
-        const uint8_t *pNewDataArray=&(*pNewData)[0];
-        const uint8_t *pOldDataArray=&(*pOldData)[0];
-        if (memcmp(pOldDataArray, pNewDataArray, pOldData->size()))
-        {
-          bChanged=true;
-        }
-      }
-    }
-  }
-}
-
-//! \}
-
 uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType ) const
 {
   return slice.isIntra() ? ( ISingleTree ? 0 : ( chType << 1 ) ) : 1;
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index ee507d16c236d4a4ba103ccceb4b602285893e82..5f9a7939b0f70fdc836c7cf338a80a21a775c335 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -3196,253 +3196,6 @@ public:
 private:
 };// END CLASS DEFINITION Slice
 
-void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData);
-
-template <class T> class ParameterSetMap
-{
-public:
-  template <class Tm>
-  struct MapData
-  {
-    bool                  bChanged;
-    std::vector<uint8_t>   *pNaluData; // Can be null
-    Tm*                   parameterSet;
-  };
-
-  ParameterSetMap(int maxId)
-  :m_maxId (maxId)
-  ,m_lastActiveParameterSet(NULL)
-  {
-    m_activePsId.clear();
-  }
-
-  ~ParameterSetMap()
-  {
-    for (typename std::map<int,MapData<T> >::iterator i = m_paramsetMap.begin(); i!= m_paramsetMap.end(); i++)
-    {
-      delete (*i).second.pNaluData;
-      delete (*i).second.parameterSet;
-    }
-    delete m_lastActiveParameterSet; m_lastActiveParameterSet = NULL;
-  }
-
-  T *allocatePS(const int psId)
-  {
-    CHECK( psId >= m_maxId, "Invalid PS id" );
-    if ( m_paramsetMap.find(psId) == m_paramsetMap.end() )
-    {
-      m_paramsetMap[psId].bChanged = true;
-      m_paramsetMap[psId].pNaluData=0;
-      m_paramsetMap[psId].parameterSet = new T;
-      setID(m_paramsetMap[psId].parameterSet, psId);
-    }
-    return m_paramsetMap[psId].parameterSet;
-  }
-
-  void clearMap()
-  {
-    m_paramsetMap.clear();
-  }
-
-  void storePS(int psId, T *ps, const std::vector<uint8_t> *pNaluData)
-  {
-    CHECK( psId >= m_maxId, "Invalid PS id" );
-    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
-    {
-      MapData<T> &mapData=m_paramsetMap[psId];
-
-      // work out changed flag
-      calculateParameterSetChangedFlag(mapData.bChanged, mapData.pNaluData, pNaluData);
-
-      if( ! mapData.bChanged )
-      {
-        // just keep the old one
-        delete ps;
-        return;
-      }
-
-      if (find(m_activePsId.begin(), m_activePsId.end(), psId) != m_activePsId.end())
-      {
-        std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet );
-      }
-      delete m_paramsetMap[psId].pNaluData;
-      delete m_paramsetMap[psId].parameterSet;
-
-      m_paramsetMap[psId].parameterSet = ps;
-    }
-    else
-    {
-      m_paramsetMap[psId].parameterSet = ps;
-      m_paramsetMap[psId].bChanged = false;
-    }
-    if (pNaluData != 0)
-    {
-      m_paramsetMap[psId].pNaluData=new std::vector<uint8_t>;
-      *(m_paramsetMap[psId].pNaluData) = *pNaluData;
-    }
-    else
-    {
-      m_paramsetMap[psId].pNaluData=0;
-    }
-  }
-
-  void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals )
-  {
-    int apsId = ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + (int)aps->getAPSType();
-
-    if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() )
-    {
-      CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exist" );
-      APS* existedAPS = m_paramsetMap[apsId].parameterSet;
-
-      if( aps->getAPSType() == LMCS_APS )
-      {
-        CHECK( aps->getReshaperAPSInfo() != existedAPS->getReshaperAPSInfo(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
-      }
-      else if( aps->getAPSType() == ALF_APS )
-      {
-        CHECK( aps->getAlfAPSParam() != existedAPS->getAlfAPSParam(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
-      }
-      else if( aps->getAPSType() == SCALING_LIST_APS )
-      {
-        CHECK( aps->getScalingList() != existedAPS->getScalingList(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" );
-      }
-      else
-      {
-        CHECK( true, "Wrong APS type" );
-      }
-    }
-    else
-    {
-      accessUnitApsNals.push_back( apsId );
-    }
-  }
-
-
-  void setChangedFlag(int psId, bool bChanged=true)
-  {
-    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
-    {
-      m_paramsetMap[psId].bChanged=bChanged;
-    }
-  }
-
-  void clearChangedFlag(int psId)
-  {
-    if ( m_paramsetMap.find(psId) != m_paramsetMap.end() )
-    {
-      m_paramsetMap[psId].bChanged=false;
-    }
-  }
-
-  bool getChangedFlag(int psId) const
-  {
-    const typename std::map<int,MapData<T> >::const_iterator constit=m_paramsetMap.find(psId);
-    if ( constit != m_paramsetMap.end() )
-    {
-      return constit->second.bChanged;
-    }
-    return false;
-  }
-
-  T* getPS(int psId)
-  {
-    typename std::map<int,MapData<T> >::iterator it=m_paramsetMap.find(psId);
-    return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet;
-  }
-
-  const T* getPS(int psId) const
-  {
-    typename std::map<int,MapData<T> >::const_iterator it=m_paramsetMap.find(psId);
-    return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet;
-  }
-
-  T* getFirstPS()
-  {
-    return (m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet;
-  }
-
-  void setActive(int psId) { m_activePsId.push_back(psId); }
-  void clear() { m_activePsId.clear(); }
-
-private:
-  std::map<int,MapData<T> > m_paramsetMap;
-  int                       m_maxId;
-  std::vector<int>          m_activePsId;
-  T*                        m_lastActiveParameterSet;
-  static void setID(T* parameterSet, const int psId);
-};
-
-class ParameterSetManager
-{
-public:
-                 ParameterSetManager();
-  virtual        ~ParameterSetManager();
-
-  void           storeVPS(VPS *vps, const std::vector<uint8_t> &naluData)    { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); }
-  VPS*           getVPS( int vpsId )                                         { return m_vpsMap.getPS( vpsId ); };
-
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-  void           storeDPS(DPS *dps, const std::vector<uint8_t> &naluData)    { m_dpsMap.storePS( dps->getDecodingParameterSetId(), dps, &naluData); };
-  //! get pointer to existing video parameter set
-  DPS*           getDPS(int dpsId)                                           { return m_dpsMap.getPS(dpsId); };
-  bool           getDPSChangedFlag(int dpsId) const                          { return m_dpsMap.getChangedFlag(dpsId); }
-  void           clearDPSChangedFlag(int dpsId)                              { m_dpsMap.clearChangedFlag(dpsId); }
-  DPS*           getFirstDPS()                                               { return m_dpsMap.getFirstPS(); };
-#endif
-  //! store sequence parameter set and take ownership of it
-  void           storeSPS(SPS *sps, const std::vector<uint8_t> &naluData) { m_spsMap.storePS( sps->getSPSId(), sps, &naluData); };
-  //! get pointer to existing sequence parameter set
-  SPS*           getSPS(int spsId)                                           { return m_spsMap.getPS(spsId); };
-  bool           getSPSChangedFlag(int spsId) const                          { return m_spsMap.getChangedFlag(spsId); }
-  void           clearSPSChangedFlag(int spsId)                              { m_spsMap.clearChangedFlag(spsId); }
-  SPS*           getFirstSPS()                                               { return m_spsMap.getFirstPS(); };
-
-  //! store picture parameter set and take ownership of it
-  void           storePPS(PPS *pps, const std::vector<uint8_t> &naluData) { m_ppsMap.storePS( pps->getPPSId(), pps, &naluData); };
-  //! get pointer to existing picture parameter set
-  PPS*           getPPS(int ppsId)                                           { return m_ppsMap.getPS(ppsId); };
-  bool           getPPSChangedFlag(int ppsId) const                          { return m_ppsMap.getChangedFlag(ppsId); }
-  void           clearPPSChangedFlag(int ppsId)                              { m_ppsMap.clearChangedFlag(ppsId); }
-  PPS*           getFirstPPS()                                               { return m_ppsMap.getFirstPS(); };
-
-  //! activate a SPS from a active parameter sets SEI message
-  //! \returns true, if activation is successful
-  // bool           activateSPSWithSEI(int SPSId);
-
-  //! activate a PPS and depending on isIDR parameter also SPS
-  //! \returns true, if activation is successful
-  bool           activatePPS(int ppsId, bool isIRAP);
-  APS**          getAPSs() { return &m_apss[0]; }
-  ParameterSetMap<APS>* getApsMap() { return &m_apsMap; }
-  void           storeAPS(APS *aps, const std::vector<uint8_t> &naluData)    { m_apsMap.storePS(aps->getAPSId() + (MAX_NUM_APS * aps->getAPSType()), aps, &naluData); };
-  APS*           getAPS(int apsId, int apsType)                              { return m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); };
-  bool           getAPSChangedFlag(int apsId, int apsType) const             { return m_apsMap.getChangedFlag(apsId + (MAX_NUM_APS * apsType)); }
-  void           clearAPSChangedFlag(int apsId, int apsType)                 { m_apsMap.clearChangedFlag(apsId + ( MAX_NUM_APS * apsType)); }
-  APS*           getFirstAPS()                                               { return m_apsMap.getFirstPS(); };
-  bool           activateAPS(int apsId, int apsType);
-  const SPS*     getActiveSPS()const                                         { return m_spsMap.getPS(m_activeSPSId); };
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-  const DPS*     getActiveDPS()const                                         { return m_dpsMap.getPS(m_activeDPSId); };
-#endif
-  void           checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) { m_apsMap.checkAuApsContent( aps, accessUnitApsNals ); }
-
-protected:
-  ParameterSetMap<SPS> m_spsMap;
-  ParameterSetMap<PPS> m_ppsMap;
-  ParameterSetMap<APS> m_apsMap;
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-  ParameterSetMap<DPS> m_dpsMap;
-#endif
-  ParameterSetMap<VPS> m_vpsMap;
-
-  APS* m_apss[ALF_CTB_MAX_NUM_APS];
-#if !JVET_Q0117_PARAMETER_SETS_CLEANUP
-  int m_activeDPSId; // -1 for nothing active
-#endif
-  int m_activeSPSId; // -1 for nothing active
-  int m_activeVPSId; // -1 for nothing active
-};
 
 class PreCalcValues
 {
diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h
index 104374a2d753fb2c974010893a10fc60ea91c572..e160db1999fe6889f5c3e05a9e1030b5d1f42541 100644
--- a/source/Lib/DecoderLib/VLCReader.h
+++ b/source/Lib/DecoderLib/VLCReader.h
@@ -42,6 +42,7 @@
 #include "CommonLib/BitStream.h"
 #include "CommonLib/Slice.h"
 #include "CommonLib/SampleAdaptiveOffset.h"
+#include "CommonLib/ParameterSetManager.h"
 #include "CABACReader.h"
 
 #if ENABLE_TRACING
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
index 5c620b053c1cb0eaa42b79c06d7b5674dda76e5e..b477b532484c5f5ad72f220007bce9d28d0b8731 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
@@ -39,6 +39,7 @@
 #define __ENCADAPTIVELOOPFILTER__
 
 #include "CommonLib/AdaptiveLoopFilter.h"
+#include "CommonLib/ParameterSetManager.h"
 
 #include "CABACWriter.h"
 #include "EncCfg.h"
diff --git a/source/Lib/EncoderLib/EncLibCommon.h b/source/Lib/EncoderLib/EncLibCommon.h
index 353b7410f33d59f53f76e1c4d3c05fefe9161869..a422beda396f3fbf0fad974f1f5a35b649708645 100644
--- a/source/Lib/EncoderLib/EncLibCommon.h
+++ b/source/Lib/EncoderLib/EncLibCommon.h
@@ -39,6 +39,7 @@
 #include <list>
 #include <fstream>
 #include "CommonLib/Slice.h"
+#include "CommonLib/ParameterSetManager.h"
 
 class EncLibCommon
 {