diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index c0f2a3c5e6c44a7d65d02876755ef06cd699272b..3bf06398eb079f23e22f33c22346461781352e97 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -904,6 +904,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:
@@ -920,7 +923,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 6dace0a709eef2bb55ed451856bd234dc5b13bcb..69f265d051f1beab6b764084e55a27616a5b6bbf 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 ea525d0bacfa5ef980ea5712ce36c9630b98ddfe..d00a9c0e68ac065b823410941fe1774e84b4eae5 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -192,6 +192,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 2e159e83d95600a8943011f128319f1e38e19250..76d36f27f48ebf3f75a89a67881600aba5bf372b 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 ec8f544c1703f9f5d6d9f9e69ff2b2c211b3ea29..4279429f0c8e4525dcdc70ebf6cae6d5c660cc00 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -138,6 +138,10 @@ Slice::Slice()
 , m_uiMaxBTSizeIChroma            ( 0 )
 , m_uiMaxTTSizeIChroma            ( 0 )
 , m_uiMaxBTSize                   ( 0 )
+#if JVET_M0132
+, m_apsId                        ( -1 )
+, m_aps                          (NULL)
+#endif
 {
   for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
   {
@@ -1932,6 +1936,16 @@ PPS::~PPS()
   delete pcv;
 }
 
+#if JVET_M0132
+APS::APS()
+: m_APSId(0)
+{
+}
+
+APS::~APS()
+{
+}
+#endif
 ReferencePictureSet::ReferencePictureSet()
 : m_numberOfPictures (0)
 , m_numberOfNegativePictures (0)
@@ -2410,6 +2424,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
@@ -2520,6 +2537,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)
 {
@@ -2645,6 +2684,13 @@ void xTracePPSHeader()
   DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set  ===========\n" );
 }
 
+#if JVET_M0132
+void xTraceAPSHeader()
+{
+  DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set  ===========\n");
+}
+#endif
+
 void xTraceSliceHeader()
 {
   DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index aed91d3018085d9b0673273f51819a524a1a1676..00133d319b2883453a4f73f11d12ba18854187f1 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1563,6 +1563,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,
@@ -1719,6 +1737,10 @@ private:
   uint32_t                   m_uiMaxTTSizeIChroma;
   uint32_t                       m_uiMaxBTSize;
 
+#if JVET_M0132
+  int                        m_apsId;
+  APS*                       m_aps;
+#endif
   AlfSliceParam              m_alfSliceParam;
 #if JVET_M0427_INLOOP_RESHAPER
   SliceReshapeInfo           m_sliceReshapeInfo;
@@ -1740,6 +1762,12 @@ public:
 
   void                        setPPSId( int PPSId )                                  { m_iPPSId = PPSId;                                             }
   int                         getPPSId() const                                       { return m_iPPSId;                                              }
+#if JVET_M0132
+  void                        setAPS(APS* aps)                                     { m_aps = aps; m_apsId = (aps) ? aps->getAPSId() : -1; }
+  APS*                        getAPS()                                               { return m_aps;                                               }
+  void                        setAPSId(int apsId)                                    { m_apsId = apsId;                                             }
+  int                         getAPSId() const                                       { return m_apsId;                                              }
+#endif
   void                        setPicOutputFlag( bool b   )                           { m_PicOutputFlag = b;                                          }
   bool                        getPicOutputFlag() const                               { return m_PicOutputFlag;                                       }
   void                        setSaoEnabledFlag(ChannelType chType, bool s)          {m_saoEnabledFlag[chType] =s;                                   }
@@ -2197,6 +2225,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
@@ -2208,6 +2244,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
@@ -2302,6 +2341,9 @@ void xTraceVPSHeader();
 #endif
 void xTraceSPSHeader();
 void xTracePPSHeader();
+#if JVET_M0132
+void xTraceAPSHeader();
+#endif
 void xTraceSliceHeader();
 void xTraceAccessUnitDelimiter();
 #endif
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index e91a15bd65e45e43c14e26cea62bf94aa6f2fd80..64da37c58ff250291d083dadef6877493bc6f2f9 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -332,6 +332,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
 // ====================================================================================================================
@@ -977,6 +978,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 aaaf094cb4e429137a02681275fd9db31e812f75..977b832307c0edcc3c0c9ef326dc496c4ed89a04 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -738,6 +738,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");
 
@@ -751,6 +758,11 @@ void DecLib::xActivateParameterSets()
     m_parameterSetManager.clearSPSChangedFlag(sps->getSPSId());
     m_parameterSetManager.clearPPSChangedFlag(pps->getPPSId());
 
+#if JVET_M0132  //Hendry
+    if (aps != 0)
+      m_parameterSetManager.clearAPSChangedFlag(aps->getAPSId());
+#endif
+
     if (false == m_parameterSetManager.activatePPS(m_apcSlicePilot->getPPSId(),m_apcSlicePilot->isIRAP()))
     {
       THROW("Parameter set activation failed!");
@@ -770,7 +782,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();
@@ -784,6 +800,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();
 
@@ -791,6 +810,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
@@ -866,11 +888,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
@@ -885,6 +912,12 @@ void DecLib::xActivateParameterSets()
     {
       EXIT("Error - a new PPS has been decoded while processing a picture");
     }
+#if JVET_M0132
+    if (aps && m_parameterSetManager.getAPSChangedFlag(aps->getAPSId()))
+    {
+      EXIT("Error - a new APS has been decoded while processing a picture");
+    }
+#endif
 
     xParsePrefixSEImessages();
 
@@ -1049,6 +1082,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
@@ -1403,6 +1443,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;
@@ -1428,6 +1477,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 fe569ddae0d692b105b2783bfa425125bd911e83..0ffac78e941435d56b0731ab19c2a50981553872 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 32afc7e3f1bb73bc860be7b9be7b07e00d662689..99118d9270cd188d238d9689a539bc97797d3a45 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -607,6 +607,52 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
   xReadRbspTrailingBits();
 }
 
+#if JVET_M0132
+void HLSyntaxReader::parseAPS(APS* aps)
+{
+#if ENABLE_TRACING
+  xTraceAPSHeader();
+#endif
+
+  uint32_t  code;
+
+  READ_CODE(5, code, "adaptation_parameter_set_id");
+  aps->setAPSId(code);
+
+  AlfSliceParam param = aps->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);
+  }
+  aps->setAlfAPSParam(param);
+
+  xReadRbspTrailingBits();
+}
+#endif
+
 void  HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS)
 {
 #if ENABLE_TRACING
@@ -1601,7 +1647,26 @@ 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));
+        AlfSliceParam alfParam = pcSlice->getAPS()->getAlfAPSParam();
+        pcSlice->setAlfSliceParam(alfParam);
+        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())
@@ -2426,6 +2491,7 @@ bool HLSyntaxReader::xMoreRbspData()
   return (cnt>0);
 }
 
+#if !JVET_M0132
 void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam )
 {
   uint32_t code;
@@ -2464,6 +2530,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 ca313995e1f63b8c4474f1cd1bfecef584eb6f0a..850f0148f875035e4d7e8ae6acb55d545d1fd6eb 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)
 {
@@ -2549,6 +2559,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 e62fedc1c3a0b48504df6fe83c39b7be27aa749c..51b54e0632ff493eaf0625e3af963efe2c0aea5c 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
@@ -385,7 +395,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);
@@ -536,7 +550,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())
@@ -587,7 +606,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;
@@ -682,7 +706,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;
@@ -1487,6 +1516,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)
 {
@@ -1859,6 +1894,14 @@ void EncLib::setParamSetChanged(int spsId, int ppsId)
   m_spsMap.setChangedFlag(spsId);
 }
 #endif
+#if JVET_M0132
+bool EncLib::APSNeedsWriting(int apsId)
+{
+  bool isChanged = m_apsMap.getChangedFlag(apsId);
+  m_apsMap.clearChangedFlag(apsId);
+  return isChanged;
+}
+#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 9b94251dfa2f724c4d71ebfda9beb330f8d0d598..1affff3383d009e4173123cbd7142a8fc0522985 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -365,6 +365,37 @@ void HLSWriter::codePPS( const PPS* pcPPS )
   xWriteRbspTrailingBits();
 }
 
+#if JVET_M0132
+void HLSWriter::codeAPS( APS* pcAPS)
+{
+#if ENABLE_TRACING
+  xTraceAPSHeader();
+#endif
+
+  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 +1210,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 +1768,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 +1796,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: