Index: TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs	(revision 25660)
+++ TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs	(working copy)
@@ -114,9 +114,7 @@
       else
       {
         string timeShiftingFilename = string.Empty;
-        User user = new User();
-        user.Name = "setuptv";
-        user.IsAdmin = true; //fixing mantis bug 1513: recordings you start in manual control can not be stopped  
+        
         //user.Name = "setuptv" + id.ToString();
         int cardId = -1;
         foreach (ListViewItem listViewItem in mpListView1.SelectedItems)
@@ -127,7 +125,12 @@
             break; // Keep the first card enabled selected only
           }
         }
+        
+        User user = new User();
+        user.Name = "setuptv-" + id + "-" + cardId;
+        user.IsAdmin = true;
         user.CardId = cardId;
+
         TvResult result = server.StartTimeShifting(ref user, id, out card, cardId != -1);
         if (result != TvResult.Succeeded)
         {
Index: TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs	(working copy)
@@ -2862,6 +2862,7 @@
       Log.Info("GetConflictingSchedules: Schedule = " + rec);
       List<Schedule> conflicts = new List<Schedule>();
       IList<Schedule> schedulesList = Schedule.ListAll();
+      
       IList<Card> cards = Card.ListAll();
       if (cards.Count == 0)
       {
@@ -2879,20 +2880,18 @@
       // as he decided to keep them before. That's why they are in the db
       foreach (Schedule schedule in schedulesList)
       {
-        List<Schedule> episodes = GetRecordingTimes(schedule);
-        foreach (Schedule episode in episodes)
+        //Only consider the individual episodes and only ones that are still to be recorded.
+        if (schedule.ScheduleType != (int)ScheduleRecordingType.Once || DateTime.Now > schedule.EndTime)
         {
-          if (DateTime.Now > episode.EndTime)
-          {
-            continue;
-          }
-          if (episode.IsSerieIsCanceled(episode.StartTime))
-          {
-            continue;
-          }
-          Schedule overlapping;
-          AssignSchedulesToCard(episode, cardSchedules, out overlapping);
+          continue;
         }
+        if (schedule.IsSerieIsCanceled(schedule.StartTime))
+        {
+          continue;
+        }
+        List<Schedule> overlapping;
+        ;
+        AssignSchedulesToCard(schedule, cardSchedules, out overlapping);
       }
 
       List<Schedule> newEpisodes = GetRecordingTimes(rec);
@@ -2906,53 +2905,27 @@
         {
           continue;
         }
-        Schedule overlapping;
+        List<Schedule> overlapping;
         if (!AssignSchedulesToCard(newEpisode, cardSchedules, out overlapping))
         {
           Log.Info("GetConflictingSchedules: newEpisode can not be assigned to a card = " + newEpisode);
-          conflicts.Add(overlapping);
+          conflicts.AddRange(overlapping);
         }
-
-        /*Log.Info("GetConflictingSchedules: newEpisode = " + newEpisode.ToString());
-        foreach (Schedule schedule in schedulesList)
-        {
-          if (DateTime.Now > schedule.EndTime) continue;
-          if (schedule.Canceled != Schedule.MinSchedule) continue;
-          if (newEpisode.IdSchedule == schedule.IdSchedule) continue;
-
-          List<Schedule> otherEpisodes = GetRecordingTimes(schedule);
-          foreach (Schedule otherEpisode in otherEpisodes)
-          {
-            if (DateTime.Now > otherEpisode.EndTime) continue;
-            if (otherEpisode.Canceled != Schedule.MinSchedule) continue;
-            if (newEpisode.IdSchedule == otherEpisode.IdSchedule) continue;
-
-            if (newEpisode.IsOverlapping(otherEpisode))
-            {
-              Log.Info("GetConflictingSchedules: overlapping -> " + newEpisode.ToString() + "   with   " + otherEpisode.ToString());
-              if (!AssignSchedulesToCard(otherEpisode, cardSchedules))
-              {
-                Log.Info("GetConflictingSchedules: conflicts.Add = " + otherEpisode.ToString());
-                conflicts.Add(otherEpisode);
-              }
-            }
-          }
-        }*/
       }
       return conflicts;
     }
 
     private static bool AssignSchedulesToCard(Schedule schedule, List<Schedule>[] cardSchedules,
-                                              out Schedule overlappingSchedule)
+                                              out List<Schedule> overlappingSchedules)
     {
-      overlappingSchedule = null;
+      overlappingSchedules = new List<Schedule>();
       Log.Info("AssignSchedulesToCard: schedule = " + schedule);
       IList<Card> cards = Card.ListAll();
       bool assigned = false;
       int count = 0;
       foreach (Card card in cards)
       {
-        if (card.canViewTvChannel(schedule.IdChannel))
+        if (card.Enabled && card.canViewTvChannel(schedule.IdChannel))
         {
           // checks if any schedule assigned to this cards overlaps current parsed schedule
           bool free = true;
@@ -2963,7 +2936,7 @@
             {
               if (!(schedule.isSameTransponder(assignedSchedule) && card.supportSubChannels))
               {
-                overlappingSchedule = assignedSchedule;
+                overlappingSchedules.Add(assignedSchedule);
                 Log.Info("AssignSchedulesToCard: overlapping with " + assignedSchedule + " on card {0}, ID = {1}", count,
                          card.IdCard);
                 free = false;
@@ -2975,6 +2948,16 @@
           {
             Log.Info("AssignSchedulesToCard: free on card {0}, ID = {1}", count, card.IdCard);
             cardSchedules[count].Add(schedule);
+            int recommendedCard = schedule.RecommendedCard;
+            if (recommendedCard != card.IdCard)
+            {
+              schedule.RecommendedCard = card.IdCard;
+              //Only update, do not insert
+              if (schedule.IsPersisted)
+              {
+                schedule.Persist();
+              }
+            }
             assigned = true;
             break;
           }
Index: TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs	(working copy)
@@ -384,5 +384,10 @@
              analogChannel.ChannelNumber != ChannelNumber ||
              analogChannel.Frequency != Frequency;
     }
+
+    public bool FreeToAir
+    {
+      get { return true; }
+    }
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/RadioWebStreamChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/RadioWebStreamChannel.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvLibrary.Interfaces/Implementations/Channels/RadioWebStreamChannel.cs	(working copy)
@@ -165,5 +165,13 @@
     {
       return true;
     }
+
+    /// <summary>
+    /// returns whether this channel is FreeToAir
+    /// </summary>
+    public bool FreeToAir
+    {
+      get { return true; }
+    }
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/IChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/IChannel.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/IChannel.cs	(working copy)
@@ -46,5 +46,7 @@
     /// <param name="channel">Channel to check</param>
     /// <returns>true, if the channels are on the same transponder</returns>
     bool IsDifferentTransponder(IChannel channel);
+
+    bool FreeToAir { get; }
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/AdvancedCardAllocation.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/AdvancedCardAllocation.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/AdvancedCardAllocation.cs	(working copy)
@@ -34,25 +34,18 @@
 {
   public class AdvancedCardAllocation : CardAllocationBase, ICardAllocation
   {
-    #region private members    
 
-    private static bool IsCardFoundAndEnabled(List<CardDetail> cardsAvailable, ITvCardHandler cardHandler)
-    {      
-      //get the card info
-      bool isEnabled = false;      
 
-      if (cardsAvailable != null)
-      {
-        bool isFound = !(cardsAvailable.Exists(c => c.Card.DevicePath == cardHandler.DataBaseCard.DevicePath));
+    private readonly TvBusinessLayer _businessLayer;
+    public AdvancedCardAllocation(TvBusinessLayer businessLayer)
+    {
+      _businessLayer = businessLayer;
+    }
 
-        if (isFound)
-        {
-          //check if card is enabled
-          isEnabled = cardHandler.DataBaseCard.Enabled;
-        }
-      }      
-      
-      return isEnabled;
+     #region private members   
+    private static bool IsCardEnabled( ITvCardHandler cardHandler)
+    {      
+      return cardHandler.DataBaseCard.Enabled;
     }
 
     private static bool IsCardPresent(int cardId, string hostName)
@@ -73,126 +66,25 @@
       return isCardPresent;
     }
 
-    private bool CheckTransponder(Channel dbChannel, User user, ITvCardHandler tvcard, int decryptLimit, int cardId,
-                                  IChannel tuningDetail, bool checkTransponders, out bool isSameTransponder,
-                                  out bool canDecrypt)
-    {
-      bool checkTransponder = true;
-      isSameTransponder = (tvcard.Tuner.IsTunedToTransponder(tuningDetail) &&
-                           (tvcard.SupportsSubChannels || (!checkTransponders)));
-      canDecrypt = false;
+   
+    
 
-      bool isOwnerOfCard = tvcard.Users.IsOwner(user);
-      
-      if (isSameTransponder)
-      {
-        if (isOwnerOfCard)
-        {
-          Log.Info("Controller:    card:{0} type:{1} is tuned to same transponder", cardId, tvcard.Type);          
-        } 
-        else
-        {
-          //card is in use, but it is tuned to the same transponder.
-          //meaning.. we can use it.          
-          if (tvcard.HasCA)
-          //does the card have a CA module and a CA limit, if yes then proceed to check cam decrypt limit.
-          {
-            if (decryptLimit > 0)
-            {
-              //but we must check if cam can decode the extra channel as well
-              //first check if cam is already decrypting this channel          
-              bool isCamAlreadyDecodingChannel = IsCamAlreadyDecodingChannel(tvcard, dbChannel);
-
-              //if the user is already using this card
-              //and is watching a scrambled signal
-              //then we must the CAM will always be able to watch the requested channel
-              //since the users zaps
-
-              //check if cam is capable of descrambling an extra channel                            
-              bool isCamAbleToDecrypChannel = IsCamAbleToDecrypChannel(user, tvcard, dbChannel, decryptLimit);
-
-              canDecrypt = isCamAbleToDecrypChannel || isCamAlreadyDecodingChannel;
-
-              if (canDecrypt)
-              {
-                Log.Info("Controller:    card:{0} type:{1} is tuned to same transponder decrypting {2}/{3} channels",
-                         cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, decryptLimit);
-              }
-              else
-              {
-                //it is not, skip this card
-                Log.Info(
-                  "Controller:    card:{0} type:{1} is tuned to same transponder decrypting {2}/{3} channels. cam limit reached",
-                  cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, decryptLimit);
-              }
-
-              checkTransponder = (user.IsAdmin || canDecrypt); 
-            }            
-            else
-            {
-              canDecrypt = true;
-            }
-          }
-          else //fta
-          {
-            canDecrypt = true;
-          }
-        }
-      }
-      else
-      {
-        bool isRecordingAnyUser = tvcard.Recorder.IsRecordingAnyUser();
-        Log.Info("Controller:    card:{0} type:{1} is tuned to different transponder", cardId, tvcard.Type);
-        canDecrypt = true;
-        checkTransponder = ((user.IsAdmin && !isRecordingAnyUser) || isOwnerOfCard);
-      }
-      
-
-      return checkTransponder;
-    }
-
-    private int NumberOfUsersOnCard(Dictionary<int, ITvCardHandler> cards, User user, CardDetail cardInfo)
+    private static int NumberOfOtherUsersOnCard(ITvCardHandler card, User user)
     {
       //determine how many other users are using this card
       int nrOfOtherUsers = 0;
-      User[] users = cards[cardInfo.Id].Users.GetUsers();
+      User[] users = card.Users.GetUsers();
       if (users != null)
       {
         for (int i = 0; i < users.Length; ++i)
         {
-          if (users[i].Name != user.Name)
+          if (users[i].Name != user.Name && !users[i].Name.Equals("epg"))
             nrOfOtherUsers++;
         }
       }
       return nrOfOtherUsers;
     }
 
-    private int CardPriority(int priority, int nrOfOtherUsers, bool sameTransponder, bool canDecrypt, int cardId,
-                             int recommendedCardId)
-    {
-      //if there are other users on this card and we want to switch to another transponder
-      //then set this cards priority as very low...
-      if (nrOfOtherUsers > 0 && !sameTransponder)
-      {
-        priority -= 100;
-      }
-
-      // handle recommended cardid.
-      // boost priority if a cardid matches, but only if these criterias are met.
-      // A) if card is free while other cards are busy.
-      // B) if card is busy (but decryption slot available) while other cards are busy or free.
-
-      if (recommendedCardId == cardId)
-      {
-        if (nrOfOtherUsers == 0 || canDecrypt)
-        {
-          priority += 100;
-        }
-      }
-
-      return priority;
-    }
-
     #endregion    
     
 
@@ -202,182 +94,186 @@
 
     /// <summary>
     /// Gets a list of all free cards which can receive the channel specified
-    /// List is sorted by priority
+    /// List is sorted.
     /// </summary>
     /// <returns>list containg all free cards which can receive the channel</returns>
     public List<CardDetail> GetAvailableCardsForChannel(Dictionary<int, ITvCardHandler> cards, Channel dbChannel,
-                                                        ref User user, bool checkTransponders, out TvResult result,
-                                                        int recommendedCardId)
+                                                        ref User user, out TvResult result)
     {
       Stopwatch stopwatch = Stopwatch.StartNew();
       try
       {        
         //Log.Info("GetAvailableCardsForChannel st {0}", Environment.StackTrace);
         //construct list of all cards we can use to tune to the new channel
+        Log.Info("Controller: find free card for channel {0}", dbChannel.Name);
         List<CardDetail> cardsAvailable = new List<CardDetail>();
-        List<int> cardsUnAvailable = new List<int>();        
 
-        Log.Info("Controller: find free card for channel {0}", dbChannel.Name);
-        TvBusinessLayer layer = new TvBusinessLayer();
+        List<CardDetail> cardDetails = GetCardsForChannel(cards, dbChannel, ref user);
+        foreach (CardDetail cardDetail in cardDetails)
+        {
+          bool checkTransponder = CheckTransponder(user, cards[cardDetail.Card.IdCard], cardDetail.Card.DecryptLimit, cardDetail.Card.IdCard, cardDetail.TuningDetail);
+          if (checkTransponder)
+          {
+            cardsAvailable.Add(cardDetail);
+          }
+        }
 
+
+        //sort cards
+        cardsAvailable.Sort();
+
+        if (cardsAvailable.Count > 0)
+        {
+          result = TvResult.Succeeded;
+        }
+        else
+        {
+          result = cardDetails.Count == 0 ? TvResult.ChannelNotMappedToAnyCard : TvResult.AllCardsBusy;
+        }
+        Log.Info("Controller: found {0} free card(s)", cardsAvailable.Count);
+
+        return cardsAvailable;
+      }
+      catch (Exception ex)
+      {
+        result = TvResult.UnknownError;
+        Log.Write(ex);
+        return null;
+      }
+      finally
+      {
+        stopwatch.Stop();        
+        Log.Info("AdvancedCardAllocation.GetAvailableCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds);
+      }
+    }
+
+    /// <summary>
+    /// Gets a list of all cards which can receive the channel specified
+    /// List is sorted.
+    /// </summary>
+    /// <returns>list containg all cards which can receive the channel</returns>
+    public List<CardDetail> GetCardsForChannel(Dictionary<int, ITvCardHandler> cards, Channel dbChannel, ref User user)
+    {
+      Stopwatch stopwatch = Stopwatch.StartNew();
+      try
+      {
+        //Log.Info("GetAvailableCardsForChannel st {0}", Environment.StackTrace);
+        //construct list of all cards we can use to tune to the new channel
+        List<CardDetail> cardsAvailable = new List<CardDetail>();
+        List<int> cardsUnAvailable = new List<int>();
+
+        Log.Info("Controller: find card for channel {0}", dbChannel.Name);
+        
         //get the tuning details for the channel
-        List<IChannel> tuningDetails = layer.GetTuningChannelByName(dbChannel);
+        List<IChannel> tuningDetails = _businessLayer.GetTuningChannelByName(dbChannel);
 
         bool isValidTuningDetails = IsValidTuningDetails(tuningDetails);
         if (!isValidTuningDetails)
         {
           //no tuning details??
           Log.Info("Controller:  No tuning details for channel:{0}", dbChannel.Name);
-          result = TvResult.NoTuningDetails;
           return cardsAvailable;
-        }        
+        }
 
         Log.Info("Controller:   got {0} tuning details for {1}", tuningDetails.Count, dbChannel.Name);
 
-        int cardsFound = 0;
         int number = 0;
-
-        Dictionary<int, bool> cardsUsedByUser = GetCardsUsedByUser(cards, user);
-
-        Dictionary<int, ITvCardHandler>.ValueCollection cardHandlers = null;
-        if (tuningDetails != null && tuningDetails.Count > 0)
-        {
-          cardHandlers = cards.Values;  
-        }
-
+        Dictionary<int, ITvCardHandler>.ValueCollection cardHandlers = cards.Values;
         
-        
         foreach (IChannel tuningDetail in tuningDetails)
         {
           cardsUnAvailable.Clear();
           number++;
-          Log.Info("Controller:   channel #{0} {1} ", number, tuningDetail.ToString());                    
+          Log.Info("Controller:   channel #{0} {1} ", number, tuningDetail.ToString());
           foreach (ITvCardHandler cardHandler in cardHandlers)
-          {                        
+          {
             int cardId = cardHandler.DataBaseCard.IdCard;
 
             if (cardsUnAvailable.Contains(cardId))
             {
               Log.Info("Controller:    card:{0} has already been queried, skipping.", cardId);
-              continue;              
-            }            
-
-            bool isCardFoundAndEnabled = IsCardFoundAndEnabled(cardsAvailable, cardHandler);
-            if (!isCardFoundAndEnabled)
-            {
-              //not enabled, so skip the card
-              Log.Info("Controller:    card:{0} type:{1} is disabled", cardId, cardHandler.Type);
-              AddCardUnAvailable(ref cardsUnAvailable, cardId);
               continue;
             }
-
-            bool isCardPresent = IsCardPresent(cardId, cardHandler.DataBaseCard.ReferencedServer().HostName);
-            if (!isCardPresent)
+            if (!CanCardTuneChannel(cardHandler, dbChannel, tuningDetail))
             {
-              Log.Error("card: unable to connect to slave controller at:{0}",
-                        cardHandler.DataBaseCard.ReferencedServer().HostName);
               AddCardUnAvailable(ref cardsUnAvailable, cardId);
               continue;
             }
 
-            if (!cardHandler.Tuner.CanTune(tuningDetail))
-            {
-              //card cannot tune to this channel, so skip it
-              Log.Info("Controller:    card:{0} type:{1} cannot tune to channel", cardId, cardHandler.Type);
-              AddCardUnAvailable(ref cardsUnAvailable, cardId);
-              continue;
-            }
-
-            //check if channel is mapped to this card and that the mapping is not for "Epg Only"
-            ChannelMap channelMap = null;
-            bool isChannelMappedToCard = IsChannelMappedToCard(dbChannel, cardHandler.DataBaseCard.DevicePath, out channelMap);
-            if (!isChannelMappedToCard)
-            {
-              Log.Info("Controller:    card:{0} type:{1} channel not mapped", cardId, cardHandler.Type);
-              AddCardUnAvailable(ref cardsUnAvailable, cardId);
-              continue;
-            }
-
-            CardDetail cardInfo = null;
-            int nrOfOtherUsers = 0;
-            bool isSameTransponder = false;
-
-            bool isOnlyActiveUserCurrentUser = true;
-            cardsUsedByUser.TryGetValue(cardHandler.DataBaseCard.IdCard, out isOnlyActiveUserCurrentUser);
-
-            if (isOnlyActiveUserCurrentUser)
-            {
-              isSameTransponder = true;
-              nrOfOtherUsers = 0;
-              cardInfo = new CardDetail(cardId, channelMap.ReferencedCard(), tuningDetail);
-              cardInfo.Priority = CardPriority(cardInfo.Priority, nrOfOtherUsers, isSameTransponder, true, cardId,
-                                            recommendedCardId);              
-            }
-            else
-            {
-              //ok card could be used to tune to this channel
-              //now we check if its free...
-              cardsFound++;
-              isSameTransponder = false;
-              bool canDecrypt = true;
-              int decryptLimit = cardHandler.DataBaseCard.DecryptLimit;
-
-              bool checkTransponder = CheckTransponder(dbChannel, user, cardHandler, decryptLimit, cardId, tuningDetail,
-                                                       checkTransponders, out isSameTransponder, out canDecrypt);
-              
-              if (!checkTransponder)
-              {
-                AddCardUnAvailable(ref cardsUnAvailable, cardId);
-                continue;
-              }
-
-              cardInfo = new CardDetail(cardId, channelMap.ReferencedCard(), tuningDetail);
-              cardInfo.CanDecrypt = canDecrypt;
-
-              //determine how many other users are using this card                        
-              nrOfOtherUsers = NumberOfUsersOnCard(cards, user, cardInfo);
-              cardInfo.Priority = CardPriority(cardInfo.Priority, nrOfOtherUsers, isSameTransponder, canDecrypt, cardId,
-                                            recommendedCardId);
-            }
-                        
-            Log.Info("Controller:    card:{0} type:{1} is available priority:{2} #users:{3} same transponder:{4}",
-                     cardInfo.Id, cardHandler.Type, cardInfo.Priority, nrOfOtherUsers, isSameTransponder);
-
+            //ok card could be used to tune to this channel
+            bool isSameTransponder = IsSameTransponder(cardHandler, tuningDetail);
+            Log.Info("Controller:    card:{0} type:{1} can tune to channel", cardId, cardHandler.Type);
+            int nrOfOtherUsers = NumberOfOtherUsersOnCard(cardHandler, user);
+            Log.Info("Controller:    card:{0} type:{1} users: {2}", cardId, cardHandler.Type, nrOfOtherUsers);
+            CardDetail cardInfo = new CardDetail(cardId, cardHandler.DataBaseCard, tuningDetail, isSameTransponder, nrOfOtherUsers);
             cardsAvailable.Add(cardInfo);
           }
         }
 
 
-        //sort cards on priority
+        //sort cards
         cardsAvailable.Sort();
 
-        if (cardsAvailable.Count > 0)
-        {
-          result = TvResult.Succeeded;
-        }
-        else
-        {
-          result = cardsFound == 0 ? TvResult.ChannelNotMappedToAnyCard : TvResult.AllCardsBusy;
-        }
-        Log.Info("Controller: found {0} available", cardsAvailable.Count);
+        Log.Info("Controller: found {0} card(s) for channel", cardsAvailable.Count);
 
         return cardsAvailable;
       }
       catch (Exception ex)
       {
-        result = TvResult.UnknownError;
         Log.Write(ex);
         return null;
       }
       finally
       {
-        stopwatch.Stop();        
-        Log.Info("AdvancedCardAllocation.GetAvailableCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds);
+        stopwatch.Stop();
+        Log.Info("AdvancedCardAllocation.GetCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds);
       }
     }
 
-    private void AddCardUnAvailable(ref List<int> cardsUnAvailable, int cardId)
+    private static bool CanCardTuneChannel(ITvCardHandler cardHandler, Channel dbChannel, IChannel tuningDetail)
     {
+      int cardId = cardHandler.DataBaseCard.IdCard;
+      bool isCardEnabled = IsCardEnabled(cardHandler);
+      if (!isCardEnabled)
+      {
+        //not enabled, so skip the card
+        Log.Info("Controller:    card:{0} type:{1} is disabled", cardId, cardHandler.Type);
+        return false;
+      }
+
+      bool isCardPresent = IsCardPresent(cardId, cardHandler.DataBaseCard.ReferencedServer().HostName);
+      if (!isCardPresent)
+      {
+        Log.Error("card: unable to connect to slave controller at:{0}",
+                  cardHandler.DataBaseCard.ReferencedServer().HostName);
+        return false;
+      }
+
+      if (!cardHandler.Tuner.CanTune(tuningDetail))
+      {
+        //card cannot tune to this channel, so skip it
+        Log.Info("Controller:    card:{0} type:{1} cannot tune to channel", cardId, cardHandler.Type);
+        return false;
+      }
+
+      //check if channel is mapped to this card and that the mapping is not for "Epg Only"
+      bool isChannelMappedToCard = IsChannelMappedToCard(dbChannel, cardHandler.DataBaseCard.DevicePath);
+      if (!isChannelMappedToCard)
+      {
+        Log.Info("Controller:    card:{0} type:{1} channel not mapped", cardId, cardHandler.Type);
+        return false;
+      }
+
+      if (!tuningDetail.FreeToAir && !cardHandler.DataBaseCard.CAM)
+      {
+        Log.Info("Controller:    card:{0} type:{1} channel is encrypted but card has no CAM", cardId, cardHandler.Type);
+        return false;
+      }
+      return true;
+    }
+
+    private static void AddCardUnAvailable(ref List<int> cardsUnAvailable, int cardId)
+    {
       if (!cardsUnAvailable.Contains(cardId))
       {
         cardsUnAvailable.Add(cardId);
Index: TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/CardAllocationBase.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/CardAllocationBase.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/CardAllocationBase.cs	(working copy)
@@ -25,6 +25,7 @@
 using TvDatabase;
 using TvLibrary.Channels;
 using TvLibrary.Interfaces;
+using TvLibrary.Log;
 
 #endregion
 
@@ -35,62 +36,33 @@
     #region protected members
 
 
-    protected static Dictionary<int, bool> GetCardsUsedByUser (Dictionary<int, ITvCardHandler> cards, User currentUser)
+    protected static bool IsCamAbleToDecryptChannel(User user, ITvCardHandler tvcard, IChannel tuningDetail, int decryptLimit)
     {
-      Dictionary<int, bool> getCardsUsedByUser = new Dictionary<int, bool>();
-
-      Dictionary<int, ITvCardHandler>.ValueCollection cardHandlers = cards.Values;
-      foreach (ITvCardHandler cardHandler in cardHandlers)
+      if (!tuningDetail.FreeToAir)
       {
-        bool isActive = true;
-
-        User[] users = cardHandler.Users.GetUsers();
-
-        if (users != null && users.Length > 0)
-        {          
-          foreach (User u in users)
+        bool isRec = false;
+        bool isCamAbleToDecryptChannel = true;
+        int camDecrypting = tvcard.NumberOfChannelsDecrypting;
+        if (decryptLimit > 0)
+        {
+          if (user.CardId == tvcard.DataBaseCard.IdCard)
           {
-            if (u.Name != currentUser.Name)
+            IChannel currentUserCh = tvcard.CurrentChannel(ref user);
+            if (currentUserCh != null && !currentUserCh.FreeToAir)
             {
-              isActive = false;
-              break;
+              camDecrypting -= 1;
             }
-          }          
+          }
+          //check if cam is capable of descrambling an extra channel
+          isCamAbleToDecryptChannel = (camDecrypting < decryptLimit);
         }
-        getCardsUsedByUser.Add(cardHandler.DataBaseCard.IdCard, isActive);
-      }
-      return getCardsUsedByUser;
-    }
 
-    protected static bool IsCamAbleToDecrypChannel(User user, ITvCardHandler tvcard, Channel ch, int decryptLimit)
-    {
-      bool isRec = false;
-      bool isCamAbleToDecrypChannel = false;
-      int camDecrypting = tvcard.NumberOfChannelsDecrypting;
-      Channel currentUserCh = Channel.Retrieve(user.IdChannel);
-      
-      if (currentUserCh != null)
-      {
-        isRec = tvcard.Recorder.IsRecordingChannel(currentUserCh.Name);        
+        return isCamAbleToDecryptChannel;
       }
-      if (!isRec && tvcard.TimeShifter.IsTimeShifting(ref user))
-      {
-        bool fta = isFTA(tvcard, user);
-        if (fta)
-        {
-          camDecrypting--;
-        }
-      }
-      //check if cam is capable of descrambling an extra channel
-      if (decryptLimit > 0)
-      {
-        isCamAbleToDecrypChannel = (camDecrypting < decryptLimit);
-      }
-
-      return ((isCamAbleToDecrypChannel && !isRec) || ch.FreeToAir);
+      return true;
     }
 
-    protected static bool IsCamAlreadyDecodingChannel(ITvCardHandler tvcard, Channel dbChannel)
+    protected static bool IsCamAlreadyDecodingChannel(ITvCardHandler tvcard, IChannel tuningDetail)
     {
       bool isCamAlreadyDecodingChannel = false;
       User[] currentUsers = tvcard.Users.GetUsers();
@@ -99,7 +71,7 @@
         for (int i = 0; i < currentUsers.Length; ++i)
         {
           User tmpUser = currentUsers[i];
-          if (tvcard.CurrentDbChannel(ref tmpUser) == dbChannel.IdChannel)
+          if (tvcard.CurrentChannel(ref tmpUser).Equals(tuningDetail))
           {
             //yes, cam already is descrambling this channel
             isCamAlreadyDecodingChannel = true;
@@ -110,35 +82,16 @@
       return isCamAlreadyDecodingChannel;
     }
 
-    protected static bool isFTA(ITvCardHandler tvcard, User user)
+    protected static bool IsChannelMappedToCard(Channel dbChannel, string devicePath)
     {
-      IChannel unknownChannel = tvcard.CurrentChannel(ref user);
-      bool fta = true;
-
-      if (unknownChannel != null)
-      {
-        DVBBaseChannel dvbChannel = unknownChannel as DVBBaseChannel;
-
-        if (dvbChannel != null)
-        {
-          fta = dvbChannel.FreeToAir;
-        }        
-      }
-      return fta;
-    }
-
-    protected static bool IsChannelMappedToCard(Channel dbChannel, string devicePath,
-                                                out ChannelMap channelMap)
-    {
       //check if channel is mapped to this card and that the mapping is not for "Epg Only"
       bool isChannelMappedToCard = false;
-      channelMap = null;
 
       List<ChannelMap> channelMaps = dbChannel.ReferringChannelMap() as List<ChannelMap>;
 
       if (channelMaps != null)
       {
-        channelMap = channelMaps.Find(m => !m.EpgOnly && m.ReferencedCard().DevicePath == devicePath);
+        ChannelMap channelMap = channelMaps.Find(m => !m.EpgOnly && m.ReferencedCard().DevicePath == devicePath);
         isChannelMappedToCard = (channelMap != null);
       }      
      
@@ -151,6 +104,83 @@
       return isValid;
     }
 
+    protected static bool CheckTransponder(User user, ITvCardHandler tvcard, int decryptLimit, int cardId,
+                                  IChannel tuningDetail)
+    {
+      bool checkTransponder = true;
+      bool isSameTransponder = IsSameTransponder(tvcard, tuningDetail);
+      bool isOwnerOfCard = tvcard.Users.IsOwner(user);
+
+      if (isOwnerOfCard)
+      {
+        Log.Info("Controller:    card:{0} type:{1} is available", cardId, tvcard.Type);
+      }
+      else
+      {
+        if (isSameTransponder)
+        {
+          //card is in use, but it is tuned to the same transponder.
+          //meaning.. we can use it.          
+          //if the channel is encrypted check cam decrypt limit.
+          if (!tuningDetail.FreeToAir)
+          {
+            //but we must check if cam can decode the extra channel as well
+            //first check if cam is already decrypting this channel          
+            bool isCamAlreadyDecodingChannel = IsCamAlreadyDecodingChannel(tvcard, tuningDetail);
+
+            //if the user is already using this card
+            //and is watching a scrambled signal
+            //then we must the CAM will always be able to watch the requested channel
+            //since the users zaps
+
+            //check if cam is capable of descrambling an extra channel                            
+            bool isCamAbleToDecrypChannel = IsCamAbleToDecryptChannel(user, tvcard, tuningDetail, decryptLimit);
+
+            bool canDecrypt = isCamAbleToDecrypChannel || isCamAlreadyDecodingChannel;
+
+            if (canDecrypt)
+            {
+              if (decryptLimit > 0)
+              {
+                Log.Info(
+                  "Controller:    card:{0} type:{1} is available, tuned to same transponder decrypting {2}/{3} channels",
+                  cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, decryptLimit);
+              }
+              else
+              {
+                Log.Info(
+                  "Controller:    card:{0} type:{1} is available, tuned to same transponder",
+                  cardId, tvcard.Type);
+              }
+
+            }
+            else
+            {
+              //it is not, skip this card
+              Log.Info(
+                "Controller:    card:{0} type:{1} is not available, tuned to same transponder decrypting {2}/{3} channels (cam limit reached)",
+                cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, decryptLimit);
+              checkTransponder = false;
+            }
+          }
+        }
+        else
+        {
+          Log.Info("Controller:    card:{0} type:{1} is not available, tuned to different transponder",
+                     cardId, tvcard.Type);
+          checkTransponder = false;
+        }
+      }
+      return checkTransponder;
+    }
+
+    protected static bool IsSameTransponder(ITvCardHandler tvcard, IChannel tuningDetail)
+    {
+      return tvcard.Tuner.IsTunedToTransponder(tuningDetail) &&
+                           tvcard.SupportsSubChannels;
+
+    }
+
     #endregion
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ChannelStates.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ChannelStates.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ChannelStates.cs	(working copy)
@@ -208,13 +208,18 @@
               }
 
               //check if channel is mapped to this card and that the mapping is not for "Epg Only"
-              ChannelMap channelMap = null;
-              bool isChannelMappedToCard = IsChannelMappedToCard(ch, cardHandler.DataBaseCard.DevicePath, out channelMap);
+              bool isChannelMappedToCard = IsChannelMappedToCard(ch, cardHandler.DataBaseCard.DevicePath);
               if (!isChannelMappedToCard)
               {
                 UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel);
                 continue;
               }
+
+              if (!tuningDetail.FreeToAir && !cardHandler.DataBaseCard.CAM)
+              {
+                UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel);
+                continue;
+              }
                                           
               //ok card could be used to tune to this channel
               //now we check if its free...                              
@@ -294,12 +299,6 @@
                                                  int decryptLimit, int cardId, IChannel tuningDetail,
                                                  bool checkTransponders)
     {
-      bool isSameTransponder = tvcard.Tuner.IsTunedToTransponder(tuningDetail) &&
-                               (tvcard.SupportsSubChannels || (checkTransponders == false));
-      if (isSameTransponder)
-      {
-        bool hasCA = tvcard.HasCA;
-        int camDecrypting = tvcard.NumberOfChannelsDecrypting;
         for (int i = 0; i < allUsers.Count; i++)
         {
           User user = allUsers[i];
@@ -310,73 +309,17 @@
             continue;
           }
 
-          Dictionary<int, bool> cardsUsedByUser = GetCardsUsedByUser(cards, user);
-          bool isOnlyActiveUserCurrentUser = true;
-          cardsUsedByUser.TryGetValue(tvcard.DataBaseCard.IdCard, out isOnlyActiveUserCurrentUser);
-
-          if (isOnlyActiveUserCurrentUser)
+          bool checkTransponder = CheckTransponder( user, tvcard, decryptLimit, tvcard.DataBaseCard.IdCard, tuningDetail);
+          if (checkTransponder)
           {
-            //no need to do any further checks if user is the only one currently active.
             UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
-            continue;
-          }
-
-          bool isOwnerOfCard = tvcard.Users.IsOwner(user);         
-          if (!isOwnerOfCard)
+          } else
           {
-            if (hasCA && decryptLimit > 0)
-              //does the card have a CA module and a CA limit, if yes then proceed to check cam decrypt limit.                
-            {
-              //but we must check if cam can decode the extra channel as well
-              //first check if cam is already decrypting this channel          
-              bool isCamAlreadyDecodingChannel = IsCamAlreadyDecodingChannel(tvcard, ch);
-
-              //check if cam is capable of descrambling an extra channel              
-              bool isCamAbleToDecrypChannel = IsCamAbleToDecrypChannel(user, tvcard, ch, decryptLimit);
-
-
-              if (isCamAbleToDecrypChannel || isCamAlreadyDecodingChannel)
-              {
-                //it is.. we can really use this card
-                //Log.Info("Controller:    card:{0} type:{1} is tuned to same transponder decrypting {2}/{3} channels",
-                //    cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, keyPair.Value.DataBaseCard.DecryptLimit);
-                user = allUsers[i];
-                UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
-                allUsers[i] = user;
-              }
-              else
-              {
-                //it is not, skip this card
-                //Log.Info("Controller:    card:{0} type:{1} is tuned to same transponder decrypting {2}/{3} channels. cam limit reached",
-                //     cardId, tvcard.Type, tvcard.NumberOfChannelsDecrypting, keyPair.Value.DataBaseCard.DecryptLimit);
-                user = allUsers[i];
-                if (tvcard.Users.IsOwner(user))
-                {
-                  UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
-                }
-                else
-                {
-                  UpdateChannelStateUser(user, ChannelState.nottunable, ch.IdChannel);
-                }
-                allUsers[i] = user;
-              }
-            }
-            else // no cam present
-            {
-              UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
-            }
+            UpdateChannelStateUser(user, ChannelState.nottunable, ch.IdChannel);
           }
-          else //in case of cardowner 
-          {
-            UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
-          }
         } //foreach allusers end                         
-      }
-      else
-      {
-        //different transponder, are we the owner of this card?
-        UpdateChannelStateUserBasedOnCardOwnership(tvcard, allUsers, ch);
-      }
+      
+      
     }
 
     #endregion
Index: TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ICardAllocation.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ICardAllocation.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/CardManagement/CardAllocation/ICardAllocation.cs	(working copy)
@@ -28,10 +28,16 @@
   {
     /// <summary>
     /// Gets a list of all free cards which can receive the channel specified
-    /// List is sorted by priority
+    /// List is sorted by "same transponder" and priority
     /// </summary>
     /// <returns>list containg all free cards which can receive the channel</returns>
-    List<CardDetail> GetAvailableCardsForChannel(Dictionary<int, ITvCardHandler> cards, Channel dbChannel, ref User user,
-                                                 bool checkTransponders, out TvResult result, int recommendedCardId);
+    List<CardDetail> GetAvailableCardsForChannel(Dictionary<int, ITvCardHandler> cards, Channel dbChannel, ref User user, out TvResult result);
+
+    /// <summary>
+    /// Gets a list of all cards which can receive the channel specified
+    /// List is sorted by "same transponder" and priority
+    /// </summary>
+    /// <returns>list containg all free cards which can receive the channel</returns>
+    List<CardDetail> GetCardsForChannel(Dictionary<int, ITvCardHandler> cards, Channel dbChannel, ref User user);
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvService/Scheduler/CardDetail.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/Scheduler/CardDetail.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/Scheduler/CardDetail.cs	(working copy)
@@ -33,7 +33,8 @@
     private readonly Card _card;
     private readonly IChannel _detail;
     private int _priority;
-    private bool _canDecrypt;
+    private bool _sameTransponder;
+    private int _numberOfOtherUsers;
 
     /// <summary>
     /// ctor
@@ -41,13 +42,15 @@
     /// <param name="id">card id</param>
     /// <param name="card">card dataaccess object</param>
     /// <param name="detail">tuning detail</param>
-    public CardDetail(int id, Card card, IChannel detail)
+    /// <param name="sameTransponder">indicates whether it is the same transponder</param>
+    public CardDetail(int id, Card card, IChannel detail, bool sameTransponder, int numberOfOtherUsers)
     {
-      _canDecrypt = true;
+      _sameTransponder = sameTransponder;
       _cardId = id;
       _card = card;
       _detail = detail;
       _priority = _card.Priority;
+      _numberOfOtherUsers = numberOfOtherUsers;
     }
 
     /// <summary>
@@ -65,7 +68,6 @@
     public int Priority
     {
       get { return _priority; }
-      set { _priority = value; }
     }
 
     /// <summary>
@@ -84,22 +86,50 @@
       get { return _detail; }
     }
 
-    public bool CanDecrypt
+    /// <summary>
+    /// returns if it is the same transponder
+    /// </summary>
+    public bool SameTransponder
     {
-      get { return _canDecrypt; }
-      set { _canDecrypt = value; }
+      get { return _sameTransponder; }
     }
 
+    /// <summary>
+    /// gets the number of other users
+    /// </summary>
+    public int NumberOfOtherUsers
+    {
+      get { return _numberOfOtherUsers; }
+    }
+
     #region IComparable<CardInfo> Members
 
     // higher priority means that this one should be more to the front of the list
     public int CompareTo(CardDetail other)
     {
-      if (Priority > other.Priority)
+      if (SameTransponder == other.SameTransponder)
+      {
+        if (!SameTransponder && (NumberOfOtherUsers != other.NumberOfOtherUsers))
+        {
+          if (NumberOfOtherUsers > other.NumberOfOtherUsers)
+            return 1;
+          if (NumberOfOtherUsers < other.NumberOfOtherUsers)
+            return -1;
+          return 0;
+        }
+
+        if (Priority > other.Priority)
+          return -1;
+        if (Priority < other.Priority)
+          return 1;
+        return 0;
+      }
+
+      if (SameTransponder)
         return -1;
-      if (Priority < other.Priority)
-        return 1;
-      return 0;
+      return 1;
+
+
     }
 
     #endregion
Index: TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs	(working copy)
@@ -850,40 +850,26 @@
                 DateTime.Now.ToShortTimeString(), RecDetail.EndTime.ToShortTimeString(), RecDetail.Schedule.ProgramName);
       TvResult result;
       //get list of all cards we can use todo the recording
-      ICardAllocation allocation = new AdvancedCardAllocation(); //CardAllocationFactory.Create(false);
+      ICardAllocation allocation = new AdvancedCardAllocation(new TvBusinessLayer()); //CardAllocationFactory.Create(false);
       List<CardDetail> freeCards = allocation.GetAvailableCardsForChannel(_tvController.CardCollection,
-                                                                          RecDetail.Channel, ref user, false,
-                                                                          out result, RecDetail.Schedule.RecommendedCard);
-      if (freeCards.Count == 0)
-      {
-        return;
-      }
-        
-      CardDetail cardInfo = null;
+                                                                          RecDetail.Channel, ref user, out result);
 
-      //first try to start recording using the recommended card
-      cardInfo = FindRecommendedCard(RecDetail, freeCards);
-
-      if (cardInfo == null)
+      CardDetail cardInfo = null;
+      if (freeCards.Count > 0)
       {
-        cardInfo = FindFirstCardAlreadyTunedToTransponder(freeCards);
-      }
+        //first try to start recording using the recommended card
+        cardInfo = FindRecommendedCard(RecDetail.Schedule.RecommendedCard, freeCards);
 
-      if (cardInfo == null)
-      {        
-        cardInfo = FindFirstAvailableCardInUse(freeCards);
+        if (cardInfo == null)
+        {
+          cardInfo = freeCards[0];
+        }
       }
-
-      if (cardInfo == null)
+      else
       {
-        cardInfo = CheckCardAvailOnAlreadyTunedChannel(RecDetail, freeCards);
+        cardInfo = HijackCardForRecording(RecDetail.Channel, ref user, RecDetail.Schedule.RecommendedCard);
       }
 
-      if (cardInfo == null)
-      {       
-        cardInfo = HijackCardForRecording(freeCards);
-      }
-
       if (cardInfo != null)
       {
         try
@@ -915,28 +901,15 @@
       }
     }
 
-    private CardDetail FindRecommendedCard(RecordingDetail RecDetail, List<CardDetail> freeCards)
+    private static CardDetail FindRecommendedCard(int recommendedCard, List<CardDetail> freeCards)
     {
       CardDetail cardInfo = null;
-      if (RecDetail.Schedule.RecommendedCard > 0)
+      if (recommendedCard > 0)
       {
         foreach (CardDetail card in freeCards)
         {
-          User byUser;
-          bool isCardInUse = _tvController.IsCardInUse(card.Id, out byUser);
-          //if (card.Id != recording.Schedule.RecommendedCard) continue;
-          // now the card allocator handles the recommenedcard.
-
-          //when card is idle we can use it
-          //when card is busy, but already tuned to the correct channel then we can use it also
-          //when card is busy, but already tuned to the correct transponder then we can use it also          
-          User tmpUser = _tvController.GetUserForCard(card.Id);
-          //added by joboehl - Allows the CurrentDbChannel bellow to work when TVServer and client are on different machines
-          if ((isCardInUse == false) ||
-              _tvController.CurrentDbChannel(ref tmpUser) == RecDetail.Channel.IdChannel ||
-              (_tvController.IsTunedToTransponder(card.Id, card.TuningDetail)))
+          if (card.Id == recommendedCard)
           {
-            // use the recommended card.
             cardInfo = card;
             Log.Write("Scheduler : record on recommended card:{0} priority:{1}", cardInfo.Id, cardInfo.Card.Priority);
             break;
@@ -944,108 +917,102 @@
         }
         if (cardInfo == null)
         {
-          Log.Write("Scheduler : recommended card:{0} is not available", RecDetail.Schedule.RecommendedCard);
+          Log.Write("Scheduler : recommended card:{0} is not available", recommendedCard);
         }
       }
       return cardInfo;
     }
 
-    private CardDetail FindFirstCardAlreadyTunedToTransponder(List<CardDetail> freeCards)
+    private CardDetail HijackCardForRecording(Channel channel, ref User user, int recommendedCard)
     {
+      
       CardDetail cardInfo = null;
-      foreach (CardDetail card in freeCards)
+      TvBusinessLayer layer = new TvBusinessLayer();
+      if ((layer.GetSetting("scheduleroverlivetv", "yes").Value == "yes"))
       {
-        if (_tvController.IsTunedToTransponder(card.Id, card.TuningDetail))
-        {
-          if (card.CanDecrypt)
-          {
-            cardInfo = card;
-            Log.Write("Scheduler : record on free card:{0} priority:{1}", cardInfo.Id, cardInfo.Card.Priority);
-            break;          
-          } 
-          else
-          {
-            Log.Write("Scheduler : cannot record (decrypt failed/cam limit reached) on card:{0} priority:{1}", card.Id, card.Card.Priority);
-          }                   
-        }
-      }
-      return cardInfo;
-    }
+        ICardAllocation allocation = new AdvancedCardAllocation(layer);
+        List<CardDetail> cardDetails = allocation.GetCardsForChannel(_tvController.CardCollection,
+                                                                     channel, ref user);
 
-    private CardDetail FindFirstAvailableCardInUse(List<CardDetail> freeCards)
-    {
-      CardDetail cardInfo = null;
-      foreach (CardDetail card in freeCards)
-      {
-        User byUser;
-        if ((_tvController.IsCardInUse(card.Id, out byUser) == false))
+        cardDetails.Sort(new RecordingCardDetailComparer(recommendedCard));
+        foreach (CardDetail cardDetail in cardDetails)
         {
-          cardInfo = card;
-          Log.Write("Scheduler : record on free card:{0} priority:{1}", cardInfo.Id, cardInfo.Card.Priority);
-          break;
-        }
-        else
-        {
-          Log.Write("Scheduler : cannot record (card not in use) on card:{0} priority:{1}", card.Id, card.Card.Priority);
-        }
-      }
-      return cardInfo;
-    }
-
-    private CardDetail CheckCardAvailOnAlreadyTunedChannel(RecordingDetail RecDetail, List<CardDetail> freeCards) 
-    {
-      CardDetail cardInfo = null;
-      
-      Log.Write("Scheduler : all cards busy, check if any card is already tuned to channel:{0}",
-                RecDetail.Channel.Name);
-      //all cards in use, check if a card is already tuned to the channel we want to record
-      foreach (CardDetail card in freeCards)
-      {
-        User tmpUser = _tvController.GetUserForCard(card.Id);
-        //added by joboehl - Allows the CurrentDbChannel bellow to work when TVServer and client are on different machines
-        if (_tvController.CurrentDbChannel(ref tmpUser) == RecDetail.Channel.IdChannel)
-        {
-          if (_tvController.IsRecording(ref tmpUser) == false)
+          if ( cardDetail.SameTransponder)
           {
-            cardInfo = card;
-            Log.Write("Scheduler : record on card:{0} priority:{1} which is tuned to {2}", cardInfo.Id,
-                      cardInfo.Card.Priority, RecDetail.Channel.DisplayName);
-            break;
+            User[] tmpUsers = _tvController.GetUsersForCard(cardDetail.Id);
+
+            for (int i = 0; i < tmpUsers.Length; i++)
+            {
+              User tmpUser = tmpUsers[i];
+              if (!_tvController.IsRecording(ref tmpUser))
+              {
+                if (_tvController.IsTimeShifting(ref tmpUser))
+                {
+                  Log.Write(
+                    "Scheduler : card is tuned to the same transponder but not free. record on card:{0} priority:{1}, kicking user:{2}",
+                    cardDetail.Id, cardDetail.Card.Priority, tmpUser.Name);
+                  _tvController.StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted);
+                }
+                cardInfo = cardDetail;
+                break;
+              }
+            }
+            if (cardInfo != null)
+            {
+              break;
+            }
           }
         }
-      }
-      
-      return cardInfo;
-    }
 
-    private CardDetail HijackCardForRecording(List<CardDetail> freeCards)
-    {
-      CardDetail cardInfo = null;
-      TvBusinessLayer layer = new TvBusinessLayer();
-
-      if ((layer.GetSetting("scheduleroverlivetv", "yes").Value == "yes"))
-      {
-        User[] tmpUsers = _tvController.GetUsersForCard(freeCards[0].Id);
-
-        for (int i = 0; i < tmpUsers.Length; i++)
+        if (cardInfo == null)
         {
-          User tmpUser = tmpUsers[i];
-          if (_tvController.IsRecording(ref tmpUser) == false)
+          foreach (CardDetail cardDetail in cardDetails)
           {
-            if (_tvController.IsTimeShifting(ref tmpUser))
+            if (!cardDetail.SameTransponder)
             {
-              _tvController.StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted);
+              User[] tmpUsers = _tvController.GetUsersForCard(cardDetail.Id);
+              Boolean canKickAll = true;
+              for (int i = 0; i < tmpUsers.Length; i++)
+              {
+                User tmpUser = tmpUsers[i];
+                if (_tvController.IsRecording(ref tmpUser))
+                {
+                  canKickAll = false;
+                }
+              }
+              if (canKickAll)
+              {
+                cardInfo = cardDetail;
+                Log.Write(
+                    "Scheduler : card is not tuned to the same transponder and not recording, kicking all users. record on card:{0} priority:{1}",
+                    cardInfo.Id, cardInfo.Card.Priority);
+                for (int i = 0; i < tmpUsers.Length; i++)
+                {
+                  User tmpUser = tmpUsers[i];
+                  if (_tvController.IsTimeShifting(ref tmpUser))
+                  {
+                    Log.Write(
+                    "Scheduler : kicking user:{0}",
+                    tmpUser.Name);
+                    _tvController.StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted);
+                  }
+                  Log.Write(
+                    "Scheduler : card is tuned to the same transponder but not free. record on card:{0} priority:{1}, kicking user:{2}",
+                    cardInfo.Id, cardInfo.Card.Priority, tmpUser.Name);
+                }
+                break;
+              }
             }
-            cardInfo = freeCards[0];
-            Log.Write(
-              "Scheduler : no card is tuned to the correct channel. record on card:{0} priority:{1}, kicking user:{2}",
-              cardInfo.Id, cardInfo.Card.Priority, tmpUser.Name);
-          }           
-        }      
+          }
+        }
+        if (cardInfo == null)
+        {
+          Log.Write("Scheduler : no free card was found and no card was found where user can be kicked.");
+        }
       }
       else
       {
-        Log.Write("Scheduler : no card was found and scheduler not allowed to stop other users LiveTV or recordings. ");
+        Log.Write("Scheduler : no free card was found and scheduler is not allowed to stop other users LiveTV. ");
       }   
       
       return cardInfo;
@@ -1297,8 +1264,33 @@
         recording.Program.IsRecordingSeriesPending = false;
         recording.Program.Persist();
       }
-    }   
+    }
 
+    private class RecordingCardDetailComparer : IComparer<CardDetail>
+    {
+      private readonly int _recommendedCard;
+
+      public RecordingCardDetailComparer(int recommendedCard)
+      {
+        _recommendedCard = recommendedCard;
+      }
+
+      public int Compare(CardDetail first, CardDetail second)
+      {
+        if (first.Id == _recommendedCard)
+        {
+          return -1;
+        }
+
+        if (second.Id == _recommendedCard)
+        {
+          return 1;
+        }
+        return first.CompareTo(second);
+      } 
+
+    }
+
     #endregion
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TvService/TVController.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/TVController.cs	(revision 25660)
+++ TvEngine3/TVLibrary/TvService/TVController.cs	(working copy)
@@ -174,7 +174,7 @@
     /// </summary>
     public TVController()
     {
-      _cardAllocation = new AdvancedCardAllocation();
+      _cardAllocation = new AdvancedCardAllocation(new TvBusinessLayer());
     }
 
     public Dictionary<int, ITvCardHandler> CardCollection
@@ -2391,43 +2391,9 @@
       try
       {        
         TvResult result;
-        List<CardDetail> freeCards = _cardAllocation.GetAvailableCardsForChannel(_cards, channel, ref user, true, out result,
-                                                                            0);
-        if (freeCards.Count == 0)
+        List<CardDetail> freeCards = _cardAllocation.GetAvailableCardsForChannel(_cards, channel, ref user, out result);
+        if (freeCards.Count > 0)
         {
-          // enumerate all cards and check if some card is already timeshifting the channel requested
-          Dictionary<int, ITvCardHandler>.Enumerator enumerator = _cards.GetEnumerator();
-
-          //for each card
-          while (enumerator.MoveNext())
-          {
-            KeyValuePair<int, ITvCardHandler> keyPair = enumerator.Current;
-            //get a list of all users for this card
-            User[] users = keyPair.Value.Users.GetUsers();
-            if (users != null)
-            {
-              //for each user
-              for (int i = 0; i < users.Length; ++i)
-              {
-                User tmpUser = users[i];
-                //is user timeshifting?
-                if (keyPair.Value.TimeShifter.IsTimeShifting(ref tmpUser))
-                {
-                  //yes, is user timeshifting the correct channel
-                  if (keyPair.Value.CurrentDbChannel(ref tmpUser) == channel.IdChannel)
-                  {
-                    //yes, if card does not support subchannels (analog cards)
-                    //then assign user to this card
-                    VirtualCard card = GetVirtualCard(tmpUser);
-                    return card.Id;
-                  }
-                }
-              }
-            }
-          }
-        }
-        else
-        {
           //get first free card
           return freeCards[0].Id;
         }
@@ -2487,44 +2453,9 @@
       try
       {        
         TvResult result;
-        List<CardDetail> freeCards = _cardAllocation.GetAvailableCardsForChannel(_cards, channel, ref user, true, out result,
-                                                                            0);
+        List<CardDetail> freeCards = _cardAllocation.GetAvailableCardsForChannel(_cards, channel, ref user, out result);
         if (freeCards.Count == 0)
         {
-          // enumerate all cards and check if some card is already timeshifting the channel requested
-          Dictionary<int, ITvCardHandler>.Enumerator enumerator = _cards.GetEnumerator();
-
-          //for each card
-          while (enumerator.MoveNext())
-          {
-            KeyValuePair<int, ITvCardHandler> keyPair = enumerator.Current;
-            //get a list of all users for this card
-            User[] users = keyPair.Value.Users.GetUsers();
-            if (users != null)
-            {
-              //for each user
-              for (int i = 0; i < users.Length; ++i)
-              {
-                User tmpUser = users[i];
-                //is user timeshifting?
-                if (keyPair.Value.TimeShifter.IsTimeShifting(ref tmpUser))
-                {
-                  //yes, is user timeshifting the correct channel
-                  if (keyPair.Value.CurrentDbChannel(ref tmpUser) == channel.IdChannel)
-                  {
-                    //yes, if card does not support subchannels (analog cards)
-                    //then assign user to this card
-                    card = GetVirtualCard(tmpUser);
-                    return TvResult.Succeeded;
-                  }
-                }
-              }
-            }
-          }
-        }
-
-        if (freeCards.Count == 0)
-        {
           //no free cards available
           Log.Write("Controller: StartTimeShifting failed:{0}", result);
 
@@ -3283,7 +3214,7 @@
         {
           Channel dbchannel = Channel.Retrieve(idChannel);
           TvResult viewResult;
-          _cardAllocation.GetAvailableCardsForChannel(_cards, dbchannel, ref user, true, out viewResult, 0);
+          _cardAllocation.GetAvailableCardsForChannel(_cards, dbchannel, ref user, out viewResult);
           chanState = viewResult == TvResult.Succeeded ? ChannelState.tunable : ChannelState.nottunable;
         }
       }
