diff --git a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj
index c2a9a5c1840e81f27607cafad8e1846512477103..f6a4ed07d99b090f85173c3b763aed92015e7d2b 100644
--- a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj
+++ b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj
@@ -5,7 +5,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
+    <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Prism.Core" Version="7.2.0.1422" />
   </ItemGroup>
 
diff --git a/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs b/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs
index 9e84a6855c906e16462a1bba9b5f7c28f9fd8bcd..f4e36fc0d88af90203120fcf7d171368a984c5ca 100644
--- a/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs
+++ b/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs
@@ -1,14 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using CBSVisualizer.Messaging;
-using CBSVisualizer.Messaging.Events;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Common.Interfaces
 {
+    /// <summary>
+    /// An implementation of this interface is kept by each queue.
+    /// This implementation handles ONLY the credit.
+    /// </summary>
     public interface IQueue
     {
         public long Credit
@@ -18,25 +15,67 @@ namespace CBSVisualizer.Common.Interfaces
 
         public long IdleSlope
         {
-            get;
             set;
         }
 
-        public ObservableCollection<PriorityPacket> Queue
-        {
-            set;
-        }
+        /// <summary>
+        /// Determines if the QueueViewModel is currently allowed to send a packet.
+        /// </summary>
+        /// <returns>true if the internal rules of this IQueue allow it, false otherwise</returns>
+        /// <param name="sendCandidate">the packet that could be send if the internal condition is fulfilled</param>
+        bool CanSendPacket(PriorityPacket sendCandidate);
+
+        /// <summary>
+        /// Called when the simulation starts.
+        /// </summary>
+        void OnSimulationStarted();
+
+        /// <summary>
+        /// Called when the simulation stops.
+        /// </summary>
+        void OnSimulationStopped();
+
+        /// <summary>
+        /// Called when the gate is opened.
+        /// </summary>
+        void OnGateOpened();
+
+        /// <summary>
+        /// Called when the gate is closed.
+        /// </summary>
+        void OnGateClosed();
+
+        /// <summary>
+        /// Called if the packet was accepted.
+        /// </summary>
+        void OnPacketAccepted();
 
-        Task OnGateOpened();
+        /// <summary>
+        /// Called if the packet was denied due to pre-closing.
+        /// </summary>
+        void OnPacketDeniedPreClosing();
 
-        Task OnGateClosed();
+        /// <summary>
+        /// Called if the packet was denied due to a higher priority packet.
+        /// </summary>
+        void OnPacketDeniedHigherPriority();
 
-        Task OnPacketResponse(PacketSubmitResult result);
+        /// <summary>
+        /// Called if the transmission was preempted.
+        /// </summary>
+        void OnTransmissionPreempted();
 
-        Task OnTransmissionStarted(long bytesPerSecond);
+        /// <summary>
+        /// Called when the transmission has started.
+        /// </summary>
 
-        Task OnPacketPreempted(int leftoverBytes);
+        void OnTransmissionStarted();
 
-        Task OnTransmissionFinished();
+        /// <summary>
+        /// Called when the transmission has finished.
+        /// </summary>
+        /// <param name="sentPacket"> the packet that was sent</param>
+        /// <param name="bytesPerSecond">the transmission bitrate in bytes per second.</param>
+        void OnTransmissionFinished(PriorityPacket sentPacket, long bytesPerSecond);
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs b/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs
index a355df6d37276bd5ce3d67f949bf45b13c8e9975..fe8c7e15c7bcdd4f6d4722959237400ed495a5d7 100644
--- a/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs
+++ b/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs
@@ -1,6 +1,7 @@
 using CBSVisualizer.Messaging;
 using System.Collections.ObjectModel;
 using System.Linq;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Common
 {
diff --git a/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj b/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj
index f6367ccf057ab1a69986a6badf1692ef55a4cdb1..420b73a2984a8ceb109a665c939b123abbea8439 100644
--- a/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj
+++ b/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj
@@ -5,7 +5,7 @@
     <AssemblyName>CBSVisualizer.Core</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
+    <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj b/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj
index 73d623a9496bb488d4af18a20db7f3bf2a2bcd0c..a7797547b6883ccf49d6e63615436169825628eb 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj
@@ -5,7 +5,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
+    <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Prism.Core" Version="7.2.0.1422" />
   </ItemGroup>
 
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs
index 6eea1f8e5bd287facb5615b9dabb4d8b8ff7a3e8..a66c728f3da882f561d808abe49da7fb55bb1bae 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Prism.Events;
+using Prism.Events;
 
-namespace CBSVisualizer.Messaging.Events
+namespace CBSVisualizer.Messaging.Events.Charts
 {
     public class CreditChangedEvent : PubSubEvent<(int Prio, long Credit)>
     {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs
index c61db7740b1e74d2ec4159ea62222d9435e3a9cf..17b3673d47203f025a52285791dafd836bec27fc 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Prism.Events;
+using Prism.Events;
 
-namespace CBSVisualizer.Messaging.Events
+namespace CBSVisualizer.Messaging.Events.Charts
 {
     public class PacketCountChangedEvent : PubSubEvent<(int Prio, long NewCount)>
     {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs
deleted file mode 100644
index ea1eb9caad572c450e945fa2a3c7aa585d25df84..0000000000000000000000000000000000000000
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CBSVisualizer.Messaging.Events
-{
-    public class GateOpenedEvent : PubSubEvent<(int OpenedTime, ISet<int> OpenedGates)>
-    {
-    }
-}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f222ec28f0d67f4c0c9eac3ef6be7b6f8e43e498
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+using Prism.Events;
+
+namespace CBSVisualizer.Messaging.Events.Queue
+{
+    public class GlobalGateOpenedEvent : PubSubEvent<(int OpenedTime, ISet<int> OpenedGates)>
+    {
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs
index 6435c7f58fbd0f3cbb2ff6e21d9eb4fefd16c1fe..6d486427bbaa17d1abd3e8920b29c0e4bb39a412 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs
@@ -1,11 +1,7 @@
-using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Models;
+using Prism.Events;
 
-namespace CBSVisualizer.Messaging.Events
+namespace CBSVisualizer.Messaging.Events.Queue
 {
     public class PacketArrivedEvent : PubSubEvent<PriorityPacket>
     {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs
similarity index 65%
rename from CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs
rename to CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs
index e034bd35e216d1adace6baf103ad0b2777b16329..a0a639ed5d9b4ff39a4ba6f5aa2c9c0ee07c6006 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs
@@ -7,7 +7,7 @@ using Prism.Events;
 
 namespace CBSVisualizer.Messaging.Events.Queue
 {
-    public class PacketResponseEvent : PubSubEvent<(int Priority, PacketSubmitResult Result)>
+    public class PacketSubmitRequestEvent : PubSubEvent<ISet<int>>
     {
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs
similarity index 77%
rename from CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs
rename to CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs
index 51690fd74df03c1fac905e8d7dde54690159244f..0f3ac4f12b92a546cde37dfda4228b0411e8ed4f 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Models;
 using Prism.Events;
 
 namespace CBSVisualizer.Messaging.Events.Queue
@@ -11,7 +12,7 @@ namespace CBSVisualizer.Messaging.Events.Queue
     /// Sent from the queue to the link when it received a GateOpenedEvent.
     /// The payload is the packet that should be transmitted (or PriorityPacket.NoPacket) if we don't have any packets to transmit.
     /// </summary>
-    public class PacketSubmitEvent : PubSubEvent<PriorityPacket>
+    public class PacketSubmitResponseEvent : PubSubEvent<PriorityPacket>
     {
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs
new file mode 100644
index 0000000000000000000000000000000000000000..641c85f72e47b2dbd58ac946f5c25c4ae3048f56
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Prism.Events;
+
+namespace CBSVisualizer.Messaging.Events.Queue
+{
+    public enum PacketSubmitResult
+    {
+        /// <summary>
+        /// The packet was accepted and will be sent.
+        /// </summary>
+        Accepted,
+
+        /// <summary>
+        /// The packet was denied due to pre-closing.
+        /// </summary>
+        DeniedPreClosing,
+
+        /// <summary>
+        /// The packet was denied due to a higher-prio packet.
+        /// </summary>
+        DeniedHigherPriority
+    }
+
+    public class PacketSubmitResultEvent : PubSubEvent<(int Priority, PacketSubmitResult Result)>
+    {
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs
new file mode 100644
index 0000000000000000000000000000000000000000..260d2a607931a47ba01fd4498ca2f124d1ca26e0
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Prism.Events;
+
+namespace CBSVisualizer.Messaging.Events.Queue
+{
+    public class QueueGateOpenedEvent : PubSubEvent<ISet<int>>
+    {
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs
deleted file mode 100644
index 21304feb3849df82c630a62d71df1da1c59718a7..0000000000000000000000000000000000000000
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CBSVisualizer.Messaging.Events
-{
-    public enum PacketSubmitResult
-    {
-        /// <summary>
-        /// The packet was accepted and will be sent.
-        /// </summary>
-        Accepted,
-
-        /// <summary>
-        /// The packet was denied due to pre-closing.
-        /// </summary>
-        DeniedPreClosing,
-
-        /// <summary>
-        /// The packet was 
-        /// </summary>
-        DeniedHigherPrio
-    }
-    public interface ILinkCallback
-    {
-        /// <summary>
-        /// </summary>
-        /// <returns>the priority of the gate this callback belongs to</returns>
-        int GetPriority();
-
-        /// <summary>
-        /// Allows to perform necessary initialization operations.
-        /// </summary>
-        /// <returns></returns>
-        void Initialize();
-
-        /// <summary>
-        /// Called by the link when the gate of this queue has been opened.
-        /// </summary>
-        /// <param name="trySubmitFirstPacket">Called with the packet that should be sent. Returns the result of the attempt (Accepted or Denied because of whatever reason). </param>
-        void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket);
-
-        /// <summary>
-        /// Called by the link if the gate of the queue has been closed.
-        /// </summary>
-        void GateClosed();
-
-        /// <summary>
-        /// Called by the gate if the transmission of the given packet has been preempted.
-        /// </summary>
-        /// <param name="preemptedPacket"> the preempted packet.</param>
-        /// <param name="leftoverBytes"> the bytes that are left to sent.</param>
-        void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes);
-
-        /// <summary>
-        /// Called by the link when the transmission has started.
-        /// </summary>
-        /// <param name="bytesPerSecondRate"> the rate in bytes per second. </param>
-        void TransmissionStarted(long bytesPerSecondRate);
-
-        /// <summary>
-        /// Called when the transmission of the last packet has been completed.
-        /// </summary>
-        void TransmissionCompleted();
-    }
-    
-    /// <summary>
-    /// Used to register callbacks for different events that happen at the link.
-    /// </summary>
-    public class RegisterLinkCallbackEvent : PubSubEvent<ILinkCallback>
-    {
-    }
-}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs
index 4b25797e8ef5f002d8e860f31e75c01147e66962..dba806418bd733a1f0e394f3192ec174fb58f90b 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Prism.Events;
+using Prism.Events;
 
 namespace CBSVisualizer.Messaging.Events.Queue
 {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs
index 27a98321cff6b0c437d041022073002c374d6af9..9832ae73c45f8216561071ecf38fef02be5d96ba 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs
@@ -1,11 +1,6 @@
 using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
-namespace CBSVisualizer.Messaging.Events
+namespace CBSVisualizer.Messaging.Events.Simulation
 {
     public class SimulationStartedEvent : PubSubEvent
     {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs
index abf51a17a15c47caf3d5b0a7312007d276aeee73..3692413ec8a900f74638b91475d0ceaa7ba97be2 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs
@@ -1,11 +1,6 @@
 using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
-namespace CBSVisualizer.Messaging.Events
+namespace CBSVisualizer.Messaging.Events.Simulation
 {
     public class SimulationStoppedEvent : PubSubEvent
     {
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs
index 4600cc0b4c897659acc1146c6a86ac006ceeb511..0ab7fdbfa4e054a07c0282b6accd2a99177e9071 100644
--- a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CBSVisualizer.Messaging
+namespace CBSVisualizer.Messaging.Models
 {
     public class PriorityPacket
     {
@@ -13,7 +7,7 @@ namespace CBSVisualizer.Messaging
 
         private static readonly int PREEMPTION_TRAILER_SIZE_BYTES = 12;
 
-        public static PriorityPacket NoPacket { get; } = new PriorityPacket(int.MaxValue, int.MaxValue) { UniqueId = -1 };
+        public static PriorityPacket NoPacket { get; } = new PriorityPacket(-1, int.MaxValue) { UniqueId = -1 };
 
         /// <summary>
         /// The unique ID of the packet.
@@ -40,13 +34,7 @@ namespace CBSVisualizer.Messaging
         /// </summary>
         public int TrailerBytes { get; private set; }
 
-        public int Size
-        {
-            get
-            {
-                return PayloadBytes + HeaderBytes + TrailerBytes;
-            }
-        }
+        public int Size => PayloadBytes + HeaderBytes + TrailerBytes;
 
         private static long currentId = 0;
 
@@ -78,8 +66,6 @@ namespace CBSVisualizer.Messaging
 
         public override string ToString()
         {
-            
-
             return $"ID: {UniqueId} Priority: {Priority}, Size: {Size}";
         }
     }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs
index 54ee7b065482e7b3ea3f5773fa9c91fc484f2615..de8a7e7ad5ba66027b41cf50ba49130a993a1b12 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using CBSVisualizer.Core.Mvvm;
 using CBSVisualizer.Messaging.Events;
+using CBSVisualizer.Messaging.Events.Charts;
 using Prism.Events;
 using Prism.Regions;
 using SciChart.Charting.Model.ChartSeries;
@@ -20,8 +21,6 @@ namespace CBSVisualizer.Modules.Charts.ViewModels
             get;
         } = new ObservableConcurrentDictionary<int, ObservableCollection<IRenderableSeriesViewModel>>();
 
-        public Func<double, string> Formatter { get; } = x => new DateTime((long) x).ToString("HH:mm:ss");
-
         public ChartsViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) 
             : base(regionManager)
         {
@@ -59,20 +58,21 @@ namespace CBSVisualizer.Modules.Charts.ViewModels
 
             for (var idx = 0; idx <= 7; idx++)
             {
+
                 QueueSeries[idx] = new ObservableCollection<IRenderableSeriesViewModel>
                 {
                     new LineRenderableSeriesViewModel
                     {
                         StrokeThickness = 1,
                         AntiAliasing = true,
-                        DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Packets" },
+                        DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Packets"},
                         StyleKey = "PacketStyle",
                     },
                     new LineRenderableSeriesViewModel
                     {
                         StrokeThickness = 1,
                         AntiAliasing = true,
-                        DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Credit" },
+                        DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Credit"},
                         StyleKey = "CreditStyle",
                     }
                 };
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml
index ae844e2b72359c19fa11d23f2a9dbbcceedf57d2..f7c43911a6a023d948214a3c17112b1d6068808c 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml
@@ -10,28 +10,24 @@
              prism:ViewModelLocator.AutoWireViewModel="True" >
     <UserControl.Resources>
         <Style TargetType="s:FastLineRenderableSeries" x:Key="PacketStyle">
-            <Setter Property="StrokeDashArray" Value="5 5"/>
-            <Setter Property="StrokeThickness" Value="4"/>
+            <Setter Property="StrokeThickness" Value="1"/>
             <Setter Property="Stroke" Value="Orange"/>
             <Setter Property="SelectedSeriesStyle">
                 <Setter.Value>
                     <Style TargetType="s:FastLineRenderableSeries">
-                        <Setter Property="StrokeDashArray" Value="5 5"/>
-                        <Setter Property="StrokeThickness" Value="3"/>
+                        <Setter Property="StrokeThickness" Value="1"/>
                         <Setter Property="Stroke" Value="Orange"/>
                     </Style>
                 </Setter.Value>
             </Setter>
         </Style>
         <Style TargetType="s:FastLineRenderableSeries" x:Key="CreditStyle">
-            <Setter Property="StrokeDashArray" Value="5 5"/>
-            <Setter Property="StrokeThickness" Value="4"/>
+            <Setter Property="StrokeThickness" Value="1"/>
             <Setter Property="Stroke" Value="Blue"/>
             <Setter Property="SelectedSeriesStyle">
                 <Setter.Value>
                     <Style TargetType="s:FastLineRenderableSeries">
-                        <Setter Property="StrokeDashArray" Value="5 5"/>
-                        <Setter Property="StrokeThickness" Value="3"/>
+                        <Setter Property="StrokeThickness" Value="1"/>
                         <Setter Property="Stroke" Value="Blue"/>
                     </Style>
                 </Setter.Value>
@@ -56,15 +52,16 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
-                <s:NumericAxis AutoRange="Always"/>
+                <s:NumericAxis AutoRange="Always" />
             </s:SciChartSurface.YAxis>
 
         </s:SciChartSurface>
@@ -75,11 +72,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -94,11 +92,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -113,11 +112,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -132,11 +132,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -151,11 +152,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -170,11 +172,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
@@ -189,11 +192,12 @@
                     <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10"
                                       LegendPlacement="Inside" GetLegendDataFor="AllSeries"
                                       ShowVisibilityCheckboxes="True"/>
+                    <s:SeriesValueModifier/>
                 </s:ModifierGroup>
             </s:SciChartSurface.ChartModifier>
 
             <s:SciChartSurface.XAxis>
-                <s:DateTimeAxis AutoRange="Always"/>
+                <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/>
             </s:SciChartSurface.XAxis>
 
             <s:SciChartSurface.YAxis>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj
index 88a26a2c12a0e0f46aaf73769beed328a4c7a3ad..4bd8f21495747622572cea900f63cf161b85c9f7 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj
+++ b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj
@@ -5,8 +5,8 @@
     <AssemblyName>CBSVisualizer.Modules.Link</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="ParallelExtensionsExtras" Version="1.2.0" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
index b380d057c92a28cb8627a53477257823b53de76b..23472656e19a489174f274292185b45830af0091 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
@@ -1,61 +1,42 @@
 using System;
-using CBSVisualizer.Common;
-using CBSVisualizer.Core.Mvvm;
-using CBSVisualizer.Messaging;
-using CBSVisualizer.Messaging.Events;
-using CBSVisualizer.Services.SchedulingService.Interface;
-using CBSVisualizer.Services.SettingsService.Implementation;
-using log4net;
-using Prism.Events;
-using Prism.Regions;
-using System.Collections;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
-using System.Net.Sockets;
+using System.Reflection;
 using System.Threading;
 using System.Threading.Tasks;
+using CBSVisualizer.Common;
+using CBSVisualizer.Core.Mvvm;
 using CBSVisualizer.Messaging.Events.Queue;
+using CBSVisualizer.Messaging.Events.Simulation;
+using CBSVisualizer.Messaging.Models;
+using CBSVisualizer.Services.SchedulingService.Interface;
+using CBSVisualizer.Services.SettingService.Implementation;
+using log4net;
+using Prism.Events;
+using Prism.Regions;
 
 namespace CBSVisualizer.Modules.Link.ViewModels
 {
     public class LinkViewModel : RegionViewModelBase, IDisposable
     {
-        public ObservableConcurrentDictionary<int, ValueContainer<bool>> GateStatusDictionary { get; } =
-            new ObservableConcurrentDictionary<int, ValueContainer<bool>>
-            {
-                [0] = new ValueContainer<bool>(false),
-                [1] = new ValueContainer<bool>(false),
-                [2] = new ValueContainer<bool>(false),
-                [3] = new ValueContainer<bool>(false),
-                [4] = new ValueContainer<bool>(false),
-                [5] = new ValueContainer<bool>(false),
-                [6] = new ValueContainer<bool>(false),
-                [7] = new ValueContainer<bool>(false),
-            };
-
-        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
         private const string BitrateSettingKey = "bitrate";
-        private readonly SettingService settingService;
-        private int transmittableBytes;
 
-        private readonly ConcurrentDictionary<int, PriorityPacket> sendCandidates =
-            new ConcurrentDictionary<int, PriorityPacket>
-            {
-                [0] = PriorityPacket.NoPacket,
-                [1] = PriorityPacket.NoPacket,
-                [2] = PriorityPacket.NoPacket,
-                [3] = PriorityPacket.NoPacket,
-                [4] = PriorityPacket.NoPacket,
-                [5] = PriorityPacket.NoPacket,
-                [6] = PriorityPacket.NoPacket,
-                [7] = PriorityPacket.NoPacket,
-            };
+        private static readonly ILog Log =
+            LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType);
+
         private readonly IEventAggregator eventAggregator;
-        private CancellationTokenSource tokenSrc = new CancellationTokenSource();
-        private readonly BlockingCollection<PriorityPacket> sendQueue = new BlockingCollection<PriorityPacket>(new ConcurrentQueue<PriorityPacket>());
 
-        public LinkViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, ISchedulingService schedulingService, SettingService settingService)
+        private readonly ConcurrentBag<PriorityPacket> sendCandidates = new ConcurrentBag<PriorityPacket>();
+
+        private readonly SettingService settingService;
+
+        private Thread gateThread;
+        private CancellationTokenSource gateOpenedTokenSrc = new CancellationTokenSource();
+
+        public LinkViewModel(IRegionManager regionManager, IEventAggregator eventAggregator,
+            ISchedulingService schedulingService, SettingService settingService)
             : base(regionManager)
         {
             var scheduler = schedulingService;
@@ -64,56 +45,64 @@ namespace CBSVisualizer.Modules.Link.ViewModels
 
             InitializeQueueEventHandlers();
             InitializeSimulationHandlers(scheduler);
-            InitializeSendingThread();
         }
 
-        private void InitializeSendingThread()
-        {
-            new Thread(() =>
+        public ObservableConcurrentDictionary<int, ValueContainer<bool>> GateStatusDictionary { get; } =
+            new ObservableConcurrentDictionary<int, ValueContainer<bool>>
             {
-                while (true)
-                {
-                    var packetInTransit = sendQueue.Take();
-
-                    // Send the packet that we've just selected.
-                    eventAggregator.GetEvent<TransmissionStartedEvent>().Publish((packetInTransit.Priority,
-                        settingService.GetSettingValue<int>(BitrateSettingKey)));
-
-                    Thread.Sleep(TimeSpan.FromSeconds(packetInTransit.Size /
-                                                          settingService.GetSettingValue<double>(BitrateSettingKey)));
+                [0] = new ValueContainer<bool>(false),
+                [1] = new ValueContainer<bool>(false),
+                [2] = new ValueContainer<bool>(false),
+                [3] = new ValueContainer<bool>(false),
+                [4] = new ValueContainer<bool>(false),
+                [5] = new ValueContainer<bool>(false),
+                [6] = new ValueContainer<bool>(false),
+                [7] = new ValueContainer<bool>(false)
+            };
 
-                    eventAggregator.GetEvent<TransmissionFinishedEvent>().Publish(packetInTransit.Priority);
-                }
-            }).Start();
+        public void Dispose()
+        {
+            gateOpenedTokenSrc?.Dispose();
         }
 
         private void InitializeQueueEventHandlers()
         {
-            eventAggregator.GetEvent<GateOpenedEvent>().Subscribe(tuple =>
+            eventAggregator.GetEvent<GlobalGateOpenedEvent>().Subscribe(tuple =>
             {
-                log.Info($"The gates [{string.Join(", ", tuple.OpenedGates)}] have been opened for {tuple.OpenedTime} ms.");
+                // Set the status lamps accordingly.
+                SetStatusLamps(tuple.OpenedGates);
 
-                tokenSrc.Cancel();
-                tokenSrc = new CancellationTokenSource();
+                Log.Info(
+                    $"The gates [{string.Join(", ", tuple.OpenedGates)}] have been opened for {tuple.OpenedTime} ms.");
 
-                Task.Run(async () =>
-                {
-                    try
-                    {
-                        await HandleGateOpened(tuple);
-                    }
-                    catch (TaskCanceledException)
-                    {
-                    }
-                });
+                StopGateThread();
+
+                gateOpenedTokenSrc = new CancellationTokenSource();
+
+                // Calculate transmittable bytes.
+                var transmittableBytes = settingService.GetSettingValue<int>(BitrateSettingKey) * tuple.OpenedTime / 1000;
+
+                eventAggregator.GetEvent<QueueGateOpenedEvent>().Publish(tuple.OpenedGates);
+
+                gateThread = new Thread(() => HandleGateOpened(tuple.OpenedGates, transmittableBytes));
+                gateThread.Start();
             });
 
-            eventAggregator.GetEvent<PacketSubmitEvent>().Subscribe(packet =>
+            eventAggregator.GetEvent<PacketSubmitResponseEvent>().Subscribe(packet =>
             {
-                sendCandidates[packet.Priority] = packet;
+                sendCandidates.Add(packet);
             });
         }
 
+        private void StopGateThread()
+        {
+            gateOpenedTokenSrc.Cancel();
+            if (gateThread != null && gateThread.IsAlive)
+            {
+                gateThread.Join();
+            }
+        }
+
         private void InitializeSimulationHandlers(ISchedulingService scheduler)
         {
             eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(async () =>
@@ -121,18 +110,18 @@ namespace CBSVisualizer.Modules.Link.ViewModels
                 // Start scheduling.
                 try
                 {
-                    log.Info("Simulation started.");
+                    Log.Info("Simulation started.");
                     await scheduler.StartScheduling().ConfigureAwait(false);
                 }
                 catch (TaskCanceledException)
                 {
-                    log.Info("Scheduling was cancelled by button press.");
+                    Log.Info("Scheduling was cancelled by button press.");
                 }
             }, true);
 
             eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(() =>
             {
-                tokenSrc.Cancel();
+                gateOpenedTokenSrc?.Cancel();
 
                 // Stop the scheduler
                 scheduler.StopScheduling();
@@ -140,80 +129,109 @@ namespace CBSVisualizer.Modules.Link.ViewModels
                 // Reset all gate status lamps.
                 SetStatusLamps(new HashSet<int>());
 
-                log.Info("Simulation stopped");
+                // Terminate sending thread.
+                StopGateThread();
+
+                Log.Info("Simulation stopped");
             }, true);
         }
 
-        private async Task HandleGateOpened((int OpenedTime, ISet<int> OpenedGates) infoTuple)
+        private void HandleGateOpened(ISet<int> openedGates, int byteBudget)
         {
-            // Set the status lamps accordingly.
-            SetStatusLamps(infoTuple.OpenedGates);
+            // Copy transmittable bytes.
+            var totalBudget = byteBudget;
 
-            // Reset the packet in transit.
-            var packetInTransit = PriorityPacket.NoPacket;
+            while (!gateOpenedTokenSrc.IsCancellationRequested)
+            {
+                totalBudget = PerformCycle(openedGates, totalBudget);
+            }
+        }
 
-            // Calculate the transmittable bytes.
-            transmittableBytes = (settingService.GetSettingValue<int>(BitrateSettingKey) / 1000) * infoTuple.OpenedTime;
+        private int PerformCycle(ISet<int> openedGates, int cycleByteBudget)
+        {
+            // Init byte budget.
+            var cycleBudget = cycleByteBudget;
 
-            while (transmittableBytes > 0 && !tokenSrc.IsCancellationRequested)
-            {
+            // Cleanup the previous send candidates and request new packets from the queues with opened gates.
+            sendCandidates.Clear();
+            eventAggregator.GetEvent<PacketSubmitRequestEvent>().Publish(openedGates);
+
+            // Await all packets to arrive.
+            AwaitPacketArrival(openedGates.Count);
 
-                foreach (var openedGate in infoTuple.OpenedGates.OrderByDescending(packet => packet))
+            // When all packets have arrived, sort them descending and check if we can send them in time.
+            var selectedPacket = PriorityPacket.NoPacket;
+            foreach (var sendCandidate in sendCandidates.Except(Enumerable.Repeat(PriorityPacket.NoPacket, 1))
+                .OrderByDescending(packet => packet.Priority))
+            {
+                if (selectedPacket == PriorityPacket.NoPacket && CanSendInTime(sendCandidate, cycleBudget))
                 {
-                    if (tokenSrc.IsCancellationRequested)
-                    {
-                        return;
-                    }
-
-                    // If we've already selected a packet for transmission, notify and continue.
-                    if (packetInTransit != PriorityPacket.NoPacket)
-                    {
-                        eventAggregator.GetEvent<PacketResponseEvent>()
-                            .Publish((openedGate, PacketSubmitResult.DeniedHigherPrio));
-                        continue;
-                    }
-
-
-                    // If we can send the send candidate in time, we notify him.
-                    if (sendCandidates[openedGate] != PriorityPacket.NoPacket &&
-                        CanSendInTime(sendCandidates[openedGate]))
-                    {
-                        packetInTransit = sendCandidates[openedGate];
-                        transmittableBytes -= packetInTransit.Size;
-                        eventAggregator.GetEvent<PacketResponseEvent>()
-                            .Publish((openedGate, PacketSubmitResult.Accepted));
-
-                        sendQueue.Add(packetInTransit);
-                        sendCandidates[openedGate] = PriorityPacket.NoPacket;
-                    }
-                    else if (sendCandidates[openedGate] != PriorityPacket.NoPacket)
-                    {
-                        eventAggregator.GetEvent<PacketResponseEvent>()
-                            .Publish((openedGate, PacketSubmitResult.DeniedPreClosing));
-                    }
-                }
+                    // If we can send it in time and there was nothing selected yet...
+                    // ... reduce transmittable bytes.
+                    cycleBudget -= sendCandidate.Size;
+
+                    // ... notify the queue that its packet was selected.
+                    eventAggregator.GetEvent<PacketSubmitResultEvent>()
+                        .Publish((sendCandidate.Priority, PacketSubmitResult.Accepted));
 
-                if (packetInTransit == PriorityPacket.NoPacket)
+                    //... add it to the sending queue.
+                    selectedPacket = sendCandidate;
+                }
+                else if (selectedPacket == PriorityPacket.NoPacket && !CanSendInTime(sendCandidate, cycleBudget))
                 {
-                    continue;
+                    // If nothing was selected and we cannot send in time, the packet was denied due to pre-closing.
+                    // Notify the queue.
+                    eventAggregator.GetEvent<PacketSubmitResultEvent>()
+                        .Publish((sendCandidate.Priority, PacketSubmitResult.DeniedPreClosing));
                 }
-
-                if (tokenSrc.IsCancellationRequested)
+                else
                 {
-                    return;
+                    // Otherwise, the packet was denied due to higher prio.
+                    // Notify the queue.
+                    eventAggregator.GetEvent<PacketSubmitResultEvent>()
+                        .Publish((sendCandidate.Priority, PacketSubmitResult.DeniedHigherPriority));
                 }
+            }
+
+            // Send the packet that we've just selected.
+            if (selectedPacket != PriorityPacket.NoPacket)
+            {            
+                TransmitPacket(selectedPacket);
+            }
+
+
+            return cycleBudget;
+        }
 
-                packetInTransit = PriorityPacket.NoPacket;
+        private void TransmitPacket(PriorityPacket selectedPacket)
+        {
+            Log.Info($"Sending {selectedPacket}...");
+            eventAggregator.GetEvent<TransmissionStartedEvent>().Publish((selectedPacket.Priority,
+                settingService.GetSettingValue<int>(BitrateSettingKey)));
+
+            Thread.Sleep(TimeSpan.FromSeconds(selectedPacket.Size /
+                                              settingService.GetSettingValue<double>(BitrateSettingKey)));
+
+            Log.Info($"Transmission of {selectedPacket} finished!");
+            eventAggregator.GetEvent<TransmissionFinishedEvent>().Publish(selectedPacket.Priority);
+        }
+
+        private void AwaitPacketArrival(int openedGatesCount)
+        {
+            while (!gateOpenedTokenSrc.IsCancellationRequested && sendCandidates.Count != openedGatesCount)
+            {
+                Debug.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: Awaiting {openedGatesCount}, having {sendCandidates.Count}");
+                Thread.Sleep(50);
             }
         }
 
-        private bool CanSendInTime(PriorityPacket packet)
+        private bool CanSendInTime(PriorityPacket packet, int budget)
         {
-            return packet.Size <= transmittableBytes;
+            return packet.Size <= budget;
         }
 
         /// <summary>
-        /// Sets the status lamps according to the set.
+        ///     Sets the status lamps according to the set.
         /// </summary>
         /// <param name="openedGates">the set containing the opened gates</param>
         private void SetStatusLamps(ICollection<int> openedGates)
@@ -223,11 +241,5 @@ namespace CBSVisualizer.Modules.Link.ViewModels
                 GateStatusDictionary[key].Value = openedGates.Contains(key);
             }
         }
-
-        public void Dispose()
-        {
-            tokenSrc?.Dispose();
-            sendQueue?.Dispose();
-        }
     }
 }
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj
index 390006bb7dc98c42cafd102ccbc279905ca926cb..e6f31b2b3b5c9b174e43a8b1b6ad2a88b307b033 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj
+++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj
@@ -5,8 +5,8 @@
     <AssemblyName>CBSVisualizer.Modules.MenuBar</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs
index c94c3c881febff7d49816adb0b76ade8603e9e95..51033fb23fbdd61e12bad61d9b684c84533bf842 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs
@@ -4,29 +4,23 @@ using log4net;
 using Prism.Commands;
 using System.Threading;
 using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Events.Queue;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Modules.MenuBar.ViewModels
 {
     public partial class MenuBarViewModel
     {
-        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+        public DelegateCommand StartLoadGeneration { get; }
 
-        public DelegateCommand StartLoadGeneration { get; private set; }
-
-        public DelegateCommand StopLoadGeneration { get; private set; }
+        public DelegateCommand StopLoadGeneration { get; }
 
         private bool loadGenerationInProgress = false;
         private bool LoadGenerationInProgress
         {
-            get
-            {
-                return loadGenerationInProgress;
-            }
+            get => loadGenerationInProgress;
 
-            set
-            {
-                SetProperty(ref loadGenerationInProgress, value);
-            }
+            set => SetProperty(ref loadGenerationInProgress, value);
         }
 
         private CancellationTokenSource tokenSource = new CancellationTokenSource();
@@ -51,20 +45,16 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels
 
         private async Task GenerateLoad()
         {
-            int packetCount = 0;
-
             while (!tokenSource.IsCancellationRequested)
             {
                 eventAggregator.GetEvent<PacketArrivedEvent>().Publish(GenerateRandomPacket());
                 await Task.Delay(settings.GetSettingValue<int>("interarrival_time"));
-                log.Info($"I've generated {++packetCount} packets");
             }
         }
 
         private PriorityPacket GenerateRandomPacket()
         {
             PriorityPacket ret = packetService.GeneratePacket();
-            log.Info(ret);
             return ret;
         }
     }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs
index ee49c0fc51ea31ae7fe3126a61faa90c701eef0b..880c210236aef8720c3d12cc07b8fe0d3505aba6 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs
@@ -1,7 +1,8 @@
 using CBSVisualizer.Core.Mvvm;
 using CBSVisualizer.Messaging.Events;
+using CBSVisualizer.Messaging.Events.Simulation;
 using CBSVisualizer.Services.PacketService.Interface;
-using CBSVisualizer.Services.SettingsService.Implementation;
+using CBSVisualizer.Services.SettingService.Implementation;
 using Prism.Commands;
 using Prism.Events;
 using Prism.Regions;
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj
index 4028604f50fa2c2ce55fe7dfe3128eeca4aca053..ca0e11e4edfcc015da7acb86d4d2ec1a2e7f525f 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj
@@ -5,8 +5,8 @@
     <AssemblyName>CBSVisualizer.Modules.Queue.QueueGroup</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs
index 8bc55b4cfc34ca6c9f89563a3fe100ad72c7fbdf..93a7dd701af2046583c9b99351817295159afab8 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs
@@ -1,10 +1,9 @@
 using CBSVisualizer.Core;
-using CBSVisualizer.Modules.Queue.QueueGroup.Views;
 using Prism.Ioc;
 using Prism.Modularity;
 using Prism.Regions;
 
-namespace CBSVisualizer.Modules.Queue.QueueGroup
+namespace CBSVisualizer.Modules.QueueGroup
 {
     public class QueueGroupModule : IModule
     {
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs
index 81bc3b6cecbedc1da0d6d89adf78ee2c6368d31d..46a91e57c3d0ca04f6d6f51a5a28f4b05de5919d 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs
@@ -1,16 +1,7 @@
 using CBSVisualizer.Core.Mvvm;
-using CBSVisualizer.Modules.Queue.ViewModels;
-using Prism.Commands;
-using Prism.Mvvm;
 using Prism.Regions;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
-namespace CBSVisualizer.Modules.Queue.QueueGroup.ViewModels
+namespace CBSVisualizer.Modules.QueueGroup.ViewModels
 {
     public class QueueGroupViewModel : RegionViewModelBase
     {
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml
index 091e5a5f3f375a74b022b2c3597034f7ec6a13df..82db6dfb6169f3c925f8798646a3d434a6730499 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml
@@ -1,7 +1,6 @@
-<UserControl x:Class="CBSVisualizer.Modules.Queue.QueueGroup.Views.QueueGroup"
+<UserControl x:Class="CBSVisualizer.Modules.QueueGroup.Views.QueueGroup"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:local="clr-namespace:CBSVisualizer.Modules.Queue.QueueGroup.Views"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              mc:Ignorable="d" 
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs
index f9174517046edf5d5e791795b9c0d837b080d670..72b4c92eec965491512a3a7d4034ef444a5c04a2 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs
@@ -1,37 +1,24 @@
-using CBSVisualizer.Modules.Queue.ViewModels;
+using System.Windows.Controls;
+using CBSVisualizer.Modules.Queue.ViewModels;
 using CBSVisualizer.Services.PacketService.Interface;
+using CBSVisualizer.Services.SettingService.Implementation;
 using Prism.Events;
-using Prism.Ioc;
 using Prism.Regions;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
 
-namespace CBSVisualizer.Modules.Queue.QueueGroup.Views
+namespace CBSVisualizer.Modules.QueueGroup.Views
 {
     /// <summary>
     /// Interaction logic for ViewA.xaml
     /// </summary>
     public partial class QueueGroup : UserControl
     {
-        public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator, IPacketService packetService)
+        public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator, IPacketService packetService, SettingService settingService)
         {
             InitializeComponent();
 
             for (int prio = 7; prio >= 0; prio--)
             {
-                Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio, packetService));
+                Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio, packetService, settingService));
                 Grid.SetRow(newQueue, 7 - prio);
                 Grid.Children.Add(newQueue);
             }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj
index 44a18e90abdee68d8ccfa3c53825e3578dd46e4a..5759bee39f2b1a03229c7d44779833e97cc530be 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj
@@ -5,8 +5,8 @@
     <AssemblyName>CBSVisualizer.Modules.Queue</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
@@ -14,5 +14,6 @@
     <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" />
     <ProjectReference Include="..\CBSVisualizer.MessagingCore\CBSVisualizer.Messaging.csproj" />
     <ProjectReference Include="..\CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj" />
+    <ProjectReference Include="..\CBSVisualizer.Services.SettingsService\CBSVisualizer.Services.SettingService.csproj" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs
new file mode 100644
index 0000000000000000000000000000000000000000..afd71c4342f442d7cce09925ab8a313a3a085054
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Reflection;
+using CBSVisualizer.Common.Interfaces;
+using CBSVisualizer.Messaging.Events.Charts;
+using CBSVisualizer.Messaging.Models;
+using log4net;
+using Prism.Events;
+using Prism.Mvvm;
+
+namespace CBSVisualizer.Modules.Queue.QueueImplementations
+{
+    internal abstract class CbsQueueBase : BindableBase, IQueue
+    {
+        protected readonly IEventAggregator EventAggregator;
+        protected readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType);
+        protected readonly int Priority;
+        protected readonly ReadOnlyCollection<PriorityPacket> ReadOnlyQueue;
+        private readonly object creditLock = new object();
+
+        private long lastUpdateTimestamp;
+
+        private long credit;
+
+        private long internalSlopeBytesPerSecond;
+
+        protected CbsQueueBase(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue,
+            IEventAggregator eventAggregator)
+        {
+            Priority = priority;
+            ReadOnlyQueue = readOnlyQueue;
+            EventAggregator = eventAggregator;
+            PropertyChanged += HandleCreditChanged;
+        }
+
+        public long Credit
+        {
+            get
+            {
+                lock (creditLock)
+                {
+                    return credit;
+                }
+            }
+            protected set
+            {
+                lock (creditLock)
+                {
+                    SetProperty(ref credit, value);
+                }
+            }
+        }
+
+        public long IdleSlope
+        {
+            private get;
+            set;
+        }
+
+        public bool CanSendPacket(PriorityPacket sendCandidate)
+        {
+            UpdateUsingInternalSlope();
+            return Credit >= 0;
+        }
+
+        public void OnSimulationStarted()
+        {
+            // Reset everything.
+            Credit = 0;
+            internalSlopeBytesPerSecond = 0;
+            lastUpdateTimestamp = 0;
+        }
+
+        public void OnSimulationStopped()
+        {
+        }
+
+        public void OnGateOpened()
+        {
+            ApplyDefaultCreditRule();
+        }
+
+        public abstract void OnGateClosed();
+
+        public void OnPacketAccepted()
+        {
+            UpdateUsingInternalSlope();
+            Debug.WriteLine($"Queue {Priority}: My Packet was accepted.");
+        }
+
+        public abstract void OnPacketDeniedPreClosing();
+
+        public void OnPacketDeniedHigherPriority()
+        {
+            UpdateUsingInternalSlope();
+            Debug.WriteLine($"Queue {Priority}: My Packet was denied due to higher priority.");
+        }
+
+        public void OnTransmissionPreempted()
+        {
+            UpdateUsingInternalSlope();
+        }
+
+        protected void UpdateUsingInternalSlope()
+        {
+            UpdateCredit(internalSlopeBytesPerSecond);
+        }
+
+        public void OnTransmissionStarted()
+        {
+            UpdateCredit(0);
+        }
+
+        public void OnTransmissionFinished(PriorityPacket packetInTransit, long bytesPerSecond)
+        {
+            // Update credit manually.
+            Credit += (IdleSlope - bytesPerSecond) * packetInTransit.Size / bytesPerSecond;
+
+            ApplyDefaultCreditRule();
+        }
+
+        private void HandleCreditChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName != null && e.PropertyName.Equals("Credit"))
+            {
+                EventAggregator.GetEvent<CreditChangedEvent>().Publish((Priority, Credit));
+            }
+        }
+
+        private void ApplyDefaultCreditRule()
+        {
+            UpdateUsingInternalSlope();
+            if (ReadOnlyQueue.Count > 0 || Credit < 0)
+            {
+                UpdateCredit(IdleSlope);
+            }
+            else
+            {
+                UpdateCredit(0);
+            }
+        }
+
+        /// <summary>
+        ///     Updates the credit with the current internal slope and restarts the timer.
+        /// </summary>
+        /// <param name="newInternalSlopeBytesPerSecond">the new internal slope.</param>
+        protected void UpdateCredit(long newInternalSlopeBytesPerSecond)
+        {
+            lock (creditLock)
+            {
+                var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
+
+                var deltaCredit = 0L;
+                if (lastUpdateTimestamp != 0)
+                {
+                    deltaCredit = internalSlopeBytesPerSecond * (now - lastUpdateTimestamp) / 1000;
+                }
+
+                Credit += deltaCredit;
+
+                // Update the internal slope and the min value.
+                internalSlopeBytesPerSecond = newInternalSlopeBytesPerSecond;
+
+                // Reset update timestamp.
+                lastUpdateTimestamp = now;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs
new file mode 100644
index 0000000000000000000000000000000000000000..142f1d7271ff2e8ea5e0cd360688c0c5d74a2c9d
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Models;
+using Prism.Events;
+
+namespace CBSVisualizer.Modules.Queue.QueueImplementations
+{
+    internal class FrozenBehaviourQueue : CbsQueueBase
+    {
+        public FrozenBehaviourQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator)
+            : base(priority, readOnlyQueue, eventAggregator)
+        {
+        }
+
+        public override void OnGateClosed()
+        {
+            // Nothing happens here, as the credit is frozen in the Pre-Closing.
+        }
+
+        /// <summary>
+        /// The credit is frozen in the pre-closing phase.
+        /// </summary>
+        public override void OnPacketDeniedPreClosing()
+        {
+            UpdateCredit(0);
+        }
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs
index 445627309655496f4ccef9be5ea432bcbda48f7e..35a1bc567a8fc53d1f5dfaeee7dc36cb5e558231 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs
@@ -1,83 +1,56 @@
-using System.Collections.ObjectModel;
-using System.Threading.Tasks;
-using CBSVisualizer.Common;
-using CBSVisualizer.Common.Interfaces;
-using CBSVisualizer.Messaging;
-using CBSVisualizer.Messaging.Events;
-using CBSVisualizer.Messaging.Events.Queue;
-using log4net;
-using Prism.Events;
+using CBSVisualizer.Common.Interfaces;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Modules.Queue.QueueImplementations
 {
-    class NoCbsQueue : IQueue
+    internal class NoCbsQueue : IQueue
     {
         public long Credit { get; } = 0;
+        public long IdleSlope { get; set; }
 
-        public long IdleSlope { get; set; } = 0;
+        public bool CanSendPacket(PriorityPacket sendCandidate)
+        {
+            return true;
+        }
 
-        private ObservableCollection<PriorityPacket> queue;
-        private readonly IEventAggregator eventAggregator;
-        private readonly int priority;
-        private PriorityPacket lastSubmittedPacket = PriorityPacket.NoPacket;
-        private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType);
+        public void OnSimulationStarted()
+        {
+        }
+
+        public void OnSimulationStopped()
+        {
+        }
 
-        public ObservableCollection<PriorityPacket> Queue
+        public void OnGateOpened()
         {
-            set => queue = value;
         }
 
-        public NoCbsQueue(int priority, IEventAggregator eventAggregator)
+        public void OnGateClosed()
         {
-            this.eventAggregator = eventAggregator;
-            this.priority = priority;
         }
 
-        public Task OnGateOpened()
+        public void OnPacketAccepted()
         {
-            // Try to send a packet if we have any available.
-            lastSubmittedPacket = queue.GetFirstSynchronized();
-            eventAggregator.GetEvent<PacketSubmitEvent>().Publish(lastSubmittedPacket);
-            return Task.CompletedTask;
         }
 
-        public Task OnGateClosed()
+        public void OnPacketDeniedPreClosing()
         {
-            // Do nothing.
-            return Task.CompletedTask;
         }
 
-        public Task OnTransmissionStarted(long bytesPerSecond)
+        public void OnPacketDeniedHigherPriority()
         {
-            // Do nothing :-)
-            return Task.CompletedTask;
         }
 
-        public Task OnPacketPreempted(int leftoverBytes)
+        public void OnTransmissionPreempted()
         {
-            // Add a new packet with the leftover bytes and the preemption headers.
-            queue.PrependSynchronized(new PriorityPacket(priority, leftoverBytes));
-            return Task.CompletedTask;
         }
 
-        public Task OnTransmissionFinished()
+        public void OnTransmissionStarted()
         {
-            // Try to submit the next packet.
-            return OnGateOpened();
         }
 
-        public Task OnPacketResponse(PacketSubmitResult result)
+        public void OnTransmissionFinished(PriorityPacket packetInTransit, long bytesPerSecond)
         {
-            if (result == PacketSubmitResult.Accepted)
-            {
-                queue.RemoveSynchronized(lastSubmittedPacket);
-                lastSubmittedPacket = PriorityPacket.NoPacket;
-                return Task.CompletedTask;
-            }
-            else
-            {
-                return OnGateOpened();
-            }
         }
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0a8e33946f3d2cfdcd64be2ba685813dc8d4d5b9
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Models;
+using Prism.Events;
+
+namespace CBSVisualizer.Modules.Queue.QueueImplementations
+{
+    internal class ReturnToZeroQueue : CbsQueueBase
+    {
+        public ReturnToZeroQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator) : base(priority, readOnlyQueue, eventAggregator)
+        {
+        }
+
+        void HandleReturnToZero()
+        {
+            UpdateUsingInternalSlope();
+            if (Credit > 0)
+            {
+                UpdateCredit(0);
+                Credit = 0;
+            }
+        }
+
+        public override void OnGateClosed()
+        {
+            HandleReturnToZero();
+        }
+
+        public override void OnPacketDeniedPreClosing()
+        {
+            HandleReturnToZero();
+        }
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eee2f124cb8c0474da9becb9e56f1e1142ee9b61
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs
@@ -0,0 +1,30 @@
+using System.Collections.ObjectModel;
+using CBSVisualizer.Messaging.Models;
+using Prism.Events;
+
+namespace CBSVisualizer.Modules.Queue.QueueImplementations
+{
+    internal class StandardBehaviourQueue : CbsQueueBase
+    {
+        public StandardBehaviourQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator) : 
+            base(priority, readOnlyQueue, eventAggregator)
+        {
+        }
+        
+        /// <summary>
+        /// The standard behaviour, labelled (S) considers that the credit
+        /// increases up to gate-close event, and is frozen while the gate is
+        /// closed.
+        /// </summary>
+        public override void OnGateClosed()
+        {
+            UpdateCredit(0);
+        }
+
+        public override void OnPacketDeniedPreClosing()
+        {            
+            // Credit increases up to the GateClosingEvent, so do nothing on pre-closing.
+            UpdateUsingInternalSlope();
+        }
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
index 0df43c13ca333f7d3f500cd5a2065633216df69f..9ba6cda7bc09634803b6a084dd23bcb9eedd5fd4 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
@@ -1,24 +1,26 @@
-using CBSVisualizer.Core.Mvvm;
-using CBSVisualizer.Messaging;
-using CBSVisualizer.Messaging.Events;
-using CBSVisualizer.Services.PacketService.Interface;
-using log4net;
-using Prism.Commands;
-using Prism.Events;
-using Prism.Regions;
-using System;
-using System.Collections.ObjectModel;
+using System.Collections.ObjectModel;
 using System.Collections.Specialized;
-using System.Threading;
+using System.ComponentModel;
+using System.Reflection;
 using System.Threading.Tasks;
 using CBSVisualizer.Common;
 using CBSVisualizer.Common.Interfaces;
+using CBSVisualizer.Core.Mvvm;
+using CBSVisualizer.Messaging.Events.Charts;
 using CBSVisualizer.Messaging.Events.Queue;
+using CBSVisualizer.Messaging.Events.Simulation;
+using CBSVisualizer.Messaging.Models;
 using CBSVisualizer.Modules.Queue.QueueImplementations;
+using CBSVisualizer.Services.PacketService.Interface;
+using CBSVisualizer.Services.SettingService.Implementation;
+using log4net;
+using Prism.Commands;
+using Prism.Events;
+using Prism.Regions;
 
 namespace CBSVisualizer.Modules.Queue.ViewModels
 {
-    public sealed partial class QueueViewModel : RegionViewModelBase
+    public sealed class QueueViewModel : RegionViewModelBase
     {
         public enum CreditBehaviour
         {
@@ -35,90 +37,128 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
             ReturnToZero
         }
 
-        private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType);
+        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType);
         private readonly IEventAggregator eventAggregator;
         private readonly IPacketService packetService;
 
+        private volatile bool transmissionFinishedPending;
+
         private IQueue queueImplementation;
+        private CreditBehaviour selectedCreditBehaviour;
+        private long idleSlope;
+        private SettingService settings;
+
+        public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int priority,
+            IPacketService packetService, SettingService settings) :
+            base(regionManager)
+        {
+            this.eventAggregator = eventAggregator;
+            this.packetService = packetService;
+            this.settings = settings;
+
+            Priority = priority;
+            HandleLabels();
+
+            // Register handlers for the different events.
+            RegisterPacketEventHandlers();
+            RegisterLinkEventHandlers();
+            RegisterSimulationStartedEventHandlers();
+
+            PropertyChanged += HandleCreditBehaviourChanged;
+            Queue.CollectionChanged += QueueChangedHandler;
+
+            QueueImplementation = new NoCbsQueue();
+        }
+
         public IQueue QueueImplementation
         {
             get => queueImplementation;
-
             set => SetProperty(ref queueImplementation, value);
         }
 
-        private CreditBehaviour selectedCreditBehaviour;
         public CreditBehaviour SelectedCreditBehaviour
         {
             get => selectedCreditBehaviour;
-
             set => SetProperty(ref selectedCreditBehaviour, value);
         }
+
+        public long IdleSlope
+        {
+            get => idleSlope;
+            set => SetProperty(ref idleSlope, value);
+        }
+
         public int Priority { get; }
         public string PrioLabel { get; private set; }
         public string PacketLabel { get; private set; }
         public ObservableCollection<PriorityPacket> Queue { get; } = new ObservableCollection<PriorityPacket>();
-        public int IdleSlope { get; set; } = 100;
         public DelegateCommand GeneratePacketOnClick { get; private set; }
 
-        public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio, IPacketService packetService) :
-            base(regionManager)
+        private void RegisterSimulationStartedEventHandlers()
         {
-            this.eventAggregator = eventAggregator;
-            this.packetService = packetService;
-            this.QueueImplementation = new NoCbsQueue(prio, eventAggregator)
+            eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(async () =>
             {
-                Queue = Queue
-            };
-
-            Priority = prio;
-            HandleLabels();
-
-            // Register handlers for the different events.
-            RegisterPacketEventHandlers();
-            RegisterLinkEventHandlers();
+                QueueImplementation.IdleSlope = idleSlope;
+                await Task.Run(QueueImplementation.OnSimulationStarted);
+            });
 
-            PropertyChanged += HandleCreditBehaviourChanged;
-            Queue.CollectionChanged += QueueChangedHandler;
+            eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(async () =>
+            {
+                await Task.Run(QueueImplementation.OnSimulationStopped);
+            });
         }
 
         private void RegisterLinkEventHandlers()
         {
-            eventAggregator.GetEvent<GateOpenedEvent>().Subscribe(async tuple =>
+            eventAggregator.GetEvent<QueueGateOpenedEvent>().Subscribe(async openedGates =>
             {
-                if (tuple.OpenedGates == null)
-                {
-                    return;
-                }
-
-                if (tuple.OpenedGates.Contains(Priority))
+                if (openedGates.Contains(Priority))
                 {
-                    await QueueImplementation.OnGateOpened().ConfigureAwait(false);
+                    await Task.Run(QueueImplementation.OnGateOpened);
                 }
                 else
                 {
-                    await QueueImplementation.OnGateClosed().ConfigureAwait(false);
+                    await Task.Run(QueueImplementation.OnGateClosed);
                 }
             });
 
             eventAggregator.GetEvent<PacketPreemptedEvent>().Subscribe(async tuple =>
             {
-                if (tuple.Priority != Priority)
+                var (priority, leftoverBytes) = tuple;
+                if (priority != Priority)
                 {
                     return;
                 }
 
-                Log.Info($"Queue {Priority}: Packet was preempted!");
-                await QueueImplementation.OnPacketPreempted(tuple.LeftoverBytes).ConfigureAwait(false);
+                transmissionFinishedPending = false;
+
+                // Prepend leftover bytes and call queue implementation.
+                Queue.PrependSynchronized(new PriorityPacket(priority, leftoverBytes));
+                await Task.Run(QueueImplementation.OnTransmissionPreempted);
             });
 
-            eventAggregator.GetEvent<PacketResponseEvent>().Subscribe(async tuple =>
+            eventAggregator.GetEvent<PacketSubmitResultEvent>().Subscribe(async tuple =>
             {
-                if (tuple.Priority != Priority)
+                var (priority, result) = tuple;
+                if (priority != Priority)
                 {
                     return;
                 }
-                await QueueImplementation.OnPacketResponse(tuple.Result).ConfigureAwait(false);
+
+                // If the last submitted packet was accepted, remove the first packet from the queue.
+                // Otherwise, just call the corresponding handler.
+                if (result == PacketSubmitResult.Accepted)
+                {
+                    transmissionFinishedPending = true;
+                    await Task.Run(QueueImplementation.OnPacketAccepted);
+                } else if (result == PacketSubmitResult.DeniedHigherPriority)
+                {
+                    await Task.Run(QueueImplementation.OnPacketDeniedHigherPriority);
+                }
+                else
+                {
+                    await Task.Run(QueueImplementation.OnPacketDeniedPreClosing);
+                }
             });
 
             eventAggregator.GetEvent<TransmissionFinishedEvent>().Subscribe(async priority =>
@@ -127,18 +167,39 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
                 {
                     return;
                 }
-                Log.Info($"Queue {Priority}: Transmission finished!");
-                await QueueImplementation.OnTransmissionFinished().ConfigureAwait(false);
+
+                transmissionFinishedPending = false;
+                await Task.Run(() => QueueImplementation.OnTransmissionFinished(Queue.GetRemoveFirstSynchronized(), settings.GetSettingValue<long>("bitrate")));
             });
 
             eventAggregator.GetEvent<TransmissionStartedEvent>().Subscribe(async tuple =>
             {
-                if (tuple.Priority != Priority)
+                var (priority, bytesPerSecond) = tuple;
+                if (priority != Priority)
                 {
                     return;
                 }
-                Log.Info($"Queue {Priority}: Transmission started!");
-                await QueueImplementation.OnTransmissionStarted(tuple.BytesPerSecond).ConfigureAwait(false);
+
+                await Task.Run(QueueImplementation.OnTransmissionStarted);
+            });
+
+
+            eventAggregator.GetEvent<PacketSubmitRequestEvent>().Subscribe(openedGates =>
+            {
+                if (!openedGates.Contains(Priority))
+                {
+                    return;
+                }
+
+                var sendCandidate = Queue.GetFirstSynchronized();
+                if (!QueueImplementation.CanSendPacket(sendCandidate) || transmissionFinishedPending || sendCandidate == PriorityPacket.NoPacket )
+                {
+                    eventAggregator.GetEvent<PacketSubmitResponseEvent>().Publish(PriorityPacket.NoPacket);
+                }
+                else
+                {
+                    eventAggregator.GetEvent<PacketSubmitResponseEvent>().Publish(sendCandidate);
+                }
             });
         }
 
@@ -167,15 +228,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
             }
         }
 
-        private void HandleCreditBehaviourChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+        private void HandleCreditBehaviourChanged(object sender, PropertyChangedEventArgs e)
         {
             if (e.PropertyName != null && e.PropertyName.Equals("SelectedCreditBehaviour"))
             {
-                // TODO: Select appropriate credit behaviour.
-                queueImplementation = new NoCbsQueue(Priority, eventAggregator)
+                switch (SelectedCreditBehaviour)
                 {
-                    Queue = Queue
-                };
+                    case CreditBehaviour.Standard:
+                        QueueImplementation = new StandardBehaviourQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator);
+                        break;
+                    case CreditBehaviour.Frozen:
+                        QueueImplementation = new FrozenBehaviourQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator);
+                        break;
+                    case CreditBehaviour.ReturnToZero:
+                        QueueImplementation = new ReturnToZeroQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator);
+                        break;
+                    default:
+                        QueueImplementation = new NoCbsQueue();
+                        break;
+                }
             }
         }
 
@@ -183,20 +254,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
         {
             eventAggregator.GetEvent<PacketArrivedEvent>().Subscribe(packet =>
             {
-                if (packet.Priority != Priority)
-                {
-                    return;
-                }
+                if (packet.Priority != Priority) return;
 
                 Queue.AddSynchronized(packet);
             });
 
             GeneratePacketOnClick = new DelegateCommand(async () =>
             {
-                await Task.Run(() =>
-                {
-                    Queue.AddSynchronized(packetService.GeneratePacket(Priority));
-                });
+                await Task.Run(() => { Queue.AddSynchronized(packetService.GeneratePacket(Priority)); });
             });
         }
     }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
index 9643543231c88b1cc8c6374799c2cf9dedea277c..0ab958531a191fb80d44a1e630b538adbac83576 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
@@ -2,7 +2,6 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
-             xmlns:local="clr-namespace:CBSVisualizer.Modules.Queue.Views"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              mc:Ignorable="d" 
@@ -32,7 +31,7 @@
 
         <TextBox materialDesign:HintAssist.Hint="Idle Slope [byte/s]"
                  Style="{StaticResource MaterialDesignFloatingHintTextBox}"
-                 x:Name="CreditRateTextBox" Text="{Binding QueueImplementation.IdleSlope}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" Grid.RowSpan="2"/>
+                 x:Name="CreditRateTextBox" Text="{Binding IdleSlope}" Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" />
 
         <ComboBox Style="{StaticResource MaterialDesignFloatingHintComboBox}"
             materialDesign:TextFieldAssist.UnderlineBrush="{DynamicResource SecondaryAccentBrush}"
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs
index e20fa113f4e700db0a74d685dd072d612c2a6c5a..e926813e478310808e9e844ac5cb601f6e8d8949 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs
@@ -38,11 +38,13 @@ namespace CBSVisualizer.Modules.Queue.Views
 
         private static ObservableCollection<CreditBehaviour> InitList()
         {
-            ObservableCollection<CreditBehaviour> ret = new ObservableCollection<CreditBehaviour>();
-            ret.Add(CreditBehaviour.NoCbs);
-            ret.Add(CreditBehaviour.Frozen);
-            ret.Add(CreditBehaviour.Standard);
-            ret.Add(CreditBehaviour.ReturnToZero);
+            ObservableCollection<CreditBehaviour> ret = new ObservableCollection<CreditBehaviour>
+            {
+                CreditBehaviour.NoCbs,
+                CreditBehaviour.Frozen,
+                CreditBehaviour.Standard,
+                CreditBehaviour.ReturnToZero
+            };
             return ret;
         }
     }
diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj
index f9da61e23557705f8f1ba54d825927701759910a..93b5cac740f9c2c01488040115f411df5dc33ab1 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj
+++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj
@@ -5,8 +5,8 @@
     <AssemblyName>CBSVisualizer.Modules.SettingsDialog</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs
index ad966f202e8564bfd697996917b7818ac820f16b..90d59d4b4c050d3b8a19ac55dcb2878abed8ca0d 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs
@@ -1,8 +1,8 @@
 using CBSVisualizer.Core.Mvvm;
-using CBSVisualizer.Services.SettingsService.Implementation;
 using Prism.Regions;
 using Prism.Services.Dialogs;
 using System;
+using CBSVisualizer.Services.SettingService.Implementation;
 
 namespace CBSVisualizer.Modules.SettingsDialog.ViewModels
 {
diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml
index 6488678fc334cb4fd0427971e58494d2a1435c21..0c7bea91fa5fbcccb274c796da0bd02dba0d21ac 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml
+++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml
@@ -2,7 +2,6 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:local="clr-namespace:CBSVisualizer.Modules.SettingsDialog.Views"
-             xmlns:settings="clr-namespace:CBSVisualizer.Services.SettingsService.Types;assembly=CBSVisualizer.Services.SettingsService"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              mc:Ignorable="d" 
@@ -10,6 +9,8 @@
              xmlns:prism="http://prismlibrary.com/"
              prism:ViewModelLocator.AutoWireViewModel="True"
              xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+             xmlns:settings="clr-namespace:CBSVisualizer.Services.SettingService.Types;assembly=CBSVisualizer.Services.SettingsService"
+             xmlns:abstract="clr-namespace:CBSVisualizer.Services.SettingService.Types.Abstract;assembly=CBSVisualizer.Services.SettingsService"
              TextElement.Foreground="{DynamicResource MaterialDesignBody}"
              Background="{DynamicResource MaterialDesignPaper}"
              TextElement.FontWeight="Medium"
@@ -59,7 +60,7 @@
                 </GroupBox>
             </DataTemplate>
 
-            <DataTemplate DataType="{x:Type settings:SettingGroup}">
+            <DataTemplate DataType="{x:Type abstract:SettingGroup}">
                 <GroupBox Header="{Binding GroupName}">
                     <ItemsControl ItemsSource="{Binding Members}" />
                 </GroupBox>
diff --git a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj b/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj
deleted file mode 100644
index 723cd685d3a48fff964017fccea5fc52f4743bbe..0000000000000000000000000000000000000000
--- a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Prism.Core" Version="7.2.0.1422" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Messaging\CBSVisualizer.Messaging\CBSVisualizer.Messaging.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs b/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs
deleted file mode 100644
index 5e69ed4e778807ea53781cefaaa56540c33d6462..0000000000000000000000000000000000000000
--- a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using CBSVisualizer.Messaging.Events;
-using Prism.Events;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace CBSVisualizer.Services.GateControlListService
-{
-    public class GateControlListService
-    {
-        /// <summary>
-        /// The time between a GateOpened and its GateClosedEvent.
-        /// </summary>
-        public const int MILLISECONDS_BETWEEN_EVENTS = 300;
-
-        private readonly HashSet<int> QUEUE_0_SET = InitZeroQueueSet();
-
-        private readonly HashSet<int> OTHER_QUEUES_SET = InitOtherQueuesSet();
-
-        private volatile bool linkActive = false;
-
-        private Thread eventSchedulerThread;
-
-        private IEventAggregator eventAggregator;
-
-        public GateControlListService(IEventAggregator eventAggregator)
-        {
-            this.eventAggregator = eventAggregator;
-
-            eventAggregator.GetEvent<LinkActiveEvent>().Subscribe(() =>
-            {
-                linkActive = true;
-
-                eventSchedulerThread = new Thread(HandleEventScheduling);
-                eventSchedulerThread.Start();
-            });
-            eventAggregator.GetEvent<LinkDeactivatedEvent>().Subscribe(() =>
-            {
-                linkActive = false;
-                eventSchedulerThread.Join();
-            });
-        }
-
-        private void HandleEventScheduling(object obj)
-        {
-            while (linkActive)
-            {
-                // TODO: Implement this.       
-            }
-        }
-
-        private static HashSet<int> InitOtherQueuesSet()
-        {
-            HashSet<int> newSet = new HashSet<int>();
-            newSet.Add(1);
-            newSet.Add(2);
-            newSet.Add(3);
-            newSet.Add(4);
-            newSet.Add(5);
-            newSet.Add(6);
-            newSet.Add(7);
-            return newSet;
-        }
-
-        private static HashSet<int> InitZeroQueueSet()
-        {
-            HashSet<int> newSet = new HashSet<int>();
-            newSet.Add(0);
-            return newSet;
-        }
-    }
-}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs
index be5b66a7cab5bdb8b0d2c16ee72359a8770e0e6e..6d9d3741fef760212aa989388a25fa5c7b26497b 100644
--- a/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Services.PacketService.Implementation
 {
diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs
index 0b7ca4c7af53071b4507b212f86373a57d7c8de3..89c925b7c683fc298dca958f1941bf30f824daf2 100644
--- a/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs
@@ -1,6 +1,7 @@
 using CBSVisualizer.Messaging;
 using System;
 using System.Net.Mail;
+using CBSVisualizer.Messaging.Models;
 
 namespace CBSVisualizer.Services.PacketService.Interface
 {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj
index 20f292c650d0f693a36b2cb1468a1c85fad4880b..13ebb9059a91f1e78b5ef81e096896cfe67189c9 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj
+++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj
@@ -5,7 +5,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
+    <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Prism.Core" Version="7.2.0.1422" />
   </ItemGroup>
 
diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs
index 8d88e5e46c38b8fc28dab41359acbd1ddbcebab6..1d325fda668be6c352bae7dd3c325a79eec804bb 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs
@@ -1,27 +1,26 @@
 using CBSVisualizer.Messaging.Events;
 using CBSVisualizer.Services.SchedulingService.Interface;
-using CBSVisualizer.Services.SettingsService.Implementation;
 using log4net;
 using Prism.Events;
 using System;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
+using CBSVisualizer.Messaging.Events.Queue;
 
 namespace CBSVisualizer.Services.SchedulingService.Implementation
 {
     public class RandomSchedulingService : ISchedulingService
     {
         private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-        private const int ProcessingDelayMs = 1500;
         private const string MinDelaySettingKey = "random_scheduler_min_delay";
         private const string MaxDelaySettingKey = "random_scheduler_max_delay";
         private CancellationTokenSource tokenSource;
         private readonly Random random = new Random();
-        private readonly SettingService settings;
+        private readonly SettingService.Implementation.SettingService settings;
         private readonly IEventAggregator eventAggregator;
 
-        public RandomSchedulingService(IEventAggregator aggregator, SettingService settingService)
+        public RandomSchedulingService(IEventAggregator aggregator, SettingService.Implementation.SettingService settingService)
         {
             settings = settingService;
             eventAggregator = aggregator;
@@ -38,20 +37,20 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation
 
                 // Publish GateOpenedEvent for the high prio queue.
                 Log.Info("Publishing GateOpenedEvent [High Prio]");
-                eventAggregator.GetEvent<GateOpenedEvent>().Publish((OpenedTime: highPrioOpenedTime, OpenedGates: new HashSet<int> { 7 }));
+                eventAggregator.GetEvent<GlobalGateOpenedEvent>().Publish((OpenedTime: highPrioOpenedTime, OpenedGates: new HashSet<int> { 7 }));
 
                 // Wait for the specified time.
-                await Task.Delay(highPrioOpenedTime + ProcessingDelayMs, tokenSource.Token);
+                await Task.Delay(highPrioOpenedTime, tokenSource.Token);
 
                 // Get the opening time for the low prio.
                 var lowPrioOpenedTime = GetRandomWaitingTime();
 
                 // Publish another GateOpenedEvent for the other queues.
                 Log.Info("Publishing GateOpenedEvent [Lower Prio]");
-                eventAggregator.GetEvent<GateOpenedEvent>().Publish((OpenedTime: lowPrioOpenedTime, OpenedGates: new HashSet<int> { 0, 1, 2, 3, 4, 5, 6 }));
+                eventAggregator.GetEvent<GlobalGateOpenedEvent>().Publish((OpenedTime: lowPrioOpenedTime, OpenedGates: new HashSet<int> { 0, 1, 2, 3, 4, 5, 6 }));
 
                 // Wait for the specified time again.
-                await Task.Delay(lowPrioOpenedTime + ProcessingDelayMs, tokenSource.Token);
+                await Task.Delay(lowPrioOpenedTime, tokenSource.Token);
             }
         }
 
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj
index 6ba72c0c5c7caf355fbd9215255973bf80481707..eda9d73f06d6235e9421e4ce3541bb4321da4ddf 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj
@@ -7,7 +7,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
+    <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
     <PackageReference Include="Prism.Core" Version="7.2.0.1422" />
   </ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
index a14d183572169550d609269f3b744662ee514b53..d4f53f405dbcdee903b9257292417b69256aa2bc 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
@@ -1,12 +1,11 @@
-using CBSVisualizer.Services.SettingsService.Types;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using CBSVisualizer.Services.SettingService.Types;
+using CBSVisualizer.Services.SettingService.Types.Abstract;
 
-namespace CBSVisualizer.Services.SettingsService.Implementation
+namespace CBSVisualizer.Services.SettingService.Implementation
 {
     public class SettingService
     {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs
index 2c0b93af5768c256e50e4af6d706b03563a78c0a..f882a9ee6a14c2bc39c8dda8d3533a0bca5c516b 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs
@@ -1,11 +1,7 @@
-using Prism.Mvvm;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System;
+using Prism.Mvvm;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types.Abstract
 {
     public class Setting : BindableBase
     {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs
index 4e1a965e16449060ee1326505d1132d1ae8c2c23..5bd1d43d3a17e5adb78afdd9cbf682b16bb5e10c 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs
@@ -1,12 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Configuration;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.ObjectModel;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types.Abstract
 {
     public class SettingGroup
     {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs
index 7db018036c88776802e2a2c97c3bab1bef792a9d..44d30119ce0e95117e97a9ffdf60e53fdda46de5 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs
@@ -1,11 +1,6 @@
-using Prism.Mvvm;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using CBSVisualizer.Services.SettingService.Types.Abstract;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types
 {
     public class BooleanSetting : Setting<bool>
     {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs
index 3d37dc393f9b22d4f345fdce8d51b39c37b83c1a..cbd978e1be6c0a6a70de0b78f0d833a49e20c1ee 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs
@@ -1,9 +1,9 @@
-using Prism.Commands;
+using CBSVisualizer.Services.SettingService.Types.Abstract;
 using Microsoft.Win32;
-using System;
 using Ookii.Dialogs.Wpf;
+using Prism.Commands;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types
 {
 
     public enum SelectionMode
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs
index 9a9db697b3ea87e51191494767dd2ebc4717407e..19bd6d73e114fc4d065d52b55966c37f2108a741 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs
@@ -1,11 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using CBSVisualizer.Services.SettingService.Types.Abstract;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types
 {
     public class SelectionSetting : Setting<string>
     {
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs
index e5a20f16a7aebb7aa893bd070d6608a1b52aecb9..d7798131ea2f251711d5b5139ebc7170d7101fa1 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs
@@ -1,11 +1,6 @@
-using Prism.Commands;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using CBSVisualizer.Services.SettingService.Types.Abstract;
 
-namespace CBSVisualizer.Services.SettingsService.Types
+namespace CBSVisualizer.Services.SettingService.Types
 {
     public class StringSetting : Setting<string>
     {
diff --git a/CBSVisualizer/CBSVisualizer/App.xaml.cs b/CBSVisualizer/CBSVisualizer/App.xaml.cs
index edc32b1bbb17622552a8148a1b8b454b78d9dc52..6b3c9e03a17f239339242535bde5a65122ab8260 100644
--- a/CBSVisualizer/CBSVisualizer/App.xaml.cs
+++ b/CBSVisualizer/CBSVisualizer/App.xaml.cs
@@ -2,16 +2,16 @@
 using CBSVisualizer.Views;
 using System.Windows;
 using Prism.Modularity;
-using CBSVisualizer.Services.SettingsService.Implementation;
 using CBSVisualizer.Services.SchedulingService.Implementation;
-using CBSVisualizer.Modules.Queue.QueueGroup;
 using CBSVisualizer.Modules.Link;
 using CBSVisualizer.Modules.SettingsDialog;
 using CBSVisualizer.Modules.MenuBar;
 using CBSVisualizer.Modules.Charts;
+using CBSVisualizer.Modules.QueueGroup;
 using CBSVisualizer.Services.PacketService.Implementation;
 using CBSVisualizer.Services.PacketService.Interface;
 using CBSVisualizer.Services.SchedulingService.Interface;
+using CBSVisualizer.Services.SettingService.Implementation;
 using SciChart.Charting.Visuals;
 
 namespace CBSVisualizer
diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
index a34f54c868506f60c713a2343f501a8f50e037fa..bcbaa66d6567ea90fd752e55753b680e4a8c33c3 100644
--- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
+++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
@@ -7,8 +7,8 @@
     <AssemblyName>CBSVisualizer</AssemblyName>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="log4net" Version="2.0.9" />
-    <PackageReference Include="MaterialDesignThemes" Version="3.1.3" />
+    <PackageReference Include="log4net" Version="2.0.11" />
+    <PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
     <PackageReference Include="Prism.DryIoc" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
diff --git a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
index e8f27f4db3919e229369693c8ae02230b5e07b50..5478e0ce5b4f4ffc5946ff4888652c9ee10863e9 100644
--- a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
+++ b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
@@ -18,7 +18,7 @@
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="Auto"/>
-            <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="0.4*"/>
             <ColumnDefinition Width="*"/>
         </Grid.ColumnDefinitions>
         <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuBarRegion}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"/>