diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 2e76735fa7f04452af11633d832efa72fc442c61..b5d613e4ae4d8e392602a64d4a03cd8752d2e990 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -195,10 +195,14 @@ rrc_mac_config_req(
       }
     }
     else {
-      if (logicalChannelConfig)
-	UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
-      else
-	UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = 0;
+      if (UE_id == -1) {
+        LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
+      } else {
+        if (logicalChannelConfig)
+	  UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
+        else
+	  UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = 0;
+      }
     }
   }
 
@@ -296,7 +300,10 @@ rrc_mac_config_req(
 
   if (physicalConfigDedicated != NULL) {
     if (eNB_flagP==1) {
-      mac_xface->phy_config_dedicated_eNB(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated);
+      if (UE_id == -1)
+        LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
+      else
+        mac_xface->phy_config_dedicated_eNB(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated);
     } else {
       mac_xface->phy_config_dedicated_ue(Mod_idP,0,eNB_index,physicalConfigDedicated);
       UE_mac_inst[Mod_idP].physicalConfigDedicated=physicalConfigDedicated; // for SR proc
@@ -308,7 +315,10 @@ rrc_mac_config_req(
   if (sCellToAddMod_r10 != NULL) {
 
     if (eNB_flagP==1) {
-      mac_xface->phy_config_dedicated_scell_eNB(Mod_idP,UE_RNTI(Mod_idP,UE_id),sCellToAddMod_r10,1);
+      if (UE_id == -1)
+        LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
+      else
+        mac_xface->phy_config_dedicated_scell_eNB(Mod_idP,UE_RNTI(Mod_idP,UE_id),sCellToAddMod_r10,1);
     } else {
 
 	//#warning "phy_config_dedicated_scell_ue is empty"
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index c2098d537a38106013a45d9d331612c209c0f763..1a61c669480e7fe35b6af6d80e885d27cc9dc1da 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -99,7 +99,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
   int           result;
 #endif
   DCI_PDU *DCI_pdu[MAX_NUM_CCs];
-  int CC_id,i,next_i;
+  int CC_id,i; //,next_i;
   UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
   rnti_t rnti;
   void         *DLSCH_dci=NULL;
@@ -121,10 +121,21 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
     memset(eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map,0,100);
   }
 
+  // clear DCI and BCCH contents before scheduling
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    DCI_pdu[CC_id]->Num_common_dci  = 0;
+    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
+#ifdef Rel10
+    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
+#endif
+    eNB_mac_inst[module_idP].frame    = frameP;
+    eNB_mac_inst[module_idP].subframe = subframeP;
+  }
+
   // refresh UE list based on UEs dropped by PHY in previous subframe
-  i = UE_list->head;
+  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    if (UE_list->active[i] != TRUE) continue;
 
-  while (i>=0) {
     rnti = UE_RNTI(module_idP, i);
     CC_id = UE_PCCID(module_idP, i);
     if ((frameP==0)&&(subframeP==0))
@@ -132,8 +143,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
 	    UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync",
 	    UE_list->UE_template[CC_id][i].phr_info);
 
-    next_i= UE_list->next[i];
-
     PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
     if (i==UE_list->head)
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]); 
@@ -261,8 +270,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
 	}
       }
     } // ul_failure_timer>0
-    
-    i = next_i;
   }
 
 #if defined(ENABLE_ITTI)
@@ -319,22 +326,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
 
 #endif
 
-  // clear DCI and BCCH contents before scheduling
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    DCI_pdu[CC_id]->Num_common_dci  = 0;
-    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
-
-
-#ifdef Rel10
-    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
-#endif
-
-    eNB_mac_inst[module_idP].frame    = frameP;
-    eNB_mac_inst[module_idP].subframe = subframeP;
-
-
-  }
-  
 /* #ifndef DISABLE_SF_TRIGGER */
 /*   //Send subframe trigger to the controller */
 /*   if (mac_agent_registered[module_idP]) { */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index e24281b89aeb985a17310d33cb805df5fd20cb18..991f8bfbfa55061de2eab1fdf2216bbc20fe4cbd 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -73,7 +73,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
   unsigned char i,harq_pid,round;
   int16_t rrc_sdu_length;
   unsigned char lcid,offset;
-  module_id_t UE_id= UE_INDEX_INVALID;
+  int UE_id = -1;
   unsigned short TBsize = -1;
   unsigned short msg4_padding,msg4_post_padding,msg4_header;
   uint8_t *vrb_map;
@@ -266,6 +266,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
 
           // check for Msg4 Message
           UE_id = find_UE_id(module_idP,RA_template->rnti);
+          if (UE_id == -1) { printf("%s:%d:%s: FATAL ERROR\n", __FILE__, __LINE__, __FUNCTION__); abort(); }
 
           if (Is_rrc_registered == 1) {
 
@@ -709,7 +710,10 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
 			    RA_template->RA_dci_size_bits2,
 			    RA_template->RA_dci_fmt2,
 			    0);
+printf("MAC: msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
 	  }
+else
+printf("MAC: msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
 	  LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
 		module_idP,CC_id,frameP,subframeP,RA_template->rnti);
 	} else {
@@ -718,6 +722,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
 		  remove UE instance across all the layers: mac_xface->cancel_RA();
 		  }
 	  */
+printf("MAC: msg4 acknowledged for rnti %x fsf %d/%d, let's configure it\n", RA_template->rnti, frameP, subframeP);
 	  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_id,frameP,subframeP);
 	  RA_template->wait_ack_Msg4=0;
 	  RA_template->RA_active=FALSE;
@@ -746,14 +751,26 @@ void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,0);
 
   for (i=0; i<NB_RA_PROC_MAX; i++) {
-    if (RA_template[i].RA_active==FALSE) {
+    if (RA_template[i].RA_active==FALSE &&
+        RA_template[i].wait_ack_Msg4 == 0) {
+      int loop = 0;
       RA_template[i].RA_active=TRUE;
       RA_template[i].generate_rar=1;
       RA_template[i].generate_Msg4=0;
       RA_template[i].wait_ack_Msg4=0;
       RA_template[i].timing_offset=timing_offset;
-      // Put in random rnti (to be replaced with proper procedure!!)
-      RA_template[i].rnti = taus();
+      /* TODO: find better procedure to allocate RNTI */
+      do {
+        RA_template[i].rnti = taus();
+        loop++;
+      } while (loop != 100 &&
+               /* TODO: this is not correct, the rnti may be in use without
+                * being in the MAC yet. To be refined.
+                */
+               !(find_UE_id(module_idP, RA_template[i].rnti) == -1 &&
+                 /* 1024 and 60000 arbirarily chosen, not coming from standard */
+                 RA_template[i].rnti >= 1024 && RA_template[i].rnti < 60000));
+      if (loop == 100) { printf("%s:%d:%s: FATAL ERROR! contact the authors\n", __FILE__, __LINE__, __FUNCTION__); abort(); }
       RA_template[i].RA_rnti = 1+subframeP+(10*f_id);
       RA_template[i].preamble_index = preamble_index;
       LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n",
@@ -763,6 +780,8 @@ void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t
       return;
     }
   }
+
+  LOG_E(MAC,"[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index);
 }
 
 void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rnti)
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 45e79930e524688f107d092019961a8a975d4ab0..3933fe3f8dea5eae172fdc5db8a329732023df98 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -453,9 +453,11 @@ schedule_ue_spec(
   UE_sched_ctrl           *ue_sched_ctl;
   int i;
 
+#if 0
   if (UE_list->head==-1) {
     return;
   }
+#endif
 
   start_meas(&eNB->schedule_dlsch);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index ce08bc54081112e15f1da8874f552347a58d8434..9dfd2f095b230ae3d7595120622b12ab13235c4b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -107,18 +107,17 @@ DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame
 int find_UE_id(module_id_t mod_idP, rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
-
   int UE_id;
   UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
 
-  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
+    if (UE_list->active[UE_id] != TRUE) continue;
     if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
       return(UE_id);
     }
   }
 
   return(-1);
-
 }
 
 //------------------------------------------------------------------------------
@@ -235,21 +234,17 @@ void dump_ue_list(UE_list_t *listP, int ul_flag)
 int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
 {
   int UE_id;
-  int j;
+  int i, j;
 
   UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
 
   LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs);
   dump_ue_list(UE_list,0);
 
-  if (UE_list->avail>=0) {
-    UE_id = UE_list->avail;
-    AssertFatal( UE_id < NUMBER_OF_UE_MAX, "BAD UE_id %u > NUMBER_OF_UE_MAX",UE_id );
-    UE_list->avail = UE_list->next[UE_list->avail];
-    UE_list->next[UE_id] = UE_list->head;
-    UE_list->next_ul[UE_id] = UE_list->head_ul;
-    UE_list->head = UE_id;
-    UE_list->head_ul = UE_id;
+  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    if (UE_list->active[i] == TRUE) continue;
+printf("MAC: new UE id %d rnti %x\n", i, rntiP);
+    UE_id = i;
     UE_list->UE_template[cc_idP][UE_id].rnti       = rntiP;
     UE_list->UE_template[cc_idP][UE_id].configured = FALSE;
     UE_list->numactiveCCs[UE_id]                   = 1;
@@ -273,6 +268,7 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
     return(UE_id);
   }
 
+printf("MAC: cannot add new UE for rnti %x\n", rntiP);
   LOG_E(MAC,"error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
   dump_ue_list(UE_list,0);
   return(-1);
@@ -282,23 +278,27 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
 int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP) 
 //------------------------------------------------------------------------------
 {
-
-  int prev,i, ret=-1;
-
-
+  int i;
   UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
   int UE_id = find_UE_id(mod_idP,rntiP);
-  int pCC_id = UE_PCCID(mod_idP,UE_id);
+  int pCC_id;
 
   if (UE_id == -1) {
+printf("MAC: cannot remove UE rnti %x\n", rntiP);
     LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
-    mac_phy_remove_ue(mod_idP,rntiP);
+    mac_phy_remove_ue(mod_idP, rntiP);
     return 0;
   }
 
+  pCC_id = UE_PCCID(mod_idP,UE_id);
+
+printf("MAC: remove UE %d rnti %x\n", UE_id, rntiP);
   LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
   dump_ue_list(UE_list,0);
 
+  UE_list->active[UE_id] = FALSE;
+  UE_list->num_UEs--;
+
   // clear all remaining pending transmissions
   UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0]  = 0;
   UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1]  = 0;
@@ -313,58 +313,13 @@ int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP)
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].status                      = S_DL_NONE;
 
-  prev = UE_list->head;
-
-  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
-    if (i == UE_id) {
-      // link prev to next in Active list
-      if (i==UE_list->head) {
-        UE_list->head = UE_list->next[i];
-      } else {
-        UE_list->next[prev] = UE_list->next[i];
-      }
-
-      // add UE id (i)to available
-      UE_list->next[i] = UE_list->avail;
-      UE_list->avail = i;
-      UE_list->active[i] = FALSE;
-      UE_list->num_UEs--;
-      ret=0;
-      break;
-    }
-
-    prev=i;
-  }
-
-  // do the same for UL
-  prev = UE_list->head_ul;
-
-  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
-    if (i == UE_id) {
-      // link prev to next in Active list
-      if (i==UE_list->head_ul) {
-        UE_list->head_ul = UE_list->next_ul[i];
-      } else {
-        UE_list->next_ul[prev] = UE_list->next_ul[i];
-      }
-
-      // add UE id (i)to available
-      UE_list->next_ul[i] = UE_list->avail;
-      ret = 0;
-      break;
-    }
-
-    prev=i;
-  }
-
   mac_phy_remove_ue(mod_idP,rntiP);
 
   // check if this has an RA process active
   RA_TEMPLATE *RA_template;
   for (i=0;i<NB_RA_PROC_MAX;i++) {
     RA_template = (RA_TEMPLATE *)&eNB_mac_inst[mod_idP].common_channels[pCC_id].RA_template[i];
-    if ((RA_template->RA_active == TRUE) && 
-	(RA_template->rnti == rntiP)){
+    if (RA_template->rnti == rntiP){
       RA_template->RA_active=FALSE;
       RA_template->generate_rar=0;
       RA_template->generate_Msg4=0;
@@ -372,18 +327,11 @@ int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP)
       RA_template->timing_offset=0;
       RA_template->RRC_timer=20;
       RA_template->rnti = 0;
-      break;
+      //break;
     }
   }
-  if (ret == 0) {
-    return (0);
-  }
-
-  LOG_E(MAC,"error in mac_remove_ue(), could not find previous to %d in UE_list, should never happen, Dumping UE list\n",UE_id);
-  dump_ue_list(UE_list,0);
-  mac_xface->macphy_exit("mac_remove_ue: Problem in UE_list");
-  return(-1);
 
+  return 0;
 }
 
 
@@ -1096,7 +1044,7 @@ try_again:
                 1<<DCI_pdu->dci_alloc[j].L,
                 nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
         }
-	dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,dci_alloc->L);
+	//dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,dci_alloc->L);
 
         goto failed;
       }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 831b00a2f953778e681e08f6ae2b2ed1fb8277e1..3fd1ba6508826ca661ea81ff467c32a52df9bb54 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -751,6 +751,39 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
       continue;
     }
 
+    /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */
+    /* TODO: refine? */
+    drop_ue = 0;
+    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
+      CC_id = UE_list->ordered_ULCCids[n][UE_id];
+      if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) {
+        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
+        drop_ue = 1;
+        break;
+      }
+    }
+    if (drop_ue == 1) {
+/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */
+abort();
+      /* TODO: this is a hack. Sometimes the UE has no PHY context but
+       * is still present in the MAC with 'ul_failure_timer' = 0 and
+       * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's
+       * start an UL out of sync procedure in this case.
+       * The root cause of this problem has to be found and corrected.
+       * In the meantime, this hack...
+       */
+      if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 &&
+          UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) {
+        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n",
+              module_idP,frameP,subframeP,UE_id,rnti,CC_id);
+        // inform RRC of failure and clear timer
+        mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti);
+        UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0;
+        UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1;
+      }
+      continue;
+    }
+
     // loop over all active UL CC_ids for this UE
     for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
       // This is the actual CC_id in the list
@@ -758,15 +791,6 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
       frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
       eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
 
-      if (eNB_UE_stats==NULL) {
-        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
-	drop_ue=1;
-        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
-      }
-
-      if (drop_ue==1)
-	continue;
-
       if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
         LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
         continue; // break;
@@ -882,6 +906,12 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
               T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
               T_INT(TBS), T_INT(ndi));
 
+	    if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
+	      LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
+		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
+		    first_rb[CC_id],rb_table[rb_table_index],
+		    rb_table_index,TBS,harq_pid);
+
 	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
             // increment for next UE allocation
             first_rb[CC_id]+=rb_table[rb_table_index];
@@ -891,12 +921,6 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
 	    if (UE_id == UE_list->head)
 	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
 
-	    if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
-	      LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
-		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
-		    first_rb[CC_id],rb_table[rb_table_index],
-		    rb_table_index,TBS,harq_pid);
-
 	    // adjust total UL buffer status by TBS, wait for UL sdus to do final update
 	    LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS);
 	    if (UE_template->ul_total_buffer > TBS)
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index f0679098da6478450dd4093c339b85789e250fd7..e7bfb348ee7879efa59ad2193c7a3019db86ff74 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -29,6 +29,9 @@
 
  */
 
+#define _GNU_SOURCE
+#include <stdlib.h>
+
 #include "assertions.h"
 #include "PHY/defs.h"
 #include "PHY/extern.h"
@@ -62,6 +65,17 @@
   #endif
 */
 
+/* this function checks that get_eNB_UE_stats returns
+ * a non-NULL pointer for all CCs for a given UE
+ */
+static int phy_stats_exist(module_id_t Mod_id, int rnti)
+{
+  int CC_id;
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
+    if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL)
+      return 0;
+  return 1;
+}
 
 // This function stores the downlink buffer for all the logical channels
 void store_dlsch_buffer (module_id_t Mod_id,
@@ -75,7 +89,8 @@ void store_dlsch_buffer (module_id_t Mod_id,
   UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
   UE_TEMPLATE           *UE_template;
 
-  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
+    if (UE_list->active[UE_id] != TRUE) continue;
 
     UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
 
@@ -155,10 +170,16 @@ void assign_rbs_required (module_id_t Mod_id,
   LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
 
   // clear rb allocations across all CC_ids
-  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
+    if (UE_list->active[UE_id] != TRUE) continue;
+
     pCCid = UE_PCCID(Mod_id,UE_id);
     rnti = UE_list->UE_template[pCCid][UE_id].rnti;
 
+    /* skip UE not present in PHY (for any of its active CCs) */
+    if (!phy_stats_exist(Mod_id, rnti))
+      continue;
+
     //update CQI information across component carriers
     for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
 
@@ -262,7 +283,7 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin
 }
 
 // This function scans all CC_ids for a particular UE to find the maximum DL CQI
-
+// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
 int maxcqi(module_id_t Mod_id,int32_t UE_id)
 {
 
@@ -276,8 +297,9 @@ int maxcqi(module_id_t Mod_id,int32_t UE_id)
     eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,UE_RNTI(Mod_id,UE_id));
 
     if (eNB_UE_stats==NULL) {
-      mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
-      return 0; // not reached
+      /* the UE may have been removed in the PHY layer, don't exit */
+      //mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
+      return -1;
     }
 
     if (eNB_UE_stats->DL_cqi[0] > CQI) {
@@ -288,13 +310,124 @@ int maxcqi(module_id_t Mod_id,int32_t UE_id)
   return(CQI);
 }
 
+struct sort_ue_dl_params {
+  int Mod_idP;
+  int frameP;
+  int subframeP;
+};
+
+static int ue_dl_compare(const void *_a, const void *_b, void *_params)
+{
+  struct sort_ue_dl_params *params = _params;
+  UE_list_t *UE_list = &eNB_mac_inst[params->Mod_idP].UE_list;
+
+  int UE_id1 = *(const int *)_a;
+  int UE_id2 = *(const int *)_b;
+
+  int rnti1  = UE_RNTI(params->Mod_idP, UE_id1);
+  int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
+  int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1);
+
+  int rnti2  = UE_RNTI(params->Mod_idP, UE_id2);
+  int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
+  int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1);
+
+  int cqi1 = maxcqi(params->Mod_idP, UE_id1);
+  int cqi2 = maxcqi(params->Mod_idP, UE_id2);
+
+  if (round1 > round2) return -1;
+  if (round1 < round2) return 1;
+
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] >
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
+    return -1;
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] <
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
+    return 1;
+
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max >
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
+    return -1;
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
+    return 1;
+
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
+    return -1;
+  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
+      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
+    return 1;
+
+  if (cqi1 > cqi2) return -1;
+  if (cqi1 < cqi2) return 1;
+
+  return 0;
+#if 0
+  /* The above order derives from the following.  */
+      if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order
+        swap_UEs(UE_list,UE_id1,UE_id2,0);
+      } else if (round2 == round1) {
+        // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels.  This should be done on the sum of all information that has to be sent.  And still it wouldn't ensure fairness.  It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service.
+        //  for(j=0;j<MAX_NUM_LCID;j++){
+        //    if (eNB_mac_inst[Mod_id][pCC_id1].UE_template[UE_id1].dl_buffer_info[j] <
+        //      eNB_mac_inst[Mod_id][pCC_id2].UE_template[UE_id2].dl_buffer_info[j]){
+
+        // first check the buffer status for SRB1 and SRB2
 
+        if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) <
+             (UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])   ) {
+          swap_UEs(UE_list,UE_id1,UE_id2,0);
+        } else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
+                   UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max   ) {
+          swap_UEs(UE_list,UE_id1,UE_id2,0);
+        } else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
+                   UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total   ) {
+          swap_UEs(UE_list,UE_id1,UE_id2,0);
+        } else if (cqi1 < cqi2) {
+          swap_UEs(UE_list,UE_id1,UE_id2,0);
+        }
+      }
+#endif
+}
 
 // This fuction sorts the UE in order their dlsch buffer and CQI
 void sort_UEs (module_id_t Mod_idP,
                int         frameP,
                sub_frame_t subframeP)
 {
+  int               i;
+  int               list[NUMBER_OF_UE_MAX];
+  int               list_size = 0;
+  int               rnti;
+  struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP };
+
+  UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;
+
+  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    rnti = UE_RNTI(Mod_idP, i);
+    if (rnti == NOT_A_RNTI)
+      continue;
+    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
+      continue;
+    if (!phy_stats_exist(Mod_idP, rnti))
+      continue;
+    list[list_size] = i;
+    list_size++;
+  }
+
+  qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params);
+
+  if (list_size) {
+    for (i = 0; i < list_size-1; i++)
+      UE_list->next[list[i]] = list[i+1];
+    UE_list->next[list[list_size-1]] = -1;
+    UE_list->head = list[0];
+  } else {
+    UE_list->head = -1;
+  }
+
+#if 0
 
 
   int               UE_id1,UE_id2;
@@ -315,6 +448,8 @@ void sort_UEs (module_id_t Mod_idP,
 	continue;
       if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
 	continue;
+      if (!phy_stats_exist(Mod_idP, rnti1))
+        continue;
       pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
       cqi1    = maxcqi(Mod_idP,UE_id1); //
       round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
@@ -325,6 +460,8 @@ void sort_UEs (module_id_t Mod_idP,
         continue;
       if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
 	continue;
+      if (!phy_stats_exist(Mod_idP, rnti2))
+        continue;
       cqi2    = maxcqi(Mod_idP,UE_id2);
       round2  = maxround(Mod_idP,rnti2,frameP,subframeP,0);  //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
       pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
@@ -354,6 +491,7 @@ void sort_UEs (module_id_t Mod_idP,
       }
     }
   }
+#endif
 }
 
 
@@ -407,7 +545,9 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
 
     min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
 
-    for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
+    for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+      if (UE_list->active[i] != TRUE) continue;
+
       UE_id = i;
       // Initialize scheduling information for all active UEs
       
@@ -453,11 +593,9 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
       continue;
     if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
       continue;
-    UE_id = i;
-
-    // if there is no available harq_process, skip the UE
-    if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
+    if (!phy_stats_exist(Mod_id, rnti))
       continue;
+    UE_id = i;
 
     for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
       CC_id = UE_list->ordered_CCids[ii][UE_id];
@@ -465,6 +603,10 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
       harq_pid = ue_sched_ctl->harq_pid[CC_id];
       round    = ue_sched_ctl->round[CC_id];
 
+      // if there is no available harq_process, skip the UE
+      if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
+        continue;
+
       average_rbs_per_user[CC_id]=0;
 
       frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
@@ -506,6 +648,13 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
   for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
     rnti = UE_RNTI(Mod_id,i);
 
+    if(rnti == NOT_A_RNTI)
+      continue;
+    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
+      continue;
+    if (!phy_stats_exist(Mod_id, rnti))
+      continue;
+
     for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
       CC_id = UE_list->ordered_CCids[ii][i];
 
@@ -564,6 +713,8 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
             continue;
 	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
 	    continue;
+          if (!phy_stats_exist(Mod_id, rnti))
+            continue;
 
           transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
 	  //          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
@@ -610,6 +761,8 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
                     continue;
 		  if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
 		    continue;
+                  if (!phy_stats_exist(Mod_idP, rnti2))
+                    continue;
 
                   eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2);
                   //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
@@ -758,6 +911,8 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
   int sf05_upper=-1,sf05_lower=-1;
 #endif
   LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
+  if (eNB_UE_stats == NULL) return;
+
   // initialize harq_pid and round
 
   if (eNB_UE_stats == NULL)
@@ -978,6 +1133,9 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
     if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
       continue;
 
+    if (!phy_stats_exist(module_idP, rnti))
+      continue;
+
     UE_id = i;
 
     for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
@@ -1028,6 +1186,8 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       continue;
     if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
       continue;
+    if (!phy_stats_exist(module_idP, rnti))
+      continue;
 
     UE_id = i;
 
@@ -1058,6 +1218,8 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
         continue;
       if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
 	continue;
+      if (!phy_stats_exist(module_idP, rnti))
+        continue;
 
       UE_id = i;
 
@@ -1115,7 +1277,8 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
   LTE_DL_FRAME_PARMS   *frame_parms;
 
 
-  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
+  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    if (UE_list->active[i] != TRUE) continue;
 
     rnti = UE_RNTI(module_idP,i);
 
@@ -1123,6 +1286,8 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
       continue;
     if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
       continue;
+    if (!phy_stats_exist(module_idP, rnti))
+      continue;
 
     if (UE_list->UE_sched_ctrl[i].phr_received == 1)
       mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs
@@ -1206,10 +1371,103 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
   }
 }
 
+struct sort_ue_ul_params {
+  int module_idP;
+  int frameP;
+  int subframeP;
+};
+
+static int ue_ul_compare(const void *_a, const void *_b, void *_params)
+{
+  struct sort_ue_ul_params *params = _params;
+  UE_list_t *UE_list = &eNB_mac_inst[params->module_idP].UE_list;
+
+  int UE_id1 = *(const int *)_a;
+  int UE_id2 = *(const int *)_b;
+
+  int rnti1  = UE_RNTI(params->module_idP, UE_id1);
+  int pCCid1 = UE_PCCID(params->module_idP, UE_id1);
+  int round1 = maxround(params->module_idP, rnti1, params->frameP, params->subframeP, 1);
+
+  int rnti2  = UE_RNTI(params->module_idP, UE_id2);
+  int pCCid2 = UE_PCCID(params->module_idP, UE_id2);
+  int round2 = maxround(params->module_idP, rnti2, params->frameP, params->subframeP, 1);
+
+  if (round1 > round2) return -1;
+  if (round1 < round2) return 1;
+
+  if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] > UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
+    return -1;
+  if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
+    return 1;
+
+  if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer > UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer)
+    return -1;
+  if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer)
+    return 1;
+
+  if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
+    return -1;
+  if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
+    return 1;
+
+  return 0;
+
+#if 0
+  /* The above order derives from the following.
+   * The last case is not handled: "if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 )"
+   * I don't think it makes a big difference.
+   */
+      if(round2 > round1) {
+        swap_UEs(UE_list,UE_id1,UE_id2,1);
+      } else if (round2 == round1) {
+        if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) {
+          swap_UEs(UE_list,UE_id1,UE_id2,1);
+        } else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer <  UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) {
+          swap_UEs(UE_list,UE_id1,UE_id2,1);
+        } else if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul <  UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) {
+          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) {
+            swap_UEs(UE_list,UE_id1,UE_id2,1);
+          }
+        }
+      }
+#endif
+}
 
 void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
 {
+  int               i;
+  int               list[NUMBER_OF_UE_MAX];
+  int               list_size = 0;
+  int               rnti;
+  struct sort_ue_ul_params params = { module_idP, frameP, subframeP };
 
+  UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list;
+
+  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    rnti = UE_RNTI(module_idP, i);
+    if (rnti == NOT_A_RNTI)
+      continue;
+    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
+      continue;
+    if (!phy_stats_exist(module_idP, rnti))
+      continue;
+    list[list_size] = i;
+    list_size++;
+  }
+
+  qsort_r(list, list_size, sizeof(int), ue_ul_compare, &params);
+
+  if (list_size) {
+    for (i = 0; i < list_size-1; i++)
+      UE_list->next_ul[list[i]] = list[i+1];
+    UE_list->next_ul[list[list_size-1]] = -1;
+    UE_list->head_ul = list[0];
+  } else {
+    UE_list->head_ul = -1;
+  }
+
+#if 0
   int               UE_id1,UE_id2;
   int               pCCid1,pCCid2;
   int               round1,round2;
@@ -1231,6 +1489,8 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
 	continue;
       if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
 	continue;
+      if (!phy_stats_exist(module_idP, rnti1))
+        continue;
 
       pCCid1 = UE_PCCID(module_idP,UE_id1);
       round1  = maxround(module_idP,rnti1,frameP,subframeP,1);
@@ -1242,6 +1502,8 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
         continue;
       if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
 	continue;
+      if (!phy_stats_exist(module_idP, rnti2))
+        continue;
 
       pCCid2 = UE_PCCID(module_idP,UE_id2);
       round2  = maxround(module_idP,rnti2,frameP,subframeP,1);
@@ -1261,4 +1523,5 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
       }
     }
   }
+#endif
 }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index 1d9305548731e5d64e9f31d80a964cbfd52ef3ca..4051a88ef2976da6f625e280329d0ba6cb2af71e 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -557,6 +557,15 @@ rlc_am_mac_status_indication (
   status_resp.head_sdu_is_segmented            = 0;
   status_resp.rlc_info.rlc_protocol_state = rlc->protocol_state;
 
+  /* TODO: remove this hack. Problem is: there is a race.
+   * UE comes. SRB2 is configured via message to RRC.
+   * At some point the RLC AM is created but not configured yet.
+   * At this moment (I think) MAC calls mac_rlc_status_ind
+   * which calls this function. But the init was not finished yet
+   * and we have a crash below when testing mem_block != NULL.
+   */
+  if (rlc->input_sdus == NULL) return status_resp;
+
   if (rlc->last_frame_status_indication != ctxt_pP->frame) {
     rlc_am_check_timer_poll_retransmit(ctxt_pP, rlc);
     rlc_am_check_timer_reordering(ctxt_pP, rlc);
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 5f9a8e0e2a735284cf8b0616ef4f512429a71405..b4290e8b9de4c61219a8580f9b67f7a9d881c5ae 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -99,7 +99,7 @@ int errno;
 # endif
 #endif
 
-#define XER_PRINT
+//#define XER_PRINT
 
 extern Enb_properties_array_t enb_properties;
 typedef struct xer_sprint_string_s {
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 1ed4da9b27e527ca92bb3feea9a220b69c539c32..8b5b012ff1a7178a2a8dcf9a49ea1211abd09020 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -96,7 +96,7 @@
 #if defined(FLEXRAN_AGENT_SB_IF)
 #include "flexran_agent_extern.h"
 #endif
-#define XER_PRINT
+//#define XER_PRINT
 
 #ifdef PHY_EMUL
 extern EMULATION_VARS              *Emul_vars;
@@ -4191,9 +4191,11 @@ rrc_eNB_decode_ccch(
              * the current one must be removed from MAC/PHY (zombie UE)
              */
             if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
-//#warning "TODO: random_exist: remove UE from MAC/PHY (how?)"
-	      //              AssertFatal(0 == 1, "TODO: remove UE from MAC/PHY (how?)");
+              LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
+                    ctxt_pP->rnti, ue_context_p->ue_context.rnti, ctxt_pP->rnti);
+	      rrc_mac_remove_ue(ctxt_pP->module_id, ctxt_pP->rnti);
               ue_context_p = NULL;
+              return 0;
             } else {
               ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
             }
@@ -4204,9 +4206,8 @@ rrc_eNB_decode_ccch(
             m_tmsi_t   m_tmsi   = BIT_STRING_to_uint32(&s_TMSI.m_TMSI);
             random_value = (((uint64_t)mme_code) << 32) | m_tmsi;
             if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) {
-
-		//#warning "TODO: stmsi_exist: remove UE from MAC/PHY (how?)"
 	      LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti);
+	      rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
 	      stmsi_received=1;
               /* replace rnti in the context */
               /* for that, remove the context from the RB tree */
@@ -4218,8 +4219,6 @@ rrc_eNB_decode_ccch(
               /* reset timers */
               ue_context_p->ue_context.ul_failure_timer = 0;
               ue_context_p->ue_context.ue_release_timer = 0;
-	      //   AssertFatal(0 == 1, "TODO: remove UE from MAC/PHY (how?)");
-	      //              ue_context_p = NULL;
             } else {
 	      LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi);
               ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY);
@@ -4230,7 +4229,8 @@ rrc_eNB_decode_ccch(
 	        ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code;
 	        ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi;
               } else {
-                break;
+                /* TODO: do we have to break here? */
+                //break;
               }
             }
 
@@ -4786,6 +4786,7 @@ rrc_eNB_decode_dcch(
 #ifdef XER_PRINT
       xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg);
 #endif
+      LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti);
       dec_rval = uper_decode(NULL,
                              &asn_DEF_UE_EUTRA_Capability,
                              (void **)&UE_EUTRA_Capability,
@@ -4796,7 +4797,7 @@ rrc_eNB_decode_dcch(
                              choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
                              array[0]->ueCapabilityRAT_Container.size, 0, 0);
       //#ifdef XER_PRINT
-      xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability);
+      //xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability);
       //#endif
 
 #if defined(ENABLE_USE_MME)