diff --git a/src/mesh/ConnectivityDispatcher.cpp b/src/mesh/ConnectivityDispatcher.cpp
index fd99475c2ecdeff01c8aa477e0437d84e08259e5..08fea56bfd2d023b0defffa79a0ed3aeb34d3723 100644
--- a/src/mesh/ConnectivityDispatcher.cpp
+++ b/src/mesh/ConnectivityDispatcher.cpp
@@ -411,189 +411,203 @@ _buildRecvItemIdCorrespondanceByProc()
 }
 
 template <int Dimension>
+template <ItemType item_type>
 void
-ConnectivityDispatcher<Dimension>::_dispatchFaces()
+ConnectivityDispatcher<Dimension>::_buildItemReferenceList()
 {
-  if constexpr (Dimension>1) {
-    this->_buildNumberOfSubItemPerItemToRecvByProc<FaceOfCell>();
-    this->_buildSubItemNumbersToRecvByProc<FaceOfCell>();
-    this->_buildSubItemNumberToIdMap<FaceOfCell>();
-    this->_buildItemToExchangeLists<ItemType::face>();
-
-    this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector);
-
-    this->_buildItemToSubItemDescriptor<FaceOfCell>();
-
-    this->_gatherFrom(m_connectivity.cellFaceIsReversed(), m_new_descriptor.cell_face_is_reversed_vector);
-
-    this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector);
-
-    this->_buildNumberOfSubItemPerItemToRecvByProc<NodeOfFace>();
-    this->_buildSubItemNumbersToRecvByProc<NodeOfFace>();
-    this->_buildItemToSubItemDescriptor<NodeOfFace>();
+  using ItemId = ItemIdT<item_type>;
 
-    // Getting references
-    Array<const size_t> number_of_ref_face_list_per_proc
-        = parallel::allGather(m_connectivity.numberOfRefFaceList());
+  // Getting references
+  Array<const size_t> number_of_item_ref_list_per_proc
+      = parallel::allGather(m_connectivity.numberOfRefFaceList());
 
-    const size_t number_of_face_list_sender
-        = [&] () {
-            size_t number_of_face_list_sender=0;
-            for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
-              number_of_face_list_sender
-                  += (number_of_ref_face_list_per_proc[i_rank] > 0);
-            }
-            return number_of_face_list_sender;
-          }();
-
-    if (number_of_face_list_sender > 0) {
-      if (number_of_face_list_sender > 1) {
-        perr() << __FILE__ << ':' << __LINE__ << ": "
-               << rang::fgB::red
-               <<"need to check that knowing procs know the same ref_face_lists!"
-               << rang::fg::reset << '\n';
-      }
+  const size_t number_of_item_list_sender
+      = [&] () {
+          size_t number_of_item_list_sender=0;
+          for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
+            number_of_item_list_sender
+                += (number_of_item_ref_list_per_proc[i_rank] > 0);
+          }
+          return number_of_item_list_sender;
+        }();
+
+  if (number_of_item_list_sender > 0) {
+    if (number_of_item_list_sender > 1) {
+      perr() << __FILE__ << ':' << __LINE__ << ": "
+             << rang::fgB::red
+             <<"need to check that knowing procs know the same item_ref_lists!"
+             << rang::fg::reset << '\n';
+    }
 
-      if (number_of_face_list_sender < parallel::size()) {
-        const size_t sender_rank
-            = [&] () {
-                size_t i_rank = 0;
-                for (; i_rank < parallel::size(); ++i_rank) {
-                  if (number_of_ref_face_list_per_proc[i_rank] > 0) {
-                    break;
-                  }
+    if (number_of_item_list_sender < parallel::size()) {
+      const size_t sender_rank
+          = [&] () {
+              size_t i_rank = 0;
+              for (; i_rank < parallel::size(); ++i_rank) {
+                if (number_of_item_ref_list_per_proc[i_rank] > 0) {
+                  break;
                 }
-                return i_rank;
-              }();
-
-        Assert(number_of_face_list_sender < parallel::size());
-
-        // sending references tags
-        Array<RefId::TagNumberType> ref_tag_list{number_of_ref_face_list_per_proc[sender_rank]};
-        if (parallel::rank() == sender_rank){
-          for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList();
-               ++i_ref_face_list) {
-            auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list);
-            ref_tag_list[i_ref_face_list] = ref_face_list.refId().tagNumber();
-          }
+              }
+              return i_rank;
+            }();
+
+      Assert(number_of_item_list_sender < parallel::size());
+
+      // sending references tags
+      Array<RefId::TagNumberType> ref_tag_list{number_of_item_ref_list_per_proc[sender_rank]};
+      if (parallel::rank() == sender_rank){
+        for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList();
+             ++i_item_ref_list) {
+          auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list);
+          ref_tag_list[i_item_ref_list] = item_ref_list.refId().tagNumber();
         }
-        parallel::broadcast(ref_tag_list, sender_rank);
-
-        // sending references name size
-        Array<size_t> ref_name_size_list{number_of_ref_face_list_per_proc[sender_rank]};
-        if (parallel::rank() == sender_rank){
-          for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList();
-               ++i_ref_face_list) {
-            auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list);
-            ref_name_size_list[i_ref_face_list] = ref_face_list.refId().tagName().size();
-          }
+      }
+      parallel::broadcast(ref_tag_list, sender_rank);
+
+      // sending references name size
+      Array<size_t> ref_name_size_list{number_of_item_ref_list_per_proc[sender_rank]};
+      if (parallel::rank() == sender_rank){
+        for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList();
+             ++i_item_ref_list) {
+          auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list);
+          ref_name_size_list[i_item_ref_list] = item_ref_list.refId().tagName().size();
         }
-        parallel::broadcast(ref_name_size_list, sender_rank);
-
-        // sending references name size
-        Array<RefId::TagNameType::value_type> ref_name_cat{sum(ref_name_size_list)};
-        if (parallel::rank() == sender_rank){
-          size_t i_char=0;
-          for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList();
-               ++i_ref_face_list) {
-            auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list);
-            for (auto c : ref_face_list.refId().tagName()) {
-              ref_name_cat[i_char++] = c;
-            }
+      }
+      parallel::broadcast(ref_name_size_list, sender_rank);
+
+      // sending references name size
+      Array<RefId::TagNameType::value_type> ref_name_cat{sum(ref_name_size_list)};
+      if (parallel::rank() == sender_rank){
+        size_t i_char=0;
+        for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList();
+             ++i_item_ref_list) {
+          auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list);
+          for (auto c : item_ref_list.refId().tagName()) {
+            ref_name_cat[i_char++] = c;
           }
         }
-        parallel::broadcast(ref_name_cat, sender_rank);
-
-        std::vector<RefId> ref_id_list
-            = [&] () {
-                std::vector<RefId> ref_id_list;
-                ref_id_list.reserve(ref_name_size_list.size());
-                size_t begining=0;
-                for (size_t i_ref=0; i_ref < ref_name_size_list.size(); ++i_ref) {
-                  const size_t size = ref_name_size_list[i_ref];
-                  ref_id_list.emplace_back(ref_tag_list[i_ref],
-                                           std::string{&(ref_name_cat[begining]), size});
-                  begining += size;
-                }
-                return ref_id_list;
-              } ();
-
-        using block_type = int32_t;
-        constexpr size_t block_size = sizeof(block_type);
-        const size_t nb_block = ref_id_list.size()/block_size + (ref_id_list.size()%block_size != 0);
-        for (size_t i_block=0; i_block<nb_block; ++i_block) {
-          FaceValue<block_type> face_references(m_connectivity);
-          face_references.fill(0);
-
-          if (m_connectivity.numberOfRefFaceList() > 0) {
-            const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1));
-            for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) {
-              block_type ref_bit{1<<i};
-              auto ref_face_list = m_connectivity.refFaceList(i_ref);
-
-              const auto& face_list = ref_face_list.faceList();
-              for (size_t i_face=0; i_face<face_list.size(); ++i_face) {
-                const FaceId& face_id = face_list[i_face];
-                face_references[face_id] |= ref_bit;
+      }
+      parallel::broadcast(ref_name_cat, sender_rank);
+
+      std::vector<RefId> ref_id_list
+          = [&] () {
+              std::vector<RefId> ref_id_list;
+              ref_id_list.reserve(ref_name_size_list.size());
+              size_t begining=0;
+              for (size_t i_ref=0; i_ref < ref_name_size_list.size(); ++i_ref) {
+                const size_t size = ref_name_size_list[i_ref];
+                ref_id_list.emplace_back(ref_tag_list[i_ref],
+                                         std::string{&(ref_name_cat[begining]), size});
+                begining += size;
               }
-            }
-          }
-
-          const auto& nb_face_to_send_by_proc =
-              this->_dispatchedInfo<ItemType::face>().m_list_to_send_size_by_proc;
-          const auto& send_face_id_by_proc = m_dispatched_face_info.m_list_to_send_by_proc;
-          std::vector<Array<const block_type>> send_face_refs_by_proc(parallel::size());
-
-          for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-            Array<block_type> send_face_refs(nb_face_to_send_by_proc[i_rank]);
-            const Array<const FaceId> send_face_id = send_face_id_by_proc[i_rank];
-            parallel_for(send_face_id.size(), PASTIS_LAMBDA(const size_t& l) {
-                const FaceId& face_id = send_face_id[l];
-                send_face_refs[l] = face_references[face_id];
-              });
-            send_face_refs_by_proc[i_rank] = send_face_refs;
-          }
+              return ref_id_list;
+            } ();
 
-          std::vector<Array<block_type>> recv_face_refs_by_proc(parallel::size());
-          for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-            recv_face_refs_by_proc[i_rank] = Array<block_type>(m_dispatched_face_info.m_list_to_recv_size_by_proc[i_rank]);
-          }
-          parallel::exchange(send_face_refs_by_proc, recv_face_refs_by_proc);
-
-          const auto& recv_face_id_correspondance_by_proc = m_dispatched_face_info.m_recv_id_correspondance_by_proc;
-          std::vector<block_type> face_refs(m_new_descriptor.face_number_vector.size());
-          for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-            for (size_t r=0; r<recv_face_refs_by_proc[i_rank].size(); ++r) {
-              const FaceId& face_id = recv_face_id_correspondance_by_proc[i_rank][r];
-              face_refs[face_id] = recv_face_refs_by_proc[i_rank][r];
-            }
-          }
+      using block_type = int32_t;
+      constexpr size_t block_size = sizeof(block_type);
+      const size_t nb_block = ref_id_list.size()/block_size + (ref_id_list.size()%block_size != 0);
+      for (size_t i_block=0; i_block<nb_block; ++i_block) {
+        FaceValue<block_type> item_references(m_connectivity);
+        item_references.fill(0);
 
+        if (m_connectivity.numberOfRefFaceList() > 0) {
           const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1));
           for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) {
             block_type ref_bit{1<<i};
+            auto item_ref_list = m_connectivity.refFaceList(i_ref);
 
-            std::vector<FaceId> face_id_vector;
-
-            for (uint32_t i_face=0; i_face<face_refs.size(); ++i_face) {
-              const FaceId face_id{i_face};
-              if (face_refs[face_id] & ref_bit) {
-                face_id_vector.push_back(face_id);
-              }
+            const auto& item_list = item_ref_list.faceList();
+            for (size_t i_item=0; i_item<item_list.size(); ++i_item) {
+              const ItemId& item_id = item_list[i_item];
+              item_references[item_id] |= ref_bit;
             }
+          }
+        }
+
+        const auto& nb_item_to_send_by_proc =
+            this->_dispatchedInfo<item_type>().m_list_to_send_size_by_proc;
+
+        const auto& send_item_id_by_proc =
+            this->_dispatchedInfo<item_type>().m_list_to_send_by_proc;
+
+        std::vector<Array<const block_type>> send_item_refs_by_proc(parallel::size());
+
+        for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+          Array<block_type> send_item_refs(nb_item_to_send_by_proc[i_rank]);
+          const Array<const ItemId> send_item_id = send_item_id_by_proc[i_rank];
+          parallel_for(send_item_id.size(), PASTIS_LAMBDA(const size_t& l) {
+              const ItemId& item_id = send_item_id[l];
+              send_item_refs[l] = item_references[item_id];
+            });
+          send_item_refs_by_proc[i_rank] = send_item_refs;
+        }
+
+        std::vector<Array<block_type>> recv_item_refs_by_proc(parallel::size());
+        for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+          recv_item_refs_by_proc[i_rank] = Array<block_type>(this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc[i_rank]);
+        }
+        parallel::exchange(send_item_refs_by_proc, recv_item_refs_by_proc);
+
+        const auto& recv_item_id_correspondance_by_proc =
+            this->_dispatchedInfo<item_type>().m_recv_id_correspondance_by_proc;
+        std::vector<block_type> item_refs(m_new_descriptor.face_number_vector.size());
+        for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+          for (size_t r=0; r<recv_item_refs_by_proc[i_rank].size(); ++r) {
+            const ItemId& item_id = recv_item_id_correspondance_by_proc[i_rank][r];
+            item_refs[item_id] = recv_item_refs_by_proc[i_rank][r];
+          }
+        }
+
+        const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1));
+        for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) {
+          block_type ref_bit{1<<i};
 
-            Array<const FaceId> face_id_array = convert_to_array(face_id_vector);
+          std::vector<ItemId> item_id_vector;
 
-            m_new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], face_id_array));
+          for (uint32_t i_item=0; i_item<item_refs.size(); ++i_item) {
+            const ItemId item_id{i_item};
+            if (item_refs[item_id] & ref_bit) {
+              item_id_vector.push_back(item_id);
+            }
           }
 
-          pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n";
+          Array<const ItemId> item_id_array = convert_to_array(item_id_vector);
+
+          m_new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], item_id_array));
         }
+
+        pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n";
       }
     }
   }
 }
 
+template <int Dimension>
+void
+ConnectivityDispatcher<Dimension>::_dispatchFaces()
+{
+  if constexpr (Dimension>1) {
+    this->_buildNumberOfSubItemPerItemToRecvByProc<FaceOfCell>();
+    this->_buildSubItemNumbersToRecvByProc<FaceOfCell>();
+    this->_buildSubItemNumberToIdMap<FaceOfCell>();
+    this->_buildItemToExchangeLists<ItemType::face>();
+
+    this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector);
+
+    this->_buildItemToSubItemDescriptor<FaceOfCell>();
+
+    this->_gatherFrom(m_connectivity.cellFaceIsReversed(), m_new_descriptor.cell_face_is_reversed_vector);
+
+    this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector);
+
+    this->_buildNumberOfSubItemPerItemToRecvByProc<NodeOfFace>();
+    this->_buildSubItemNumbersToRecvByProc<NodeOfFace>();
+    this->_buildItemToSubItemDescriptor<NodeOfFace>();
+
+    this->_buildItemReferenceList<ItemType::face>();
+  }
+}
+
 
 template <int Dimension>
 ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType& connectivity)
diff --git a/src/mesh/ConnectivityDispatcher.hpp b/src/mesh/ConnectivityDispatcher.hpp
index 13eb5e69cc14685587ef4b7883a3543148b3d29e..d6a97afcb2bf2459d03e6ce34635b2d05e5b78c6 100644
--- a/src/mesh/ConnectivityDispatcher.hpp
+++ b/src/mesh/ConnectivityDispatcher.hpp
@@ -193,6 +193,9 @@ class ConnectivityDispatcher
   template <ItemType item_type>
   void _buildRecvItemIdCorrespondanceByProc();
 
+  template <ItemType item_type>
+  void _buildItemReferenceList();
+
  public:
   std::shared_ptr<const ConnectivityType>
   dispatchedConnectivity() const