diff --git a/Control/AthenaServices/src/AthenaOutputStream.cxx b/Control/AthenaServices/src/AthenaOutputStream.cxx
index 240ac711c919db230104f2c757451ce451a65fe2..8701fa4c6513912413ec20f6bc25f79325bc93ac 100644
--- a/Control/AthenaServices/src/AthenaOutputStream.cxx
+++ b/Control/AthenaServices/src/AthenaOutputStream.cxx
@@ -291,7 +291,7 @@ StatusCode AthenaOutputStream::initialize() {
    }
 
    // Check compression settings and print some information about the configuration
-   // Both should be between [5, 23] and high compression should be <= low compression
+   // Both should be between [5, 23] and high compression should be < low compression
    if(m_compressionBitsHigh < 5 || m_compressionBitsHigh > 23) {
      ATH_MSG_INFO("Float compression mantissa bits for high compression " <<
                   "(" << m_compressionBitsHigh << ") is outside the allowed range of [5, 23].");
@@ -304,11 +304,11 @@ StatusCode AthenaOutputStream::initialize() {
      ATH_MSG_INFO("Setting it to the appropriate limit.");
      m_compressionBitsLow = m_compressionBitsLow < 5 ? 5 : 23;
    }
-   if(m_compressionBitsLow < m_compressionBitsHigh) {
-     ATH_MSG_INFO("Float compression mantissa bits for low compression " <<
-                  "(" << m_compressionBitsLow << ") is lower than high compression " <<
-                  "(" << m_compressionBitsHigh << ")! Setting it to the high compression value.");
-     m_compressionBitsLow = m_compressionBitsHigh;
+   if(m_compressionBitsLow <= m_compressionBitsHigh) {
+     ATH_MSG_ERROR("Float compression mantissa bits for low compression " <<
+                   "(" << m_compressionBitsLow << ") is lower than or equal to high compression " <<
+                   "(" << m_compressionBitsHigh << ")! Please check the configuration! ");
+     return StatusCode::FAILURE;
    }
    if(m_compressionListHigh.value().empty() && m_compressionListLow.value().empty()) {
      ATH_MSG_VERBOSE("Both high and low float compression lists are empty. Float compression will NOT be applied.");
@@ -711,79 +711,20 @@ void AthenaOutputStream::addItemObjects(const SG::FolderItem& item,
       }
    }
 
-   // Here we build the list of attributes for the float compression
-   // CompressionList follows the same logic as the ItemList
-   // We find the matching keys, read the string after "Aux.",
-   // tokenize by "." and build an std::set of these to be
-   // communicated to ThinningInfo down below
-   std::vector<unsigned int> comp_bits{ m_compressionBitsHigh, m_compressionBitsLow };
-   std::vector<std::set<std::string>> comp_attr;
-   comp_attr.resize(2);
-   if(item_key.find("Aux.") != string::npos) {
-     // First the high compression list
-     for (SG::IFolder::const_iterator iter = m_compressionDecoderHigh->begin(), iterEnd = m_compressionDecoderHigh->end();
-            iter != iterEnd; iter++) {
-       // First match the IDs for early rejection.
-       if (iter->id() != item_id) {
-         continue;
-       }
-       // Then find the compression item key and the compression list string
-       size_t seppos = iter->key().find(".");
-       string comp_item_key{""}, comp_str{""};
-       if(seppos != string::npos) {
-         comp_item_key = iter->key().substr(0, seppos+1);
-         comp_str = iter->key().substr(seppos+1);
-       } else {
-         comp_item_key = iter->key();
-       }
-       // Proceed only if the keys match and the
-       // compression list string is not empty
-       if (!comp_str.empty() && comp_item_key == item_key) {
-         std::stringstream ss(comp_str);
-         std::string attr;
-         while( std::getline(ss, attr, '.') ) {
-            comp_attr[0].insert(attr);
-         }
-       }
-     }
-     // Then the low compression list
-     // Code duplication is not nice but not worth making modular
-     for (SG::IFolder::const_iterator iter = m_compressionDecoderLow->begin(), iterEnd = m_compressionDecoderLow->end();
-            iter != iterEnd; iter++) {
-       // First match the IDs for early rejection.
-       if (iter->id() != item_id) {
-         continue;
-       }
-       // Then find the compression item key and the compression list string
-       size_t seppos = iter->key().find(".");
-       string comp_item_key{""}, comp_str{""};
-       if(seppos != string::npos) {
-         comp_item_key = iter->key().substr(0, seppos+1);
-         comp_str = iter->key().substr(seppos+1);
-       } else {
-         comp_item_key = iter->key();
+   // Here we build the list of attributes for the lossy float compression
+   // Note that we do not allow m_compressionBitsHigh >= m_compressionBitsLow
+   // Otherwise is, in any case, a logical error and they'd potentially overwrite each other
+   std::map< unsigned int, std::set< std::string > > comp_attr_map;
+   comp_attr_map[ m_compressionBitsHigh ] = buildCompressionSet( m_compressionDecoderHigh, item_id, item_key );
+   comp_attr_map[ m_compressionBitsLow  ] = buildCompressionSet( m_compressionDecoderLow, item_id, item_key );
+
+   // Print some debugging information regarding the lossy float compression configuration
+   for( const auto& it : comp_attr_map ) {
+     ATH_MSG_DEBUG("     Comp Attr " << it.second.size() << " with " << it.first << " mantissa bits.");
+     if ( it.second.size() > 0 ) {
+       for( const auto& attr : it.second ) {
+          ATH_MSG_DEBUG("       >> " << attr);
        }
-       // Proceed only if the keys match and the
-       // compression list string is not empty
-       if (!comp_str.empty() && comp_item_key == item_key) {
-         std::stringstream ss(comp_str);
-         std::string attr;
-         while( std::getline(ss, attr, '.') ) {
-            comp_attr[1].insert(attr);
-         }
-       }
-     }
-   }
-   ATH_MSG_DEBUG("     Comp Attr High: " << comp_attr[0].size() << " with " << comp_bits[0] << " mantissa bits.");
-   if ( comp_attr[0].size() > 0 ) {
-     for(auto attr : comp_attr[0]) {
-        ATH_MSG_DEBUG("       >> " << attr);
-     }
-   }
-   ATH_MSG_DEBUG("     Comp Attr Low: " << comp_attr[1].size() << " with " << comp_bits[1] << " mantissa bits.");
-   if ( comp_attr[1].size() > 0 ) {
-     for(auto attr : comp_attr[1]) {
-        ATH_MSG_DEBUG("       >> " << attr);
      }
    }
 
@@ -939,13 +880,13 @@ void AthenaOutputStream::addItemObjects(const SG::FolderItem& item,
                     // store it in the relevant map that is going to be inserted into
                     // the ThinningCache later on by the ThinningCacheTool
                     xAOD::AuxCompression compression;
-                    compression.setCompressedAuxIDs( comp_attr );
-                    compression.setCompressionBits( comp_bits );
-
-                    compMap[comp_bits[0]] = compression.getCompressedAuxIDs( allVars, true ); // High
-                    compMap[comp_bits[1]] = compression.getCompressedAuxIDs( allVars, false ); // Low
+                    compression.setCompressedAuxIDs( comp_attr_map );
+                    for( const auto& it : compression.getCompressedAuxIDs( allVars ) ) {
+                      if( it.second.size() > 0 ) // insert only if the set is non-empty
+                        compMap[ it.first ] = it.second;
+                    }
 
-                    for(auto& it : compMap) {
+                    for( const auto& it : compMap ) {
                       ATH_MSG_DEBUG( "Lossy float compression level " << it.first <<
                                      " contains " << it.second.size() <<  " elements"
                                      " for container " << key );
@@ -985,6 +926,54 @@ void AthenaOutputStream::addItemObjects(const SG::FolderItem& item,
    }
 }
 
+/// Here we build the list of attributes for the float compression
+/// CompressionList follows the same logic as the ItemList
+/// We find the matching keys, read the string after "Aux.",
+/// tokenize by "." and build an std::set of these to be
+/// communicated to ThinningInfo elsewhere in the code.
+std::set<std::string>
+AthenaOutputStream::buildCompressionSet (const ToolHandle<SG::IFolder>& handle,
+                                         const CLID& item_id,
+                                         const std::string& item_key) const
+{
+  // Create an empty result
+  std::set<std::string> result;
+
+  // Check the item is indeed Aux.
+  if(item_key.find("Aux.") == string::npos) {
+    return result;
+  }
+
+  // First the high compression list
+  for (SG::IFolder::const_iterator iter = handle->begin(), iterEnd = handle->end();
+         iter != iterEnd; iter++) {
+    // First match the IDs for early rejection.
+    if (iter->id() != item_id) {
+      continue;
+    }
+    // Then find the compression item key and the compression list string
+    size_t seppos = iter->key().find(".");
+    string comp_item_key{""}, comp_str{""};
+    if(seppos != string::npos) {
+      comp_item_key = iter->key().substr(0, seppos+1);
+      comp_str = iter->key().substr(seppos+1);
+    } else {
+      comp_item_key = iter->key();
+    }
+    // Proceed only if the keys match and the
+    // compression list string is not empty
+    if (!comp_str.empty() && comp_item_key == item_key) {
+      std::stringstream ss(comp_str);
+      std::string attr;
+      while( std::getline(ss, attr, '.') ) {
+         result.insert(attr);
+      }
+    }
+  }
+
+  // All done, return the result
+  return result;
+}
 
 void AthenaOutputStream::handleVariableSelection (SG::IAuxStoreIO& auxio,
                                                   SG::DataProxy& itemProxy,
diff --git a/Control/AthenaServices/src/AthenaOutputStream.h b/Control/AthenaServices/src/AthenaOutputStream.h
index ae7ad6ae5d8bb5096c6e76c63b2b2e96c6094665..3b8524587ec97495afc6569969efe6c0600dd9ec 100644
--- a/Control/AthenaServices/src/AthenaOutputStream.h
+++ b/Control/AthenaServices/src/AthenaOutputStream.h
@@ -224,6 +224,10 @@ private:
    /// Write MetaData for this stream (by default) or for a substream outputFN (in ES mode)
    void writeMetaData( const std::string outputFN="" );
 
+   /// Helper function for building the compression lists
+   std::set<std::string> buildCompressionSet (const ToolHandle<SG::IFolder>& handle,
+                                              const CLID& item_id,
+                                              const std::string& item_key) const;
 };
 
 #endif // ATHENASERVICES_OUTPUTSTREAM_H
diff --git a/Event/xAOD/xAODCore/Root/AuxCompression.cxx b/Event/xAOD/xAODCore/Root/AuxCompression.cxx
index 57cb5aebaab72267994c62790ed4028897f7058e..d2c5954baa5a6181e6bfe4f53f482a5cfc324046 100644
--- a/Event/xAOD/xAODCore/Root/AuxCompression.cxx
+++ b/Event/xAOD/xAODCore/Root/AuxCompression.cxx
@@ -4,7 +4,6 @@
 
 // System include(s):
 #include <iostream>
-#include <map>
 
 // EDM include(s):
 #include "AthContainers/AuxTypeRegistry.h"
@@ -15,8 +14,7 @@
 namespace xAOD {
 
   AuxCompression::AuxCompression()
-    : m_names{},
-      m_nbits{}
+    : m_compression_map{}
   {
   }
 
@@ -30,12 +28,13 @@ namespace xAOD {
   ///   - A set of variable names, each prefixed by "-", will compress all
   ///     variables but the ones listed.
   ///
-  /// @param attributes The attributes from CompressionList. By convention the first element holds the
-  /// high compression and the second element holds the low compression lists
+  /// @param attributes The attributes from CompressionList.
+  ///                   By convention the key is the nmantissa and the value is the
+  ///                   set of variables that should be compressed at that level.
   ///
-  void AuxCompression::setCompressedAuxIDs( const std::vector< std::set< std::string > >& attributes ) {
+  void AuxCompression::setCompressedAuxIDs( const std::map< unsigned int, std::set< std::string > >& attributes ) {
 
-     m_names = attributes;
+     m_compression_map = attributes;
      return;
   }
 
@@ -45,118 +44,100 @@ namespace xAOD {
   /// be compressed.
   ///
   /// @param fullset The variables to be compressed based on the rules received
-  /// @param highComp Whether to retrieve the high or the low compression list
-  /// @returns The list of variables to be compressed
+  /// @returns The list of variables to be compressed per compression level
   ///
-  SG::auxid_set_t
-  AuxCompression::getCompressedAuxIDs( const SG::auxid_set_t& fullset, const bool& highComp ) const {
-
-    // Find the relevant index
-    const bool idx = highComp ? AuxCompression::High : AuxCompression::Low;
-
-    // Start from an empty list
-    SG::auxid_set_t auxids;
-
-    // Check the simplest case, nothing to be compressed
-    if( m_names.size() < AuxCompression::NTotal || m_names[ idx ].empty() || ( m_names[ idx ].find("-") != m_names[ idx ].end() ) ) {
-      return auxids;
-    }
-
-    // Check that the user only put positive or negative selections on the
-    // list. They can't be mixed.
-    bool sub = false, add = false;
-    std::set< std::string >::const_iterator name_itr = m_names[ idx ].begin();
-    std::set< std::string >::const_iterator name_end = m_names[ idx ].end();
-    for( ; name_itr != name_end; ++name_itr ) {
-       if( ( *name_itr )[ 0 ] == '-' ) {
-          sub = true;
-       } else {
-          add = true;
-       }
-    }
-    if( sub && add ) {
-       // At this level we don't have a handle to the MsgStream,
-       // otherwise it'd be preferred!
-       std::cerr << "xAOD::AuxCompression ERROR Mixing + and - options for "
-                 << "compression attributes" << std::endl;
-       return auxids;  // Ill-defined input, not compressing anything just in case
-    }
-
-    // Loop over the full set, find all float and std::vector<float> variables, add to the list
-    // This is our starting point as we currently compress only floats.
-    // This way we don't mistakenly float compress a random type based on wrong user input.
-    SG::auxid_set_t fauxids;
-
-    for ( const SG::auxid_t& auxid : fullset ) {
-      const std::string cType = SG::AuxTypeRegistry::instance().getTypeName( auxid );
-      if( cType == "float" || cType == "std::vector<float>" ) {
-        fauxids.insert( auxid );
+  std::map< unsigned int, SG::auxid_set_t >
+  AuxCompression::getCompressedAuxIDs( const SG::auxid_set_t& fullset ) const {
+
+    // Create an empty result map
+    std::map< unsigned int, SG::auxid_set_t > result;
+
+    // Loop over the internal map set by setCompressedAuxIDs
+    for(const auto& val : m_compression_map) {
+
+      // Set helper variables
+      const unsigned int nmantissa = val.first;
+      const std::set< std::string > names = val.second;
+
+      // Start from an empty list
+      SG::auxid_set_t auxids;
+
+      // Check the simplest case, nothing to be compressed
+      if( names.empty() || ( names.find("-") != names.end() ) ) {
+        continue;
       }
-    }
-
-    // Check if all floats are to be compressed, if so return the full float list at this point
-    if( m_names[ idx ].find("*") != m_names[ idx ].end() ) {
-      return fauxids;
-    }
-
-    // Here comes the parsing either + or - as in AuxSelection that we follow closely
-    if( add ) {
-      // Build the list of variables to be compressed starting from the empty list
-      name_itr = m_names[ idx ].begin();
-      name_end = m_names[ idx ].end();
+
+      // Check that the user only put positive or negative selections on the
+      // list. They can't be mixed.
+      bool sub = false, add = false;
+      std::set< std::string >::const_iterator name_itr = names.begin();
+      std::set< std::string >::const_iterator name_end = names.end();
       for( ; name_itr != name_end; ++name_itr ) {
-         // Get the ID of this name
-         const SG::auxid_t auxid = SG::AuxTypeRegistry::instance().findAuxID( *name_itr );
-         if( auxid != SG::null_auxid ) {
-            // Add this variable if it exists
-            if( fauxids.test( auxid ) ) {
-               auxids.insert( auxid );
-            }
+         if( ( *name_itr )[ 0 ] == '-' ) {
+            sub = true;
+         } else {
+            add = true;
          }
       }
-    } else {
-      // Build the list of variables to be compressed starting from the full float list
-      auxids = fauxids;
-      // Loop over all float variables and remove if matching
-      for (SG::auxid_t auxid : fauxids) {
-         // Construct the name of this ID
-         const std::string attrname = "-" + SG::AuxTypeRegistry::instance().getName( auxid );
-         // Check if it is in the list to be removed
-         if( m_names[ idx ].find( attrname ) != m_names[ idx ].end() ) {
-            auxids.erase( auxid );
-         }
+      if( sub && add ) {
+         // At this level we don't have a handle to the MsgStream,
+         // otherwise it'd be preferred!
+         std::cerr << "xAOD::AuxCompression ERROR Mixing + and - options for "
+                   << "compression attributes" << std::endl;
+         continue;  // Ill-defined input, not compressing anything just in case
       }
-    }
 
-    // Return the list of variables to be compressed
-    return auxids;
-  }
+      // Loop over the full set, find all float and std::vector<float> variables, add to the list
+      // This is our starting point as we currently compress only floats.
+      // This way we don't mistakenly float compress a random type based on wrong user input.
+      SG::auxid_set_t fauxids;
 
-  /// Set the number of bits to be used in the float compression
-  /// By definition first element stores the high compression
-  /// while the second element stores the low compression configuration
-  ///
-  /// params nbits The vector holding the mantissa bits
-  ///
-  void AuxCompression::setCompressionBits( const std::vector< unsigned int >& nbits ) {
+      for ( const SG::auxid_t& auxid : fullset ) {
+        const std::string cType = SG::AuxTypeRegistry::instance().getTypeName( auxid );
+        if( cType == "float" || cType == "std::vector<float>" ) {
+          fauxids.insert( auxid );
+        }
+      }
 
-    m_nbits = nbits;
-    return;
-  }
+      // Check if all floats are to be compressed
+      if( names.find("*") != names.end() ) {
+        auxids = fauxids;
+      }
+      // Here comes the parsing either + or - as in AuxSelection that we follow closely
+      else if( add ) {
+        // Build the list of variables to be compressed starting from the empty list
+        name_itr = names.begin();
+        name_end = names.end();
+        for( ; name_itr != name_end; ++name_itr ) {
+           // Get the ID of this name
+           const SG::auxid_t auxid = SG::AuxTypeRegistry::instance().findAuxID( *name_itr );
+           if( auxid != SG::null_auxid ) {
+              // Add this variable if it exists
+              if( fauxids.test( auxid ) ) {
+                 auxids.insert( auxid );
+              }
+           }
+        }
+      } else {
+        // Build the list of variables to be compressed starting from the full float list
+        auxids = fauxids;
+        // Loop over all float variables and remove if matching
+        for ( SG::auxid_t auxid : fauxids ) {
+           // Construct the name of this ID
+           const std::string attrname = "-" + SG::AuxTypeRegistry::instance().getName( auxid );
+           // Check if it is in the list to be removed
+           if( names.find( attrname ) != names.end() ) {
+              auxids.erase( auxid );
+           }
+        }
+      }
 
-  /// Get the number of bits to be used in the float compression
-  /// See above for the convention
-  ///
-  /// params highComp Either high or low compression
-  ///
-  unsigned int
-  AuxCompression::getCompressionBits( const bool& highComp ) const {
+      // Finally fill the result map
+      result[ nmantissa ] = auxids;
 
-    // Find the relevant index
-    const bool idx = highComp ? AuxCompression::High : AuxCompression::Low;
+    } // End of loop over internal map
 
-    // Return the number of mantissa bits
-    return m_nbits[ idx ];
+    return result; // Return the result map
   }
 
 } // namespace xAOD
diff --git a/Event/xAOD/xAODCore/xAODCore/AuxCompression.h b/Event/xAOD/xAODCore/xAODCore/AuxCompression.h
index 3d1a726ccb40c784406f29d9c0057b3efc7fd0c5..d287b89349010bf09d385fd0d190661e8b28cb9a 100644
--- a/Event/xAOD/xAODCore/xAODCore/AuxCompression.h
+++ b/Event/xAOD/xAODCore/xAODCore/AuxCompression.h
@@ -6,6 +6,7 @@
 #define XAODCORE_AUXCOMPRESSION_H
 
 // System include(s):
+#include <map>
 #include <set>
 #include <string>
 #include <vector>
@@ -22,31 +23,17 @@ namespace xAOD {
       /// Default constructor
       AuxCompression();
 
-      /// Set which variables should be compressed
+      /// Set which variables should be compressed per compression setting
       virtual void
-      setCompressedAuxIDs( const std::vector< std::set< std::string > >& attributes );
+      setCompressedAuxIDs( const std::map< unsigned int, std::set< std::string > >& attributes );
 
-      /// Return those variables that are selected to be compressed
-      virtual SG::auxid_set_t
-      getCompressedAuxIDs( const SG::auxid_set_t& fullset, const bool& highComp = true ) const;
-
-      /// Set the number of bits that should be used in the compression
-      virtual void
-      setCompressionBits( const std::vector< unsigned int >& nbits );
-
-      /// Return the number of bits that should be used in the compression
-      virtual unsigned int
-      getCompressionBits( const bool& highComp = true ) const;
-
-      /// Enum for the indices used for the high and low compression setup
-      enum FloatCompressionBits { High = 0, Low = 1, NTotal = 2 };
+      /// Return those variables that are selected to be compressed per compression setting
+      virtual std::map< unsigned int, SG::auxid_set_t >
+      getCompressedAuxIDs( const SG::auxid_set_t& fullset ) const;
 
    protected:
       /// Properties following the variable selection convention
-      std::vector< std::set< std::string > > m_names;
-
-      /// Vector holding the number of mantissa bits for the compression
-      std::vector< unsigned int > m_nbits;
+      std::map< unsigned int, std::set< std::string > > m_compression_map;
 
    }; // class AuxCompression