function LeakyBucket(Steps, TimeUnit, ScrnWidth, ScrnHeight, SourceAvgRate, SourceBurstiness, LB1BufferSize, LB1PermitsBufferSize, LB1PermitsRate, ...
    LB2BufferSize, LB2PermitsBufferSize, LB2PermitsRate)
% 
% Leaky-Bucket Simulator
%
% by Johannes Karlsson 2009 (johk@ee.kth.se)
%
% Usage:  LeakyBucket(Steps, TimeUnit, ScrnWidth, ScrnHeight, 
%            SourceAvgRate, SourceBurstiness, 
%            LBBufferSize, LBPermitsBufferSize, LBPermitsRate)
%
% where:  Steps - the number of time steps to be simulated.
%         TimeUnit - the time unit for each step in seconds.
%         ScrnWidth - sets the width of the figure.
%         ScrnHeight - sets the height of the figure.
%
%         SourceAvgRate - Average rate of the Poisson source (0, 1]
%         SourceBurstiness - Determines the burstiness [1, inf)
%         LBBufferSize - Size of the Leaky Bucket input buffer [0, inf]
%         LBPermitsBufferSize - Size of the permits buffer [0, inf]
%         LBPermitsRate - Rate at which permits are created
%
% Examples: 
%    Avg. rate control
%         LeakyBucket(1000, 0.3, 1024, 768, 1/3, 1, 4, inf, 1/5)
%    Peak rate control
%         LeakyBucket(1000, 0.3, 1024, 768, 1/3, 2, inf, 0, 1/2)
%
% Two Leaky Buckets in Cascade
% Usage:  LeakyBucket(Steps, TimeUnit, ScrnWidth, ScrnHeight, 
%            SourceAvgRate, SourceBurstiness, 
%            LB1BufferSize, LB1PermitsBufferSize, LB1PermitsRate)
%            LB2BufferSize, LB2PermitsBufferSize, LB2PermitsRate)
%
% Example:
%   Avg. rate control and Peak rate control
%         LeakyBucket(1000, 0.3, 1024, 768, 1/3, 1, 3, inf, 1/5, inf, 0, 1/3)
%




    DUAL_LB = false;

    Source.AvgRate = SourceAvgRate;
    Source.Burstiness = SourceBurstiness;
    Source.PacketsWaiting = 0;

    InputStage.Length = 20;
    InputStage.Buffer = zeros(InputStage.Length, 1);
    InputStage.PacketsWaiting = 0;
    InputStage.Back2Back = 0; 
    InputStage.Back2BackCounter = 0;
    InputStage.PacketCount = 0;
    
    LB1.BufferSize = LB1BufferSize;
    LB1.BufferPackets = 0;
    LB1.PermitsSize = LB1PermitsBufferSize;
    LB1.PermitsRate = LB1PermitsRate;
    LB1.Permits = 0;
    LB1.PermitsCounter = 0;
    LB1.PacketsWaiting = 0;
    LB1.PacketsDropped = 0;

    LB2 = [];
    if nargin > 9
        DUAL_LB = true;

        LB2.BufferSize = LB2BufferSize;
        LB2.BufferPackets = 0;
        LB2.PermitsSize = LB2PermitsBufferSize;
        LB2.PermitsRate = LB2PermitsRate;
        LB2.Permits = 0;
        LB2.PermitsCounter = 0;
        LB2.PacketsWaiting = 0;
        LB2.PacketsDropped = 0;
    end

    Transmission.Length = 20;
    Transmission.Buffer = zeros(Transmission.Length, 1);
    Transmission.PacketsWaiting = 0;
    Transmission.Back2Back = 0; 
    Transmission.Back2BackCounter = 0;
    Transmission.PacketCount = 0;

    [InputStage, LB1, LB2, Transmission] = InitializeScreen(InputStage, LB1, LB2, Transmission, ScrnWidth, ScrnHeight, DUAL_LB);
    
%    return;
    ii = 1;
    while ii < InputStage.Length;
        Source = SourceUpdate(Source);
        [Source, InputStage] = InputStageUpdate(Source, InputStage);
        ii = ii + 1;
    end
        
    ii = 0;

    while ii < Steps
        Source = SourceUpdate(Source);
        [Source, InputStage] = InputStageUpdate(Source, InputStage);
        [InputStage, LB1] = LeakyBucketUpdate(InputStage, LB1);
        if (DUAL_LB)
            [LB1, LB2] = LeakyBucketUpdate(LB1, LB2);
            [LB2, Transmission] = TransmissionUpdate(LB2, Transmission);
        else
            [LB1, Transmission] = TransmissionUpdate(LB1, Transmission);
        end

        UpdateScreen(InputStage, LB1, LB2, Transmission, ii+1, DUAL_LB);
    
        pause(TimeUnit);
        ii = ii + 1;
    end



end

function Source = SourceUpdate(Source)
    %% This generates a Poisson process (with burstiness)
    if rand < Source.AvgRate/Source.Burstiness
        Source.PacketsWaiting = Source.PacketsWaiting + Source.Burstiness;
    end
end


function [Source, InputStage] = InputStageUpdate(Source, InputStage)
    %% If there's a packet in the end of the buffer, move it to the waiting
    %% buffer.
    if InputStage.Buffer(InputStage.Length) == 1
        InputStage.PacketsWaiting = InputStage.PacketsWaiting + 1;
        InputStage.PacketCount = InputStage.PacketCount + 1;
    end
    
    %% Move all packets one step forward...
    InputStage.Buffer = [0; InputStage.Buffer(1:(end-1))];
    if Source.PacketsWaiting > 0
        InputStage.Buffer(1) = 1;
        Source.PacketsWaiting = Source.PacketsWaiting - 1;
        
        if InputStage.Buffer(2) == 1
            InputStage.Back2BackCounter = InputStage.Back2BackCounter + 1;
        end
    else
        if (InputStage.Back2BackCounter+1) > InputStage.Back2Back
            InputStage.Back2Back = InputStage.Back2BackCounter + 1;
        end
        InputStage.Back2BackCounter = 0;
    end
end


function [Input, LB] = LeakyBucketUpdate(Input, LB)
    LB.BufferPackets = LB.BufferPackets + Input.PacketsWaiting;
    Input.PacketsWaiting = 0;

    %% New permits arrive here
    LB.PermitsCounter = LB.PermitsCounter + 1;
    while LB.PermitsCounter > 1/LB.PermitsRate
        LB.PermitsCounter = LB.PermitsCounter - 1/LB.PermitsRate;
        LB.Permits = LB.Permits + 1;
    end
    %% How many packets can we permit
    PacketsToPermit = min(LB.BufferPackets, LB.Permits);
    
    LB.BufferPackets = LB.BufferPackets - PacketsToPermit;
    LB.Permits = LB.Permits - PacketsToPermit;
    LB.PacketsWaiting = LB.PacketsWaiting + PacketsToPermit;
    %% Check max buffer sizes (Note! This implementation allows the buffer
    %% sizes to be exceeded temporarly at each iteration)
    %% Drop packets/permits if the buffer sizes are exceeded
    if LB.BufferPackets > LB.BufferSize
        LB.PacketsDropped = LB.PacketsDropped + LB.BufferPackets - LB.BufferSize;
        LB.BufferPackets = LB.BufferSize;
    end
    LB.Permits = min(LB.Permits, LB.PermitsSize);
  
end

function [LB, Transmission] = TransmissionUpdate(LB, Transmission)
    %% If there's a packet in the end of the buffer, remove it (and put it in the waiting
    %% buffer.
    if Transmission.Buffer(Transmission.Length) == 1
        Transmission.PacketsWaiting = Transmission.PacketsWaiting + 1;
    end
    
    %% Move all packets one step forward...
    Transmission.Buffer = [0; Transmission.Buffer(1:(end-1))];
    if LB.PacketsWaiting > 0
        Transmission.Buffer(1) = 1;
        Transmission.PacketCount = Transmission.PacketCount + 1;
        if Transmission.Buffer(2) == 1
            Transmission.Back2BackCounter = Transmission.Back2BackCounter + 1;
        end
        LB.PacketsWaiting = LB.PacketsWaiting - 1;
    else
        if (Transmission.Back2BackCounter+1) > Transmission.Back2Back
            Transmission.Back2Back = Transmission.Back2BackCounter + 1;
        end
        Transmission.Back2BackCounter = 0;
    end

end

function [InputStage, LB1, LB2, Transmission] = InitializeScreen(InputStage, LB1, LB2, Transmission, Width, Height, DUAL)
    h = figure(123);
    FS = Height/800;
    clf;
    set(h, 'Position', [0, 0, Width, Height]);
    LM = 5;
    ISw = 25;                    %% InputStageWidth
    Pw = ISw/InputStage.Length;  %% PacketWidth
    Ph = 10;                     %% PacketHeight
    Py = 50;                     %% PacketYposition
    LBw = 40;                    %% LeakyBucketWidth
    LBc = 8;
    TRw = 25;                    %% TransmissionWidth
    subplot('Position', [0.0, 0.0, 1, 1]);
    axis off;
    rectangle('Position', [0, 0, 100, 100]);  %% Creates a box in which everything else should be
    hold on;
    tmp = text(LM, 95, 'Leaky-Bucket Simulator');
    set(tmp, 'FontSize', 25*FS);
    set(tmp, 'VerticalAlignment', 'top');
    tmp = text(LM, 3, 'by Johannes Karlsson 2009 (johk@ee.kth.se)');
    set(tmp, 'FontSize', 15*FS);
    set(tmp, 'VerticalAlignment', 'bottom');

    tmp = text(LM, 44, 'Input statistics');
    set(tmp, 'FontSize', 15*FS);
    set(tmp, 'VerticalAlignment', 'top');
    InputStage.avgGUI = text(LM, 40, '-');
    set(InputStage.avgGUI, 'FontSize', 15*FS);
    set(InputStage.avgGUI, 'VerticalAlignment', 'top');
    InputStage.b2bGUI = text(LM, 36, '-');
    set(InputStage.b2bGUI, 'FontSize', 15*FS);
    set(InputStage.b2bGUI, 'VerticalAlignment', 'top');

    LB1.droppedGUI = text(LM, 32, 'Packets dropped: 0');
    set(LB1.droppedGUI, 'FontSize', 15*FS);
    set(LB1.droppedGUI, 'VerticalAlignment', 'top');

    
    tmp = text(LM+ISw+LBw+1*Pw, 44, 'Output statistics');
    set(tmp, 'FontSize', 15*FS);
    set(tmp, 'VerticalAlignment', 'top');
    Transmission.avgGUI = text(LM+ISw+LBw+1*Pw, 40, '-');
    set(Transmission.avgGUI, 'FontSize', 15*FS);
    set(Transmission.avgGUI, 'VerticalAlignment', 'top');
    Transmission.b2bGUI = text(LM+ISw+LBw+1*Pw, 36, '-');
    set(Transmission.b2bGUI, 'FontSize', 15*FS);
    set(Transmission.b2bGUI, 'VerticalAlignment', 'top');

    % Draw input stage
    InputStage.GUI = zeros(InputStage.Length, 1);
    for ii=1:InputStage.Length
        InputStage.GUI(ii) = rectangle('Position', [LM + (ii-1)*Pw, Py, Pw, Ph]);
        set(InputStage.GUI(ii), 'FaceColor', 'white');
        set(InputStage.GUI(ii), 'EdgeColor', 'black');
    end
    % Draw transmission stage
    Transmission.GUI = zeros(Transmission.Length, 1);
    for ii=1:Transmission.Length
        Transmission.GUI(ii) = rectangle('Position', [LM+ISw+LBw+ii*Pw, Py, Pw, Ph]);
        set(Transmission.GUI(ii), 'FaceColor', 'white');
        set(Transmission.GUI(ii), 'EdgeColor', 'black');
    end
    
    if (DUAL == false)
        
        %% LeakyBucket box
        tmp = rectangle('Position', [LBc+LM+ISw-0.5*Pw, 30, 0.7*LBw, 54]);
        set(tmp, 'LineWidth', 2);

        LB1.GUI = [];
        for jj=1:(min(LB1.BufferSize, 5))
            LB1.GUI(jj) = rectangle('Position', [LBc+LM+ISw+(6-jj)*Pw, Py+13, Pw, Ph]);
            set(LB1.GUI(jj), 'FaceColor', 'white');
            set(LB1.GUI(jj), 'EdgeColor', 'black');
        end
        if LB1.BufferSize > 5
            set(LB1.GUI(min(LB1.BufferSize, 5)), 'LineStyle', 'none');
        end
        %% Permits
        LB1.pGUI = [];
        for jj=1:(min(LB1.PermitsSize, 5))
            LB1.pGUI(jj) = rectangle('Position', [LBc+LM+ISw+LBw/3, 45-(jj-1)*3, 3, 3]);
            set(LB1.pGUI(jj), 'FaceColor', 'white');
            set(LB1.pGUI(jj), 'EdgeColor', 'black');
        end
        if LB1.PermitsSize > 5
            set(LB1.pGUI(min(LB1.PermitsSize, 5)), 'LineStyle', 'none');
        end
        %% Permits on cue
        LB1.pqGUI = rectangle('Position', [LBc+LM+ISw+LBw/6, 41, 3, 3]);
        set(LB1.pqGUI, 'FaceColor', 'white');
        set(LB1.pqGUI, 'EdgeColor', 'black');
 %        tmp = line(LM+ISw+LBw/6+1.5*[1, 1], [Py+Ph/2-3.5, 44]);

%% This is not needed        
%        for jj=1:5
%            LB1.wGUI(jj) = rectangle('Position', [LM+ISw+2*LBw/3+(6-jj)*Pw, Py+13, Pw, Ph]);
%            set(LB1.wGUI(jj), 'FaceColor', 'white');
%            set(LB1.wGUI(jj), 'EdgeColor', 'black');
%        end
%        set(LB1.wGUI(5), 'LineStyle', 'none');
%%
        tmp = rectangle('Position', [LBc+LM+ISw+LBw/6+1.5-7*Height/(2*Width), Py+Ph/2-3.5, 7*Height/Width, 7], 'Curvature', [1, 1]);
        set(tmp, 'LineWidth', 2);
        tmp = line([LM+ISw, LBc+LM+ISw+LBw/6+1.5-7*Height/(2*Width)], (Py+Ph/2)*[1, 1]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        tmp = line([LBc+LM+ISw+LBw/6+1.5+7*Height/(2*Width), LM+ISw+LBw+1*Pw], (Py+Ph/2)*[1, 1]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        tmp = line(LBc+LM+ISw+LBw/6+1.5*[1, 1], [Py+Ph/2-3.5, 44]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        
        LB1.GUIt(1) = text(LBc+LM+ISw+3*Pw, Py+Ph+13+3, '-/-');
        LB1.GUIt(2) = text(LBc+LM+ISw+LBw/3 + 5, 39, '-/-');
        LB1.GUIt(3) = text(LBc+LM+ISw+LBw/3 + 4, 43, 'permits');

        for ii=1:length(LB1.GUIt)
            set(LB1.GUIt(ii), 'FontSize', 15*FS);
            set(LB1.GUIt(ii), 'VerticalAlignment', 'bottom');
        end
        
        
    else
    %% Two Leaky Buckets in cascade
        %% LeakyBucket box
        LBc = 1.5*Pw;
        oldLBw = LBw;
        LBw = 22;
        tmp = rectangle('Position', [LBc+LM+ISw-0.5*Pw, 30, 0.85*LBw, 54]);
        set(tmp, 'LineWidth', 2);

        LB1.GUI = [];
        for jj=1:(min(LB1.BufferSize, 5))
            LB1.GUI(jj) = rectangle('Position', [LBc+LM+ISw+(6-jj)*Pw, Py+13, Pw, Ph]);
            set(LB1.GUI(jj), 'FaceColor', 'white');
            set(LB1.GUI(jj), 'EdgeColor', 'black');
        end
        if LB1.BufferSize > 5
            set(LB1.GUI(min(LB1.BufferSize, 5)), 'LineStyle', 'none');
        end
        %% Permits
        LB1.pGUI = [];
        for jj=1:(min(LB1.PermitsSize, 5))
            LB1.pGUI(jj) = rectangle('Position', [LBc+LM+ISw+LBw/3, 45-(jj-1)*3, 3, 3]);
            set(LB1.pGUI(jj), 'FaceColor', 'white');
            set(LB1.pGUI(jj), 'EdgeColor', 'black');
        end
        if LB1.PermitsSize > 5
            set(LB1.pGUI(min(LB1.PermitsSize, 5)), 'LineStyle', 'none');
        end
        %% Permits on cue
        LB1.pqGUI = rectangle('Position', [LBc+LM+ISw+LBw/6, 41, 3, 3]);
        set(LB1.pqGUI, 'FaceColor', 'white');
        set(LB1.pqGUI, 'EdgeColor', 'black');
 
        tmp = rectangle('Position', [LBc+LM+ISw+LBw/6+1.5-7*Height/(2*Width), Py+Ph/2-3.5, 7*Height/Width, 7], 'Curvature', [1, 1]);
        set(tmp, 'LineWidth', 2);
        tmp = line([LM+ISw, LBc+LM+ISw+LBw/6+1.5-7*Height/(2*Width)], (Py+Ph/2)*[1, 1]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        tmp = line(LBc+LM+ISw+LBw/6+1.5*[1, 1], [Py+Ph/2-3.5, 44]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        tmp = line([LBc+LM+ISw+LBw/6+1.5+7*Height/(2*Width), 0.95*LBw + 0.5*Pw+LM+ISw+LBw/6+1.5-7*Height/(2*Width)], (Py+Ph/2)*[1, 1]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        
        LB1.GUIt(1) = text(LBc+LM+ISw+3*Pw, Py+Ph+13+3, '-/-');
        LB1.GUIt(2) = text(LBc+LM+ISw+LBw/3 + 4, 39, '-/-');
        LB1.GUIt(3) = text(LBc+LM+ISw+LBw/3 + 4, 43, 'permits');

        for ii=1:length(LB1.GUIt)
            set(LB1.GUIt(ii), 'FontSize', 15*FS);
            set(LB1.GUIt(ii), 'VerticalAlignment', 'bottom');
        end
        
        

        %% LeakyBucket box 2
        LBc = 0.95*LBw + 0.5*Pw;

        tmp = rectangle('Position', [LBc+LM+ISw-0.5*Pw, 30, 0.9*LBw, 54]);
        set(tmp, 'LineWidth', 2);

        LB2.GUI = [];
        for jj=1:(min(LB2.BufferSize, 5))
            LB2.GUI(jj) = rectangle('Position', [LBc+LM+ISw+(6-jj)*Pw, Py+13, Pw, Ph]);
            set(LB2.GUI(jj), 'FaceColor', 'white');
            set(LB2.GUI(jj), 'EdgeColor', 'black');
        end
        if LB2.BufferSize > 5
            set(LB2.GUI(min(LB2.BufferSize, 5)), 'LineStyle', 'none');
        end

        %% Permits
        LB2.pGUI = [];
        for jj=1:(min(LB2.PermitsSize, 5))
            LB2.pGUI(jj) = rectangle('Position', [LBc+LM+ISw+LBw/3, 45-(jj-1)*3, 3, 3]);
            set(LB2.pGUI(jj), 'FaceColor', 'white');
            set(LB2.pGUI(jj), 'EdgeColor', 'black');
        end
        if LB2.PermitsSize > 5
            set(LB2.pGUI(min(LB2.PermitsSize, 5)), 'LineStyle', 'none');
        end
        %% Permits on cue
        LB2.pqGUI = rectangle('Position', [LBc+LM+ISw+LBw/6, 41, 3, 3]);
        set(LB2.pqGUI, 'FaceColor', 'white');
        set(LB2.pqGUI, 'EdgeColor', 'black');
 
        tmp = rectangle('Position', [LBc+LM+ISw+LBw/6+1.5-7*Height/(2*Width), Py+Ph/2-3.5, 7*Height/Width, 7], 'Curvature', [1, 1]);
        set(tmp, 'LineWidth', 2);
        tmp = line([LBc+LM+ISw+LBw/6+1.5+7*Height/(2*Width), LM+ISw+oldLBw+Pw], (Py+Ph/2)*[1, 1]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        tmp = line(LBc+LM+ISw+LBw/6+1.5*[1, 1], [Py+Ph/2-3.5, 44]);
        set(tmp, 'LineWidth', 2);
        set(tmp, 'Color', 'black');
        
        LB2.GUIt(1) = text(LBc+LM+ISw+3*Pw, Py+Ph+13+3, '-/-');
        LB2.GUIt(2) = text(LBc+LM+ISw+LBw/3 + 4, 39, '-/-');
        LB2.GUIt(3) = text(LBc+LM+ISw+LBw/3 + 4, 43, 'permits');

        for ii=1:length(LB2.GUIt)
            set(LB2.GUIt(ii), 'FontSize', 15*FS);
            set(LB2.GUIt(ii), 'VerticalAlignment', 'bottom');
        end
        
        
        
    
    end

   

end

function UpdateScreen(InputStage, LB1, LB2, Transmission, TIME, DUAL)
    %% InputStage
    for ii=1:length(InputStage.GUI)
        if InputStage.Buffer(ii) == 1
            set(InputStage.GUI(ii), 'FaceColor', 'red');
        else
            set(InputStage.GUI(ii), 'FaceColor', 'white');
        end
    end
    %% LB InputBuffer
    for ii=1:length(LB1.GUI)
        if LB1.BufferPackets >= ii
            set(LB1.GUI(ii), 'FaceColor', 'red');
        else
            set(LB1.GUI(ii), 'FaceColor', 'white');
        end
    end

    %% Permits
    for ii=1:length(LB1.pGUI)
        if LB1.Permits >= ii
            set(LB1.pGUI(ii), 'FaceColor', 'blue');
        else
            set(LB1.pGUI(ii), 'FaceColor', 'white');
        end
    end
    %% Permits on cue?
    if (LB1.PermitsCounter+1) > 1/LB1.PermitsRate    
        set(LB1.pqGUI, 'FaceColor', 'blue');
    else
        set(LB1.pqGUI, 'FaceColor', 'white');
    end
%% Leaky Bucket 2
    if (DUAL == true)
        %% LB InputBuffer
        for ii=1:length(LB2.GUI)
            if LB2.BufferPackets >= ii
                set(LB2.GUI(ii), 'FaceColor', 'red');
            else
                set(LB2.GUI(ii), 'FaceColor', 'white');
            end
        end

        %% Permits
        for ii=1:length(LB2.pGUI)
            if LB2.Permits >= ii
                set(LB2.pGUI(ii), 'FaceColor', 'blue');
            else
                set(LB2.pGUI(ii), 'FaceColor', 'white');
            end
        end
        %% Permits on cue?
        if (LB2.PermitsCounter+1) > 1/LB2.PermitsRate
            set(LB2.pqGUI, 'FaceColor', 'blue');
        else
            set(LB2.pqGUI, 'FaceColor', 'white');
        end
        
    end
    
    
    %% Transmission
    for ii=1:length(Transmission.GUI)
        if Transmission.Buffer(ii) == 1
            set(Transmission.GUI(ii), 'FaceColor', 'green');
        else
            set(Transmission.GUI(ii), 'FaceColor', 'white');
        end
    end
    
    
    set(LB1.GUIt(1), 'String', [num2str(LB1.BufferPackets), ' / ', num2str(LB1.BufferSize)]);
    set(LB1.GUIt(2), 'String', [num2str(LB1.Permits), ' / ', num2str(LB1.PermitsSize)]);
    
    set(InputStage.avgGUI, 'String', ['Avg. rate: ', num2str(InputStage.PacketCount/TIME)]);
    set(InputStage.b2bGUI, 'String', ['Max. Back-to-back: ', num2str(InputStage.Back2Back)]);
    set(Transmission.avgGUI, 'String', ['Avg. rate: ', num2str(Transmission.PacketCount/TIME)]);
    set(Transmission.b2bGUI, 'String', ['Max. Back-to-back: ', num2str(Transmission.Back2Back)]);

    
    if (DUAL == false)
        set(LB1.droppedGUI, 'String', ['Packets dropped: ', num2str(100*LB1.PacketsDropped/InputStage.PacketCount), ' %']);
    else
        set(LB1.droppedGUI, 'String', ['Packets dropped: ', num2str(100*(LB1.PacketsDropped+LB2.PacketsDropped)/InputStage.PacketCount), ' %']);
        set(LB2.GUIt(1), 'String', [num2str(LB2.BufferPackets), ' / ', num2str(LB2.BufferSize)]);
        set(LB2.GUIt(2), 'String', [num2str(LB2.Permits), ' / ', num2str(LB2.PermitsSize)]);
    end
    
%        LB1.BufferSize = LB1BufferSize;
%    LB1.BufferPackets = 0;
%    LB1.PermitsSize = LB1PermitsBufferSize;
%    LB1.PermitsRate = LB1PermitsRate;
%    LB1.Permits = 0;
%    LB1.PermitsCounter = 0;
%    LB1.PacketsWaiting = 0;

end