diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index a38a1174f8f581354335161834968ec88d28b1f2..5f1c4f41db5efd26622f62cda6c91f4414f508b8 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -859,6 +859,9 @@ void EncApp::rateStatsAccum(const AccessUnit& au, const std::vector<uint32_t>& a
 #endif
     case NAL_UNIT_SPS:
     case NAL_UNIT_PPS:
+#if JVET_M0132
+    case NAL_UNIT_APS:
+#endif
       m_essentialBytes += *it_stats;
       break;
     default:
@@ -875,7 +878,11 @@ void EncApp::printRateSummary()
   msg( DETAILS,"Bytes written to file: %u (%.3f kbps)\n", m_totalBytes, 0.008 * m_totalBytes / time );
   if (m_summaryVerboseness > 0)
   {
+#if JVET_M0132
+    msg(DETAILS, "Bytes for SPS/PPS/APS/Slice (Incl. Annex B): %u (%.3f kbps)\n", m_essentialBytes, 0.008 * m_essentialBytes / time);
+#else
     msg( DETAILS,"Bytes for SPS/PPS/Slice (Incl. Annex B): %u (%.3f kbps)\n", m_essentialBytes, 0.008 * m_essentialBytes / time );
+#endif
   }
 }
 
diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp
index e6443eaf190ba9614243af216fa32a4572162f77..2480310f5264da07eb77ebf6dcbc33910cdebc75 100644
--- a/source/App/Parcat/parcat.cpp
+++ b/source/App/Parcat/parcat.cpp
@@ -221,6 +221,9 @@ const char * NALU_TYPE[] =
 #endif
     "SPS_NUT",
     "PPS_NUT",
+#if JVET_M0132
+    "APS_NUT",
+#endif
     "AUD_NUT",
     "EOS_NUT",
     "EOB_NUT",
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index 67ca6d94738a476430f8d78f28e61bfc22a143ce..ae2c6e3cc16db66fbfe9b233744057d1bc16ef8b 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -101,6 +101,9 @@ public:
   bool        isLossless;
   const SPS *sps;
   const PPS *pps;
+#if JVET_M0132
+  APS *      aps;
+#endif
 #if HEVC_VPS
   const VPS *vps;
 #endif
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 6d09dc35f650e11d42a96fe0daf219da1381a6e5..1f23d7a3480d6870ec15a4b073e35e9a844a8077 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -186,6 +186,9 @@ static const int C2FLAG_NUMBER =                                    1; ///< maxi
 static const int MAX_NUM_VPS =                                     16;
 static const int MAX_NUM_SPS =                                     16;
 static const int MAX_NUM_PPS =                                     64;
+#if JVET_M0132
+static const int MAX_NUM_APS =                                     32;  //Currently APS ID has 5 bits
+#endif
 
 static const int MLS_GRP_NUM =                                   1024; ///< Max number of coefficient groups, max(16, 256)
 
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 2b8f46593b255789956d72dac002c75ba4d659a0..286810db34d7c2fbc60ffd3463b0ee56201a63fe 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -881,7 +881,11 @@ const CPelUnitBuf Picture::getRecoBuf(const UnitArea &unit)     const { return g
        PelUnitBuf Picture::getRecoBuf()                               { return M_BUFS(scheduler.getSplitPicId(), PIC_RECONSTRUCTION); }
 const CPelUnitBuf Picture::getRecoBuf()                         const { return M_BUFS(scheduler.getSplitPicId(), PIC_RECONSTRUCTION); }
 
+#if JVET_M0132
+void Picture::finalInit(const SPS& sps, const PPS& pps, APS& aps)
+#else
 void Picture::finalInit( const SPS& sps, const PPS& pps )
+#endif
 {
   for( auto &sei : SEIs )
   {
@@ -917,6 +921,9 @@ void Picture::finalInit( const SPS& sps, const PPS& pps )
   cs->picture = this;
   cs->slice   = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
   cs->pps     = &pps;
+#if JVET_M0132
+  cs->aps = &aps;
+#endif
 #if HEVC_VPS
   cs->vps     = nullptr;
 #endif
@@ -939,6 +946,9 @@ void Picture::allocateNewSlice()
   slices.push_back(new Slice);
   Slice& slice = *slices.back();
 
+#if JVET_M0132
+  slice.setAPS(cs->aps);
+#endif
   slice.setPPS( cs->pps);
   slice.setSPS( cs->sps);
   if(slices.size()>=2)
@@ -952,11 +962,17 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i)
 {
   p->setSPS(cs->sps);
   p->setPPS(cs->pps);
+#if JVET_M0132
+  p->setAPS(cs->aps);
+#endif
 
   Slice * pTmp = slices[i];
   slices[i] = p;
   pTmp->setSPS(0);
   pTmp->setPPS(0);
+#if JVET_M0132
+  pTmp->setAPS(0);
+#endif
   return pTmp;
 }
 
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index fd014dcb58987ca7901c3504d16849588c259c18..e9c3a2c625141c8dc15f8e270bd00eee1d7c555d 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -233,7 +233,11 @@ struct Picture : public UnitArea
   const CPelUnitBuf getBuf(const UnitArea &unit,     const PictureType &type) const;
 
   void extendPicBorder();
+#if JVET_M0132
+  void finalInit(const SPS& sps, const PPS& pps, APS& aps);
+#else
   void finalInit( const SPS& sps, const PPS& pps );
+#endif
 
   int  getPOC()                               const { return poc; }
   void setBorderExtension( bool bFlag)              { m_bIsBorderExtended = bFlag;}
diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp
index 8494ab1b8e11a2f5d9f9378aaa9b7dac3872859b..31bb0728a56b294032f8f01d7e7b45ee31227706 100644
--- a/source/Lib/CommonLib/Rom.cpp
+++ b/source/Lib/CommonLib/Rom.cpp
@@ -86,6 +86,9 @@ const char* nalUnitTypeToString(NalUnitType type)
 #endif
   case NAL_UNIT_SPS:                    return "SPS";
   case NAL_UNIT_PPS:                    return "PPS";
+#if JVET_M0132
+  case NAL_UNIT_APS:                    return "APS";
+#endif
   case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
   case NAL_UNIT_EOS:                    return "EOS";
   case NAL_UNIT_EOB:                    return "EOB";
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 8baeacce8e337e6d675e0dc42071aaf458a639ea..4327c885d781c86dbb012b4f663f4acd062e189e 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -139,6 +139,10 @@ Slice::Slice()
 , m_uiMaxBTSizeIChroma            ( 0 )
 , m_uiMaxTTSizeIChroma            ( 0 )
 , m_uiMaxBTSize                   ( 0 )
+#if JVET_M0132
+, m_iAPSId                        ( -1 )
+, m_pcAPS                        (NULL)
+#endif
 , m_MotionCandLut                (NULL)
 #if  JVET_M0170_MRG_SHARELIST
 , m_MotionCandLuTsBkup           (NULL)
@@ -2102,6 +2106,16 @@ PPS::~PPS()
   delete pcv;
 }
 
+#if JVET_M0132
+APS::APS()
+: m_APSId(0)
+{
+}
+
+APS::~APS()
+{
+}
+#endif
 ReferencePictureSet::ReferencePictureSet()
 : m_numberOfPictures (0)
 , m_numberOfNegativePictures (0)
@@ -2580,6 +2594,9 @@ ParameterSetManager::ParameterSetManager()
 : m_spsMap(MAX_NUM_SPS)
 #endif
 , m_ppsMap(MAX_NUM_PPS)
+#if JVET_M0132
+, m_apsMap(MAX_NUM_APS)
+#endif
 #if HEVC_VPS
 , m_activeVPSId(-1)
 #endif
@@ -2690,6 +2707,28 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
   return false;
 }
 
+#if JVET_M0132
+bool ParameterSetManager::activateAPS(int apsId)
+{
+  APS *aps = m_apsMap.getPS(apsId);
+  if (aps)
+  {
+    m_apsMap.setActive(apsId);
+    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);
+}
+#endif
 template <>
 void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId)
 {
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index ffe92ca71fd05e343df8125d262612e6a2351c46..54ba6b5e4ef51beee52df2ab21ba63521fe8849d 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1573,6 +1573,24 @@ public:
   PPSRExt&               getPpsRangeExtension()                                           { return m_ppsRangeExtension;                   }
 };
 
+#if JVET_M0132
+class APS
+{
+private:
+  int                    m_APSId;                    // adaptation_parameter_set_id
+  AlfSliceParam          m_alfAPSParam;
+
+public:
+  APS();
+  virtual                ~APS();
+
+  int                    getAPSId() const                                                 { return m_APSId;                               }
+  void                   setAPSId(int i)                                                  { m_APSId = i;                                  }
+
+  void                   setAlfAPSParam(AlfSliceParam& alfAPSParam)                       { m_alfAPSParam = alfAPSParam;                  }
+  AlfSliceParam          getAlfAPSParam()                                                 { return m_alfAPSParam;                         }
+};
+#endif
 struct WPScalingParam
 {
   // Explicit weighted prediction parameters parsed in slice header,
@@ -1730,6 +1748,10 @@ private:
   uint32_t                   m_uiMaxTTSizeIChroma;
   uint32_t                       m_uiMaxBTSize;
 
+#if JVET_M0132
+  int                        m_iAPSId;
+  APS*                       m_pcAPS;
+#endif
   AlfSliceParam              m_alfSliceParam;
   LutMotionCand*             m_MotionCandLut;
 #if JVET_M0427_INLOOP_RESHAPER
@@ -1756,6 +1778,12 @@ public:
 
   void                        setPPSId( int PPSId )                                  { m_iPPSId = PPSId;                                             }
   int                         getPPSId() const                                       { return m_iPPSId;                                              }
+#if JVET_M0132
+  void                        setAPS(APS* pcAPS)                                     { m_pcAPS = pcAPS; m_iAPSId = (pcAPS) ? pcAPS->getAPSId() : -1; }
+  APS*                        getAPS()                                               { return m_pcAPS;                                               }
+  void                        setAPSId(int APSId)                                    { m_iAPSId = APSId;                                             }
+  int                         getAPSId() const                                       { return m_iAPSId;                                              }
+#endif
   void                        setPicOutputFlag( bool b   )                           { m_PicOutputFlag = b;                                          }
   bool                        getPicOutputFlag() const                               { return m_PicOutputFlag;                                       }
   void                        setSaoEnabledFlag(ChannelType chType, bool s)          {m_saoEnabledFlag[chType] =s;                                   }
@@ -2239,6 +2267,14 @@ public:
   //! \returns true, if activation is successful
   bool           activatePPS(int ppsId, bool isIRAP);
 
+#if JVET_M0132
+  void           storeAPS(APS *aps, const std::vector<uint8_t> &naluData)    { m_apsMap.storePS(aps->getAPSId(), aps, &naluData); };
+  APS*           getAPS(int apsId)                                           { return m_apsMap.getPS(apsId);                      };
+  bool           getAPSChangedFlag(int apsId) const                          { return m_apsMap.getChangedFlag(apsId);             }
+  void           clearAPSChangedFlag(int apsId)                              { m_apsMap.clearChangedFlag(apsId);                  }
+  APS*           getFirstAPS()                                               { return m_apsMap.getFirstPS();                      };
+  bool           activateAPS(int apsId);
+#endif
 #if HEVC_VPS
   const VPS*     getActiveVPS()const                                         { return m_vpsMap.getPS(m_activeVPSId); };
 #endif
@@ -2250,6 +2286,9 @@ protected:
 #endif
   ParameterSetMap<SPS> m_spsMap;
   ParameterSetMap<PPS> m_ppsMap;
+#if JVET_M0132
+  ParameterSetMap<APS> m_apsMap;
+#endif
 
 #if HEVC_VPS
   int m_activeVPSId; // -1 for nothing active
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index e5d55f34e371df0ef8693d3ad37b3e2fd137df6c..83efdc016b36f24fe08c6acfbac22eaa79bc86db 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -328,6 +328,7 @@ typedef std::pair<int, int>  TrCost;
 #define X0038_LAMBDA_FROM_QP_CAPABILITY                   1 ///< This approach derives lambda from QP+QPoffset+QPoffset2. QPoffset2 is derived from QP+QPoffset using a linear model that is clipped between 0 and 3.
                                                             // To use this capability enable config parameter LambdaFromQpEnable
 
+#define JVET_M0132                                        1
 // ====================================================================================================================
 // Tool Switches
 // ====================================================================================================================
@@ -973,6 +974,9 @@ enum NalUnitType
 #endif
   NAL_UNIT_SPS,                     // 33
   NAL_UNIT_PPS,                     // 34
+#if JVET_M0132
+  NAL_UNIT_APS,                     //NAL unit type number needs to be reaaranged.
+#endif
   NAL_UNIT_ACCESS_UNIT_DELIMITER,   // 35
   NAL_UNIT_EOS,                     // 36
   NAL_UNIT_EOB,                     // 37
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index c45864f6290260c7637df32b15d28df860fa76e8..48af875742eb28dc422f8de39f5b3d355a10c524 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -739,6 +739,13 @@ void DecLib::xActivateParameterSets()
 {
   if (m_bFirstSliceInPicture)
   {
+#if JVET_M0132
+    APS *aps = m_parameterSetManager.getAPS(m_apcSlicePilot->getAPSId()); // this is a temporary APS object. Do not store this value
+    if (m_apcSlicePilot->getAPSId() != -1)
+    {
+      CHECK(aps == 0, "No APS present");
+    }
+#endif
     const PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId()); // this is a temporary PPS object. Do not store this value
     CHECK(pps == 0, "No PPS present");
 
@@ -771,7 +778,11 @@ void DecLib::xActivateParameterSets()
 
     m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS());
 
+#if JVET_M0132
+    m_pcPic->finalInit(*sps, *pps, *aps);
+#else
     m_pcPic->finalInit( *sps, *pps );
+#endif
 
     m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth );
     m_pcPic->cs->createCoeffs();
@@ -785,6 +796,9 @@ void DecLib::xActivateParameterSets()
     Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
 
     // Update the PPS and SPS pointers with the ones of the picture.
+#if JVET_M0132
+    aps= pSlice->getAPS();
+#endif
     pps=pSlice->getPPS();
     sps=pSlice->getSPS();
 
@@ -792,6 +806,9 @@ void DecLib::xActivateParameterSets()
     m_pcPic->cs->slice = pSlice;
     m_pcPic->cs->sps   = sps;
     m_pcPic->cs->pps   = pps;
+#if JVET_M0132
+    m_pcPic->cs->aps   = aps;
+#endif
 #if HEVC_VPS
     m_pcPic->cs->vps   = pSlice->getVPS();
 #endif
@@ -863,11 +880,16 @@ void DecLib::xActivateParameterSets()
 
     const SPS *sps = pSlice->getSPS();
     const PPS *pps = pSlice->getPPS();
-
+#if JVET_M0132
+    APS *aps = pSlice->getAPS();
+#endif
     // fix Parameter Sets, now that we have the real slice
     m_pcPic->cs->slice = pSlice;
     m_pcPic->cs->sps   = sps;
     m_pcPic->cs->pps   = pps;
+#if JVET_M0132
+    m_pcPic->cs->aps   = aps;
+#endif
 #if HEVC_VPS
     m_pcPic->cs->vps   = pSlice->getVPS();
 #endif
@@ -882,6 +904,12 @@ void DecLib::xActivateParameterSets()
     {
       EXIT("Error - a new PPS has been decoded while processing a picture");
     }
+#if JVET_M0132
+    if (m_parameterSetManager.getAPSChangedFlag(aps->getAPSId()))
+    {
+      EXIT("Error - a new APS has been decoded while processing a picture");
+    }
+#endif
 
     xParsePrefixSEImessages();
 
@@ -1046,6 +1074,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     int iMaxPOClsb = 1 << sps->getBitsForPOC();
     m_apcSlicePilot->setPOC( m_apcSlicePilot->getPOC() & (iMaxPOClsb - 1) );
     xUpdatePreviousTid0POC(m_apcSlicePilot);
+#if JVET_M0132
+    if (m_apcSlicePilot->getAPSId() != -1)
+    {
+      APS *aps = m_parameterSetManager.getAPS(m_apcSlicePilot->getAPSId());
+      CHECK(aps == 0, "No APS present");
+    }
+#endif
   }
 
   // Skip pictures due to random access
@@ -1401,6 +1436,15 @@ void DecLib::xDecodePPS( InputNALUnit& nalu )
   m_parameterSetManager.storePPS( pps, nalu.getBitstream().getFifo() );
 }
 
+#if JVET_M0132
+void DecLib::xDecodeAPS(InputNALUnit& nalu)
+{
+  APS* aps = new APS();
+  m_HLSReader.setBitstream(&nalu.getBitstream());
+  m_HLSReader.parseAPS(aps);
+  m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo());
+}
+#endif
 bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
 {
   bool ret;
@@ -1426,6 +1470,11 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
     case NAL_UNIT_PPS:
       xDecodePPS( nalu );
       return false;
+#if JVET_M0132
+    case NAL_UNIT_APS:
+      xDecodeAPS(nalu);
+      return false;
+#endif
 
     case NAL_UNIT_PREFIX_SEI:
       // Buffer up prefix SEI messages until SPS of associated VCL is known.
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index ae94530450e6a9402275be64a23afaf6454dd2ba..9eea5fb986d367da97528a3547482fceaa4e5b68 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -184,6 +184,9 @@ protected:
 #endif
   void      xDecodeSPS( InputNALUnit& nalu );
   void      xDecodePPS( InputNALUnit& nalu );
+#if JVET_M0132
+  void      xDecodeAPS(InputNALUnit& nalu);
+#endif
   void      xUpdatePreviousTid0POC( Slice *pSlice ) { if ((pSlice->getTLayer()==0) && (pSlice->isReferenceNalu() && (pSlice->getNalUnitType()!=NAL_UNIT_CODED_SLICE_RASL_R)&& (pSlice->getNalUnitType()!=NAL_UNIT_CODED_SLICE_RADL_R))) { m_prevTid0POC=pSlice->getPOC(); } }
   void      xParsePrefixSEImessages();
   void      xParsePrefixSEIsForUnknownVCLNal();
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index b365dd7e042435fcaee8b904e82eedcccb756228..9278575af179c654e4db9b3baacc91e7b37896b8 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -91,6 +91,9 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream )
   cs.slice            = slice;
   cs.sps              = sps;
   cs.pps              = slice->getPPS();
+#if JVET_M0132
+  cs.aps              = slice->getAPS();
+#endif
 #if HEVC_VPS
   cs.vps              = slice->getVPS();
 #endif
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 56c467b818093085bd982fec12afd724fb325baf..3c4351e78887aa6af8e36ced8acc3abb35982d3c 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -607,6 +607,48 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
   xReadRbspTrailingBits();
 }
 
+#if JVET_M0132
+void HLSyntaxReader::parseAPS(APS* pcAPS)
+{
+  uint32_t  uiCode;
+
+  READ_CODE(5, uiCode, "adaptation_parameter_set_id");
+  pcAPS->setAPSId(uiCode);
+
+  uint32_t  code = 1;
+  AlfSliceParam param = pcAPS->getAlfAPSParam();
+  param.enabledFlag[COMPONENT_Y] = true;
+
+  int alfChromaIdc = truncatedUnaryEqProb(3);        //alf_chroma_idc
+  param.enabledFlag[COMPONENT_Cb] = alfChromaIdc >> 1;
+  param.enabledFlag[COMPONENT_Cr] = alfChromaIdc & 1;
+
+  xReadTruncBinCode(code, MAX_NUM_ALF_CLASSES);  //number_of_filters_minus1
+  param.numLumaFilters = code + 1;
+  if (param.numLumaFilters > 1)
+  {
+    for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++)
+    {
+      xReadTruncBinCode(code, param.numLumaFilters);
+      param.filterCoeffDeltaIdx[i] = code;
+    }
+  }
+  else
+  {
+    memset(param.filterCoeffDeltaIdx, 0, sizeof(param.filterCoeffDeltaIdx));
+  }
+
+  alfFilter(param, false);
+
+  if (alfChromaIdc)
+  {
+    alfFilter(param, true);
+  }
+  pcAPS->setAlfAPSParam(param);
+
+  xReadRbspTrailingBits();
+}
+#endif
 void  HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS)
 {
 #if ENABLE_TRACING
@@ -1602,7 +1644,25 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
 
     if( sps->getALFEnabledFlag() )
     {
+#if JVET_M0132
+      READ_FLAG(uiCode, "tile_group_alf_enabled_flag");
+      if (uiCode)
+      {
+        READ_CODE(5, uiCode, "tile_group_aps_id"); 
+        pcSlice->setAPSId(uiCode);
+        pcSlice->setAPS(parameterSetManager->getAPS(uiCode));
+        pcSlice->setAlfSliceParam(pcSlice->getAPS()->getAlfAPSParam());
+        pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y] = true;
+      }
+      else
+      {
+        pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y] = false;
+        pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Cb] = false;
+        pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Cr] = false;
+      }
+#else
       alf( pcSlice->getAlfSliceParam() );
+#endif
     }
 
     if (pcSlice->getIdrPicFlag())
@@ -2427,6 +2487,7 @@ bool HLSyntaxReader::xMoreRbspData()
   return (cnt>0);
 }
 
+#if !JVET_M0132
 void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam )
 {
   uint32_t code;
@@ -2465,6 +2526,7 @@ void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam )
     alfFilter( alfSliceParam, true );
   }
 }
+#endif
 
 int HLSyntaxReader::alfGolombDecode( const int k )
 {
diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h
index b8fa2d66a90a105247e1f3e3cc17bfe53e499de4..a7d47899b2511823fd7e0e01dcad6e99b4236160 100644
--- a/source/Lib/DecoderLib/VLCReader.h
+++ b/source/Lib/DecoderLib/VLCReader.h
@@ -149,6 +149,9 @@ public:
 #endif
   void  parseSPS            ( SPS* pcSPS );
   void  parsePPS            ( PPS* pcPPS );
+#if JVET_M0132
+  void  parseAPS            ( APS* pcAPS);
+#endif
   void  parseVUI            ( VUI* pcVUI, SPS* pcSPS );
   void  parsePTL            ( PTL *rpcPTL, bool profilePresentFlag, int maxNumSubLayersMinus1 );
   void  parseProfileTier    ( ProfileTierLevel *ptl, const bool bIsSubLayer );
@@ -165,7 +168,9 @@ public:
 #if JVET_M0427_INLOOP_RESHAPER
   void parseReshaper        ( SliceReshapeInfo& sliceReshaperInfo, const SPS* pcSPS, const bool isIntra );
 #endif
+#if !JVET_M0132
   void alf( AlfSliceParam& alfSliceParam );
+#endif
   void alfFilter( AlfSliceParam& alfSliceParam, const bool isChroma );
 
 private:
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 1b65607633369ca81e8084292c9cb754496b5962..da2d361916ecf7b5535d323729f99cc9386770ef 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -237,6 +237,16 @@ int EncGOP::xWritePPS (AccessUnit &accessUnit, const PPS *pps)
   return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
 }
 
+#if JVET_M0132
+int EncGOP::xWriteAPS(AccessUnit &accessUnit, APS *aps)
+{
+  OutputNALUnit nalu(NAL_UNIT_APS);
+  m_HLSWriter->setBitstream(&nalu.m_Bitstream);
+  m_HLSWriter->codeAPS(aps);
+  accessUnit.push_back(new NALUnitEBSP(nalu));
+  return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+}
+#endif
 
 int EncGOP::xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst)
 {
@@ -2545,6 +2555,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       {
         xWriteAccessUnitDelimiter(accessUnit, pcSlice);
       }
+#if JVET_M0132
+      if (pcSlice->getSPS()->getALFEnabledFlag() && pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y])
+      {
+        pcSlice->setAPSId(pcSlice->getAPS()->getAPSId());
+        pcSlice->getAPS()->setAlfAPSParam(pcSlice->getAlfSliceParam());
+        actualTotalBits += xWriteAPS(accessUnit, pcSlice->getAPS());
+      }
+#endif
 
       // reset presence of BP SEI indication
       m_bufferingPeriodSEIPresentInAU = false;
diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h
index e2c11c170105b077021b497b661030ac06930798..975609f7b29f92a5dded3f48bada224ae0565a0e 100644
--- a/source/Lib/EncoderLib/EncGOP.h
+++ b/source/Lib/EncoderLib/EncGOP.h
@@ -281,6 +281,9 @@ protected:
 #endif
   int xWriteSPS (AccessUnit &accessUnit, const SPS *sps);
   int xWritePPS (AccessUnit &accessUnit, const PPS *pps);
+#if JVET_M0132
+  int xWriteAPS(AccessUnit &accessUnit, APS *aps);
+#endif
   int xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst);
 
   void applyDeblockingFilterMetric( Picture* pcPic, uint32_t uiNumSlices );
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index c975d68d8e9c510d259ed15273a0adfaa4dcb8b6..b73b3ac67590eb587c3c8c64c68f48fadde97fba 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -60,6 +60,9 @@
 EncLib::EncLib()
   : m_spsMap( MAX_NUM_SPS )
   , m_ppsMap( MAX_NUM_PPS )
+#if JVET_M0132
+  , m_apsMap( MAX_NUM_APS )
+#endif
   , m_AUWriterIf( nullptr )
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   , m_cacheModel()
@@ -214,6 +217,9 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
 
   SPS &sps0=*(m_spsMap.allocatePS(0)); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues.
   PPS &pps0=*(m_ppsMap.allocatePS(0));
+#if JVET_M0132
+  APS &aps0=*(m_apsMap.allocatePS(0));
+#endif
 
   // initialize SPS
   xInitSPS(sps0);
@@ -251,6 +257,10 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
 
   // initialize PPS
   xInitPPS(pps0, sps0);
+#if JVET_M0132
+  // initialize APS
+  xInitAPS(aps0);
+#endif
   xInitRPS(sps0, isFieldCoding);
 
 #if ER_CHROMA_QP_WCG_PPS
@@ -376,7 +386,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     Picture *picBg = new Picture;
     picBg->create(sps0.getChromaFormatIdc(), Size(sps0.getPicWidthInLumaSamples(), sps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + 16, false);
     picBg->getRecoBuf().fill(0);
+#if JVET_M0132
+    picBg->finalInit(sps0, pps0, aps0);
+#else
     picBg->finalInit(sps0, pps0);
+#endif
     picBg->allocateNewSlice();
     picBg->createSpliceIdx(pps0.pcv->sizeInCtus);
     m_cGOPEncoder.setPicBg(picBg);
@@ -527,7 +541,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru
     const SPS *sps = m_spsMap.getPS(pps->getSPSId());
 
     picCurr->M_BUFS(0, PIC_ORIGINAL).copyFrom(m_cGOPEncoder.getPicBg()->getRecoBuf());
+#if JVET_M0132
+    APS *aps = m_apsMap.getPS(0);
+    picCurr->finalInit(*sps, *pps, *aps);
+#else
     picCurr->finalInit(*sps, *pps);
+#endif
     picCurr->poc = m_iPOCLast - 1;
     m_iPOCLast -= 2;
     if (getUseAdaptiveQP())
@@ -578,7 +597,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru
       pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL).swap(*cPicYuvTrueOrg);
 #endif
 
+#if JVET_M0132
+      APS *pAPS = m_apsMap.getPS(0);
+      pcPicCurr->finalInit(*pSPS, *pPPS, *pAPS);
+#else
       pcPicCurr->finalInit( *pSPS, *pPPS );
+#endif
     }
 
     pcPicCurr->poc = m_iPOCLast;
@@ -673,7 +697,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr
         const PPS *pPPS=(ppsID<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsID);
         const SPS *pSPS=m_spsMap.getPS(pPPS->getSPSId());
 
+#if JVET_M0132
+        APS *pAPS = m_apsMap.getPS(0);
+        pcField->finalInit(*pSPS, *pPPS, *pAPS);
+#else
         pcField->finalInit( *pSPS, *pPPS );
+#endif
       }
 
       pcField->poc = m_iPOCLast;
@@ -1492,6 +1521,12 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
   pps.pcv = new PreCalcValues( sps, pps, true );
 }
 
+#if JVET_M0132
+void EncLib::xInitAPS(APS &aps)
+{
+  //Do nothing now
+}
+#endif
 //Function for initializing m_RPSList, a list of ReferencePictureSet, based on the GOPEntry objects read from the config file.
 void EncLib::xInitRPS(SPS &sps, bool isFieldCoding)
 {
@@ -1864,6 +1899,14 @@ void EncLib::setParamSetChanged(int spsId, int ppsId)
   m_spsMap.setChangedFlag(spsId);
 }
 #endif
+#if JVET_M0132
+bool EncLib::APSNeedsWriting(int apsId)
+{
+  bool bChanged = m_apsMap.getChangedFlag(apsId);
+  m_apsMap.clearChangedFlag(apsId);
+  return bChanged;
+}
+#endif
 
 bool EncLib::PPSNeedsWriting(int ppsId)
 {
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index d143e79b28d3d2554017022d95bfe44d2e293f89..9d70ff9db60e626c5eea678933a4bde13fd6eb84 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -116,6 +116,9 @@ private:
   // SPS
   ParameterSetMap<SPS>      m_spsMap;                             ///< SPS. This is the base value. This is copied to PicSym
   ParameterSetMap<PPS>      m_ppsMap;                             ///< PPS. This is the base value. This is copied to PicSym
+#if JVET_M0132
+  ParameterSetMap<APS>      m_apsMap;                             ///< APS. This is the base value. This is copied to PicSym
+#endif
   // RD cost computation
 #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
   RdCost                   *m_cRdCost;                            ///< RD cost computation class
@@ -150,6 +153,9 @@ protected:
 #endif
   void  xInitSPS          (SPS &sps);                 ///< initialize SPS from encoder options
   void  xInitPPS          (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options
+#if JVET_M0132
+  void  xInitAPS          (APS &aps);                 ///< initialize APS from encoder options
+#endif
 #if HEVC_USE_SCALING_LISTS
   void  xInitScalingLists (SPS &sps, PPS &pps);   ///< initialize scaling lists
 #endif
@@ -219,10 +225,16 @@ public:
 
 #if JCTVC_Y0038_PARAMS
   void                   setParamSetChanged(int spsId, int ppsId);
+#endif
+#if JVET_M0132
+  bool                   APSNeedsWriting(int apsId);
 #endif
   bool                   PPSNeedsWriting(int ppsId);
   bool                   SPSNeedsWriting(int spsId);
   const PPS* getPPS( int Id ) { return m_ppsMap.getPS( Id); }
+#if JVET_M0132
+  const APS*             getAPS(int Id) { return m_apsMap.getPS(Id); }
+#endif
 
 #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
   void                   setNumCuEncStacks( int n )             { m_numCuEncStacks = n; }
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index e28d975da3553ebe0de3d39031ab4750dc348b75..50accf3328b191cdecaf3c86c3d8783bea88730c 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -365,6 +365,33 @@ void HLSWriter::codePPS( const PPS* pcPPS )
   xWriteRbspTrailingBits();
 }
 
+#if JVET_M0132
+void HLSWriter::codeAPS( APS* pcAPS)
+{
+  AlfSliceParam param = pcAPS->getAlfAPSParam();
+  WRITE_CODE(pcAPS->getAPSId(), 5, "adaptation_parameter_set_id");
+
+  const int alfChromaIdc = param.enabledFlag[COMPONENT_Cb] * 2 + param.enabledFlag[COMPONENT_Cr];
+  truncatedUnaryEqProb(alfChromaIdc, 3);   // alf_chroma_idc
+
+  xWriteTruncBinCode(param.numLumaFilters - 1, MAX_NUM_ALF_CLASSES);  //number_of_filters_minus1
+  if (param.numLumaFilters > 1)
+  {
+    for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++)
+    {
+      xWriteTruncBinCode((uint32_t)param.filterCoeffDeltaIdx[i], param.numLumaFilters);  //filter_coeff_delta[i]
+    }
+  }
+
+  alfFilter(param, false);
+
+  if (alfChromaIdc)
+  {
+    alfFilter(param, true);
+  }
+  xWriteRbspTrailingBits();
+}
+#endif
 void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS )
 {
 #if ENABLE_TRACING
@@ -1179,7 +1206,15 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
 
     if( pcSlice->getSPS()->getALFEnabledFlag() )
     {
+#if JVET_M0132
+      WRITE_FLAG(pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y], "tile_group_alf_enabled_flag");
+      if (pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y])
+      {
+        WRITE_CODE(pcSlice->getAPSId(), 5, "tile_group_aps_id");
+      }
+#else
       alf( pcSlice->getAlfSliceParam() );
+#endif
     }
 
     //check if numrefidxes match the defaults. If not, override
@@ -1729,6 +1764,7 @@ bool HLSWriter::xFindMatchingLTRP(Slice* pcSlice, uint32_t *ltrpsIndex, int ltrp
   return false;
 }
 
+#if !JVET_M0132
 void HLSWriter::alf( const AlfSliceParam& alfSliceParam )
 {
   WRITE_FLAG( alfSliceParam.enabledFlag[COMPONENT_Y], "tile_group_alf_enabled_flag" );
@@ -1756,6 +1792,7 @@ void HLSWriter::alf( const AlfSliceParam& alfSliceParam )
     alfFilter( alfSliceParam, true );
   }
 }
+#endif
 
 void HLSWriter::alfGolombEncode( int coeff, int k )
 {
diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h
index b3866e8ab3a78c22f66574ec4eda016167dc362d..e1e3fd853e7c866b0306e94b1cf4785f03198bd2 100644
--- a/source/Lib/EncoderLib/VLCWriter.h
+++ b/source/Lib/EncoderLib/VLCWriter.h
@@ -122,6 +122,9 @@ public:
   void  codeVUI                 ( const VUI *pcVUI, const SPS* pcSPS );
   void  codeSPS                 ( const SPS* pcSPS );
   void  codePPS                 ( const PPS* pcPPS );
+#if JVET_M0132
+  void  codeAPS                 ( APS* pcAPS);
+#endif
 #if HEVC_VPS
   void  codeVPS                 ( const VPS* pcVPS );
 #endif
@@ -136,7 +139,9 @@ public:
   void  codeScalingList         ( const ScalingList &scalingList );
 #endif
 
+#if !JVET_M0132
   void alf( const AlfSliceParam& alfSliceParam );
+#endif
   void alfFilter( const AlfSliceParam& alfSliceParam, const bool isChroma );
 
 private: