text:
package edu.cmu.sv.ws.ssnoc.data.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import edu.cmu.sv.ws.ssnoc.common.logging.Log;
import edu.cmu.sv.ws.ssnoc.data.SQL;
import edu.cmu.sv.ws.ssnoc.data.po.LocationCrumbPO;
	/**
	 * DAO implementation for saving User information in the H2 database.
	 *
	 */
	public class LocationCrumbDAOImpl extends BaseDAOImpl implements ILocationCrumbDAO {
		/**
		 * This method will load users from the DB with specified account location. If
		 * no location information (null) is provided, it will load all users.
		 *
		 * @return - List of users
		 */
		public List<LocationCrumbPO> loadLocationCrumbs() {
			Log.enter();

			String query = SQL.FIND_ALL_LOCATION_CRUMBS;

			List<LocationCrumbPO> locationCrumbs = new ArrayList<LocationCrumbPO>();
			try (Connection conn = getConnection();
					PreparedStatement stmt = conn.prepareStatement(query);) {
				locationCrumbs = processResults(stmt);
			} catch (SQLException e) {
				handleException(e);
				Log.exit(locationCrumbs);
			}

			return locationCrumbs;
		}

		private List<LocationCrumbPO> processResults(PreparedStatement stmt) {
			Log.enter(stmt);

			if (stmt == null) {
				Log.warn("Inside processResults method with NULL statement object.");
				return null;
			}

			Log.debug("Executing stmt = " + stmt);
			List<LocationCrumbPO> users = new ArrayList<LocationCrumbPO>();
			try (ResultSet rs = stmt.executeQuery()) {
				while (rs.next()) {
					LocationCrumbPO po = new LocationCrumbPO();
					po = new LocationCrumbPO();
					po.setLocationCrumbId(rs.getLong(1));
					po.setUserId(rs.getLong(2));
					po.setLocation(rs.getString(3));
					po.setCreatedAt(rs.getTimestamp(4));

					users.add(po);
				}
			} catch (SQLException e) {
				handleException(e);
			} finally {
				Log.exit(users);
			}

			return users;
		}

		/**
		 * This method will save the information of the location crumb into the database.
		 *
		 * @param locationCrumbPO
		 *            - Location crumb information to be saved.
		 */
		@Override
		public long save(LocationCrumbPO locationCrumbPO) {
			Log.enter(locationCrumbPO);
			long locationId = 0;
			if (locationCrumbPO == null) {
				Log.warn("Inside save method with locationCrumbPO == NULL");
				return locationId;
			}

			try (Connection conn = getConnection();
					PreparedStatement stmt = conn.prepareStatement(SQL.INSERT_LOCATION_CRUMB,  Statement.RETURN_GENERATED_KEYS)) {
				stmt.setLong(1, locationCrumbPO.getUserId());
				stmt.setString(2, locationCrumbPO.getLocation());

				int rowCount = stmt.executeUpdate();
				Log.trace("Statement executed, and " + rowCount + " rows inserted.");

				try (ResultSet generatedKeys = stmt.getGeneratedKeys()) {
		            if (generatedKeys.next()) {
		            	locationId = generatedKeys.getLong(1);
		            }
		            else {
		                throw new SQLException("Creating location failed, no ID obtained.");
		            }
		        }
			} catch (SQLException e) {
				handleException(e);
			} finally {
				Log.exit();
			}
			return locationId;
		}

		@Override
		public List<LocationCrumbPO> loadLocationCrumbsByUserName(String userName) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public LocationCrumbPO loadLocationCrumbById(int locationCrumbId) {
			// TODO Auto-generated method stub
			return null;
		}
}


text:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

Issue 1810

NotoMono-Regular

lang="en":ɨ

lang="en-fonnapa":ɨ

lang="en-fonipa":ɨ

-----------------------------------

NotoSans-Regular

lang="en":ɨ

lang="en-fonnapa":ɨ

lang="en-fonipa":ɨ

-----------------------------------

NotoSans-Italic

lang="en":ɨ

lang="en-fonnapa":ɨ

lang="en-fonipa":ɨ

-----------------------------------

NotoSerif

lang="en":ɨ

lang="en-fonnapa":ɨ

lang="en-fonipa":ɨ

-----------------------------------

NotoSerif-Italic

lang="en":ɨ

lang="en-fonnapa":ɨ

lang="en-fonipa":ɨ

 Tested font directory:
https://github.com/googlefonts/noto-fonts/tree/main/unhinted/otf/NotoSans/NotoSans-Regular.otf
 https://github.com/googlefonts/noto-fonts/tree/main/unhinted/otf/NotoSans/NotoSans-Italic.otf
 https://github.com/googlefonts/noto-fonts/tree/main/unhinted/otf/NotoSerif/NotoSerif-Regular.otf
 https://github.com/googlefonts/noto-fonts/tree/main/unhinted/otf/NotoSerif/NotoSerif-Italic.otf
 https://github.com/googlefonts/noto-fonts/tree/main/unhinted/otf/NotoMono/NotoMono-Regular.otf

Test created date:

redpajama_set_name: RedPajamaGithub


text:
<?php

  /**
   * company_card helper
   *
   * @package activeCollab.modules.system
   * @subpackage helpers
   */

  /**
   * Render company card
   *
   * Parameters:
   *
   * - company - company instance
   *
   * @param array $params
   * @param Smarty $smarty
   * @return string
   */
  function smarty_function_company_card($params, &$smarty) {
    $company = array_var($params, 'company');
    if(!instance_of($company, 'Company')) {
      return new InvalidParamError('company', $company, '$company is expected to be an valid Company instance', true);
    } // if

    $smarty->assign(array(
      '_card_company' => $company,
      '_card_options' => $company->getOptions(get_logged_user())
    ));
    return $smarty->fetch(get_template_path('_card', 'companies', SYSTEM_MODULE));
  } // smarty_function_company_card

?>


text:
As we honed our problem statement, we developed a **user persona** to focus our decision making about the product we would build.

###This is Mario:

![Image Title](https://dl.dropboxusercontent.com/u/7894148/Chronicles/mario-persona.jpg)

---

###This is Mario's journey to starting a business:

![Image Title](http://cl.ly/WIjw/unnamed.png)

###Main challenges (as told by our users):

**"I could not borrow money from the bank because MY credit was really bad"**

**"One of the things I know based on my experience is that you have to be properly capitalized. It means you have to have enough money to start"**

**"I didn't have the time to look for incentives and I knew it was going to be all this paperwork to file and I didnt have numbers to back it up."**


text:
#include "modules/video_coding/main/source/jitter_buffer.h"

#include <algorithm>
#include <cassert>

#include "modules/video_coding/main/source/event.h"
#include "modules/video_coding/main/source/frame_buffer.h"
#include "modules/video_coding/main/source/inter_frame_delay.h"
#include "modules/video_coding/main/source/internal_defines.h"
#include "modules/video_coding/main/source/jitter_buffer_common.h"
#include "modules/video_coding/main/source/jitter_estimator.h"
#include "modules/video_coding/main/source/packet.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/trace.h"

namespace webrtc {

// Predicates used when searching for frames in the frame buffer list
class FrameSmallerTimestamp {
 public:
  FrameSmallerTimestamp(uint32_t timestamp) : timestamp_(timestamp) {}
  bool operator()(VCMFrameBuffer* frame) {
    return (LatestTimestamp(timestamp_, frame->TimeStamp(), NULL) ==
        timestamp_);
  }

 private:
  uint32_t timestamp_;
};

class FrameEqualTimestamp {
 public:
  FrameEqualTimestamp(uint32_t timestamp) : timestamp_(timestamp) {}
  bool operator()(VCMFrameBuffer* frame) {
    return (timestamp_ == frame->TimeStamp());
  }

 private:
  uint32_t timestamp_;
};

class CompleteDecodableKeyFrameCriteria {
 public:
  bool operator()(VCMFrameBuffer* frame) {
    return (frame->FrameType() == kVideoFrameKey) &&
           (frame->GetState() == kStateComplete ||
            frame->GetState() == kStateDecodable);
  }
};

// Constructor
VCMJitterBuffer::VCMJitterBuffer(TickTimeBase* clock,
                                 WebRtc_Word32 vcmId,
                                 WebRtc_Word32 receiverId,
                                 bool master) :
    _vcmId(vcmId),
    _receiverId(receiverId),
    _clock(clock),
    _running(false),
    _critSect(CriticalSectionWrapper::CreateCriticalSection()),
    _master(master),
    _frameEvent(),
    _packetEvent(),
    _maxNumberOfFrames(kStartNumberOfFrames),
    _frameBuffers(),
    _frameList(),
    _lastDecodedState(),
    _packetsNotDecodable(0),
    _receiveStatistics(),
    _incomingFrameRate(0),
    _incomingFrameCount(0),
    _timeLastIncomingFrameCount(0),
    _incomingBitCount(0),
    _incomingBitRate(0),
    _dropCount(0),
    _numConsecutiveOldFrames(0),
    _numConsecutiveOldPackets(0),
    _discardedPackets(0),
    _jitterEstimate(vcmId, receiverId),
    _delayEstimate(_clock->MillisecondTimestamp()),
    _rttMs(0),
    _nackMode(kNoNack),
    _lowRttNackThresholdMs(-1),
    _highRttNackThresholdMs(-1),
    _NACKSeqNum(),
    _NACKSeqNumLength(0),
    _waitingForKeyFrame(false),
    _firstPacket(true)
{
    memset(_frameBuffers, 0, sizeof(_frameBuffers));
    memset(_receiveStatistics, 0, sizeof(_receiveStatistics));
    memset(_NACKSeqNumInternal, -1, sizeof(_NACKSeqNumInternal));

    for (int i = 0; i< kStartNumberOfFrames; i++)
    {
        _frameBuffers[i] = new VCMFrameBuffer();
    }
}

// Destructor
VCMJitterBuffer::~VCMJitterBuffer()
{
    Stop();
    for (int i = 0; i< kMaxNumberOfFrames; i++)
    {
        if (_frameBuffers[i])
        {
            delete _frameBuffers[i];
        }
    }
    delete _critSect;
}

void
VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs)
{
    if (this != &rhs)
    {
        _critSect->Enter();
        rhs._critSect->Enter();
        _vcmId = rhs._vcmId;
        _receiverId = rhs._receiverId;
        _running = rhs._running;
        _master = !rhs._master;
        _maxNumberOfFrames = rhs._maxNumberOfFrames;
        _incomingFrameRate = rhs._incomingFrameRate;
        _incomingFrameCount = rhs._incomingFrameCount;
        _timeLastIncomingFrameCount = rhs._timeLastIncomingFrameCount;
        _incomingBitCount = rhs._incomingBitCount;
        _incomingBitRate = rhs._incomingBitRate;
        _dropCount = rhs._dropCount;
        _numConsecutiveOldFrames = rhs._numConsecutiveOldFrames;
        _numConsecutiveOldPackets = rhs._numConsecutiveOldPackets;
        _discardedPackets = rhs._discardedPackets;
        _jitterEstimate = rhs._jitterEstimate;
        _delayEstimate = rhs._delayEstimate;
        _waitingForCompletion = rhs._waitingForCompletion;
        _rttMs = rhs._rttMs;
        _NACKSeqNumLength = rhs._NACKSeqNumLength;
        _waitingForKeyFrame = rhs._waitingForKeyFrame;
        _firstPacket = rhs._firstPacket;
        _lastDecodedState =  rhs._lastDecodedState;
        _packetsNotDecodable = rhs._packetsNotDecodable;
        memcpy(_receiveStatistics, rhs._receiveStatistics,
               sizeof(_receiveStatistics));
        memcpy(_NACKSeqNumInternal, rhs._NACKSeqNumInternal,
               sizeof(_NACKSeqNumInternal));
        memcpy(_NACKSeqNum, rhs._NACKSeqNum, sizeof(_NACKSeqNum));
        for (int i = 0; i < kMaxNumberOfFrames; i++)
        {
            if (_frameBuffers[i] != NULL)
            {
                delete _frameBuffers[i];
                _frameBuffers[i] = NULL;
            }
        }
        _frameList.clear();
        for (int i = 0; i < _maxNumberOfFrames; i++)
        {
            _frameBuffers[i] = new VCMFrameBuffer(*(rhs._frameBuffers[i]));
            if (_frameBuffers[i]->Length() > 0)
            {
                FrameList::reverse_iterator rit = std::find_if(
                    _frameList.rbegin(), _frameList.rend(),
                    FrameSmallerTimestamp(_frameBuffers[i]->TimeStamp()));
                _frameList.insert(rit.base(), _frameBuffers[i]);
            }
        }
        rhs._critSect->Leave();
        _critSect->Leave();
    }
}

// Start jitter buffer
void
VCMJitterBuffer::Start()
{
    CriticalSectionScoped cs(_critSect);
    _running = true;
    _incomingFrameCount = 0;
    _incomingFrameRate = 0;
    _incomingBitCount = 0;
    _incomingBitRate = 0;
    _timeLastIncomingFrameCount = _clock->MillisecondTimestamp();
    memset(_receiveStatistics, 0, sizeof(_receiveStatistics));

    _numConsecutiveOldFrames = 0;
    _numConsecutiveOldPackets = 0;
    _discardedPackets = 0;

    _frameEvent.Reset(); // start in a non-signaled state
    _packetEvent.Reset(); // start in a non-signaled state
    _waitingForCompletion.frameSize = 0;
    _waitingForCompletion.timestamp = 0;
    _waitingForCompletion.latestPacketTime = -1;
    _firstPacket = true;
    _NACKSeqNumLength = 0;
    _waitingForKeyFrame = false;
    _rttMs = 0;
    _packetsNotDecodable = 0;

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId,
                 _receiverId), "JB(0x%x): Jitter buffer: start", this);
}

// Stop jitter buffer
void
VCMJitterBuffer::Stop()
{
    _critSect->Enter();
    _running = false;
    _lastDecodedState.Reset();
    _frameList.clear();
    for (int i = 0; i < kMaxNumberOfFrames; i++)
    {
        if (_frameBuffers[i] != NULL)
        {
            static_cast<VCMFrameBuffer*>(_frameBuffers[i])->SetState(kStateFree);
        }
    }

    _critSect->Leave();
    _frameEvent.Set(); // Make sure we exit from trying to get a frame to decoder
    _packetEvent.Set(); // Make sure we exit from trying to get a sequence number
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId,
                 _receiverId), "JB(0x%x): Jitter buffer: stop", this);
}

bool
VCMJitterBuffer::Running() const
{
    CriticalSectionScoped cs(_critSect);
    return _running;
}

// Flush jitter buffer
void
VCMJitterBuffer::Flush()
{
    CriticalSectionScoped cs(_critSect);
    FlushInternal();
}

// Must be called under the critical section _critSect
void
VCMJitterBuffer::FlushInternal()
{
    // Erase all frames from the sorted list and set their state to free.
    _frameList.clear();
    for (WebRtc_Word32 i = 0; i < _maxNumberOfFrames; i++)
    {
        ReleaseFrameInternal(_frameBuffers[i]);
    }
    _lastDecodedState.Reset(); // TODO (mikhal): sync reset
    _packetsNotDecodable = 0;

    _frameEvent.Reset();
    _packetEvent.Reset();

    _numConsecutiveOldFrames = 0;
    _numConsecutiveOldPackets = 0;

    // Also reset the jitter and delay estimates
    _jitterEstimate.Reset();
    _delayEstimate.Reset(_clock->MillisecondTimestamp());

    _waitingForCompletion.frameSize = 0;
    _waitingForCompletion.timestamp = 0;
    _waitingForCompletion.latestPacketTime = -1;

    _firstPacket = true;

    _NACKSeqNumLength = 0;

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId,
                 _receiverId), "JB(0x%x): Jitter buffer: flush", this);
}

// Set the frame state to free and remove it from the sorted
// frame list. Must be called from inside the critical section _critSect.
void
VCMJitterBuffer::ReleaseFrameInternal(VCMFrameBuffer* frame)
{
    if (frame != NULL && frame->GetState() != kStateDecoding)
    {
        frame->SetState(kStateFree);
    }
}

// Update frame state (set as complete if conditions are met)
// Doing it here increases the degree of freedom for e.g. future
// reconstructability of separate layers. Must be called under the
// critical section _critSect.
VCMFrameBufferEnum
VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
{
    if (frame == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId), "JB(0x%x) FB(0x%x): "
                         "UpdateFrameState NULL frame pointer", this, frame);
        return kNoError;
    }

    int length = frame->Length();
    if (_master)
    {
        // Only trace the primary jitter buffer to make it possible to parse
        // and plot the trace file.
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                     "JB(0x%x) FB(0x%x): Complete frame added to jitter buffer,"
                     " size:%d type %d",
                     this, frame,length,frame->FrameType());
    }

    if (length != 0 && !frame->GetCountedFrame())
    {
        // ignore Ack frames
        _incomingFrameCount++;
        frame->SetCountedFrame(true);
    }

    // Check if we should drop frame
    // an old complete frame can arrive too late
    if (_lastDecodedState.IsOldFrame(frame))
    {
        // Frame is older than the latest decoded frame, drop it. Will be
        // released by CleanUpOldFrames later.
        frame->Reset();
        frame->SetState(kStateEmpty);

        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                     "JB(0x%x) FB(0x%x): Dropping old frame in Jitter buffer",
                     this, frame);
        _dropCount++;
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                     "Jitter buffer drop count: %d, consecutive drops: %u",
                     _dropCount, _numConsecutiveOldFrames);
        // Flush() if this happens consistently.
        _numConsecutiveOldFrames++;
        if (_numConsecutiveOldFrames > kMaxConsecutiveOldFrames) {
          FlushInternal();
          return kFlushIndicator;
        }
        return kNoError;
    }
    _numConsecutiveOldFrames = 0;
    frame->SetState(kStateComplete);

    // Update receive statistics. We count all layers, thus when you use layers
    // adding all key and delta frames might differ from frame count
    if (frame->IsSessionComplete())
    {
        switch (frame->FrameType())
        {
        case kVideoFrameKey:
            {
                _receiveStatistics[0]++;
                break;
            }
        case kVideoFrameDelta:
            {
                _receiveStatistics[1]++;
                break;
            }
        case kVideoFrameGolden:
            {
                _receiveStatistics[2]++;
                break;
            }
        case kVideoFrameAltRef:
            {
                _receiveStatistics[3]++;
                break;
            }
        default:
            assert(false);

        }
    }
    const FrameList::iterator it = FindOldestCompleteContinuousFrame(false);
    VCMFrameBuffer* oldFrame = NULL;
    if (it != _frameList.end())
    {
        oldFrame = *it;
    }

    // Only signal if this is the oldest frame.
    // Not necessary the case due to packet reordering or NACK.
    if (!WaitForNack() || (oldFrame != NULL && oldFrame == frame))
    {
        _frameEvent.Set();
    }
    return kNoError;
}

// Get received key and delta frames
WebRtc_Word32
VCMJitterBuffer::GetFrameStatistics(WebRtc_UWord32& receivedDeltaFrames,
                                    WebRtc_UWord32& receivedKeyFrames) const
{
    {
        CriticalSectionScoped cs(_critSect);
        receivedDeltaFrames = _receiveStatistics[1] + _receiveStatistics[3];
        receivedKeyFrames = _receiveStatistics[0] + _receiveStatistics[2];
    }
    return 0;
}

WebRtc_UWord32 VCMJitterBuffer::NumNotDecodablePackets() const {
  CriticalSectionScoped cs(_critSect);
  return _packetsNotDecodable;
}

WebRtc_UWord32 VCMJitterBuffer::DiscardedPackets() const {
  CriticalSectionScoped cs(_critSect);
  return _discardedPackets;
}

// Gets frame to use for this timestamp. If no match, get empty frame.
WebRtc_Word32
VCMJitterBuffer::GetFrame(const VCMPacket& packet, VCMEncodedFrame*& frame)
{
    if (!_running) // don't accept incoming packets until we are started
    {
        return VCM_UNINITIALIZED;
    }

    _critSect->Enter();
    // Does this packet belong to an old frame?
    if (_lastDecodedState.IsOldPacket(&packet))
    {
        // Account only for media packets
        if (packet.sizeBytes > 0)
        {
            _discardedPackets++;
            _numConsecutiveOldPackets++;
        }
        // Update last decoded sequence number if the packet arrived late and
        // belongs to a frame with a timestamp equal to the last decoded
        // timestamp.
        _lastDecodedState.UpdateOldPacket(&packet);

        if (_numConsecutiveOldPackets > kMaxConsecutiveOldPackets)
        {
            FlushInternal();
            _critSect->Leave();
            return VCM_FLUSH_INDICATOR;
        }
        _critSect->Leave();
        return VCM_OLD_PACKET_ERROR;
    }
    _numConsecutiveOldPackets = 0;

    FrameList::iterator it = std::find_if(
        _frameList.begin(),
        _frameList.end(),
        FrameEqualTimestamp(packet.timestamp));

    if (it != _frameList.end()) {
      frame = *it;
      _critSect->Leave();
      return VCM_OK;
    }

    _critSect->Leave();

    // No match, return empty frame
    frame = GetEmptyFrame();
    if (frame != NULL)
    {
        return VCM_OK;
    }
    // No free frame! Try to reclaim some...
    _critSect->Enter();
    RecycleFramesUntilKeyFrame();
    _critSect->Leave();

    frame = GetEmptyFrame();
    if (frame != NULL)
    {
        return VCM_OK;
    }
    return VCM_JITTER_BUFFER_ERROR;
}

// Deprecated! Kept for testing purposes.
VCMEncodedFrame*
VCMJitterBuffer::GetFrame(const VCMPacket& packet)
{
    VCMEncodedFrame* frame = NULL;
    if (GetFrame(packet, frame) < 0)
    {
        return NULL;
    }
    return frame;
}

// Get empty frame, creates new (i.e. increases JB size) if necessary
VCMFrameBuffer*
VCMJitterBuffer::GetEmptyFrame()
{
    if (!_running) // don't accept incoming packets until we are started
    {
        return NULL;
    }

    _critSect->Enter();

    for (int i = 0; i <_maxNumberOfFrames; ++i)
    {
        if (kStateFree == _frameBuffers[i]->GetState())
        {
            // found a free buffer
            _frameBuffers[i]->SetState(kStateEmpty);
            _critSect->Leave();
            return _frameBuffers[i];
        }
    }

    // Check if we can increase JB size
    if (_maxNumberOfFrames < kMaxNumberOfFrames)
    {
        VCMFrameBuffer* ptrNewBuffer = new VCMFrameBuffer();
        ptrNewBuffer->SetState(kStateEmpty);
        _frameBuffers[_maxNumberOfFrames] = ptrNewBuffer;
        _maxNumberOfFrames++;

        _critSect->Leave();
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
        VCMId(_vcmId, _receiverId), "JB(0x%x) FB(0x%x): Jitter buffer "
        "increased to:%d frames", this, ptrNewBuffer, _maxNumberOfFrames);
        return ptrNewBuffer;
    }
    _critSect->Leave();

    // We have reached max size, cannot increase JB size
    return NULL;
}

// Find oldest complete frame used for getting next frame to decode
// Must be called under critical section
FrameList::iterator
VCMJitterBuffer::FindOldestCompleteContinuousFrame(bool enable_decodable) {
  // If we have more than one frame done since last time, pick oldest.
  VCMFrameBuffer* oldest_frame = NULL;
  FrameList::iterator it = _frameList.begin();

  // When temporal layers are available, we search for a complete or decodable
  // frame until we hit one of the following:
  // 1. Continuous base or sync layer.
  // 2. The end of the list was reached.
  for (; it != _frameList.end(); ++it)  {
    oldest_frame = *it;
    VCMFrameBufferStateEnum state = oldest_frame->GetState();
    // Is this frame complete or decodable and continuous?
    if ((state == kStateComplete ||
        (enable_decodable && state == kStateDecodable)) &&
        _lastDecodedState.ContinuousFrame(oldest_frame)) {
      break;
    } else {
      int temporal_id = oldest_frame->TemporalId();
      oldest_frame = NULL;
      if (temporal_id <= 0) {
        // When temporal layers are disabled or we have hit a base layer
        // we break (regardless of continuity and completeness).
        break;
      }
    }
  }

  if (oldest_frame == NULL) {
    // No complete frame no point to continue.
    return _frameList.end();
  } else  if (_waitingForKeyFrame &&
              oldest_frame->FrameType() != kVideoFrameKey) {
    // We are waiting for a key frame.
    return _frameList.end();
  }

  // We have a complete continuous frame.
  return it;
}

// Call from inside the critical section _critSect
void
VCMJitterBuffer::RecycleFrame(VCMFrameBuffer* frame)
{
    if (frame == NULL)
    {
        return;
    }

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(_vcmId, _receiverId),
                 "JB(0x%x) FB(0x%x): RecycleFrame, size:%d",
                 this, frame, frame->Length());

    ReleaseFrameInternal(frame);
}

// Calculate frame and bit rates
WebRtc_Word32
VCMJitterBuffer::GetUpdate(WebRtc_UWord32& frameRate, WebRtc_UWord32& bitRate)
{
    CriticalSectionScoped cs(_critSect);
    const WebRtc_Word64 now = _clock->MillisecondTimestamp();
    WebRtc_Word64 diff = now - _timeLastIncomingFrameCount;
    if (diff < 1000 && _incomingFrameRate > 0 && _incomingBitRate > 0)
    {
        // Make sure we report something even though less than
        // 1 second has passed since last update.
        frameRate = _incomingFrameRate;
        bitRate = _incomingBitRate;
    }
    else if (_incomingFrameCount != 0)
    {
        // We have received frame(s) since last call to this function

        // Prepare calculations
        if (diff <= 0)
        {
            diff = 1;
        }
        // we add 0.5f for rounding
        float rate = 0.5f + ((_incomingFrameCount * 1000.0f) / diff);
        if (rate < 1.0f) // don't go below 1, can crash
        {
            rate = 1.0f;
        }

        // Calculate frame rate
        // Let r be rate.
        // r(0) = 1000*framecount/delta_time.
        // (I.e. frames per second since last calculation.)
        // frameRate = r(0)/2 + r(-1)/2
        // (I.e. fr/s average this and the previous calculation.)
        frameRate = (_incomingFrameRate + (WebRtc_Word32)rate) >> 1;
        _incomingFrameRate = (WebRtc_UWord8)rate;

        // Calculate bit rate
        if (_incomingBitCount == 0)
        {
            bitRate = 0;
        }
        else
        {
            bitRate = 10 * ((100 * _incomingBitCount) /
                      static_cast<WebRtc_UWord32>(diff));
        }
        _incomingBitRate = bitRate;

        // Reset count
        _incomingFrameCount = 0;
        _incomingBitCount = 0;
        _timeLastIncomingFrameCount = now;

    }
    else
    {
        // No frames since last call
        _timeLastIncomingFrameCount = _clock->MillisecondTimestamp();
        frameRate = 0;
        bitRate = 0;
        _incomingBitRate = 0;
    }

    return 0;
}

// Returns immediately or a X ms event hang waiting for a complete frame,
// X decided by caller
VCMEncodedFrame*
VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
{
    if (!_running)
    {
        return NULL;
    }

    _critSect->Enter();

    CleanUpOldFrames();

    if (_lastDecodedState.init() && WaitForNack()) {
      _waitingForKeyFrame = true;
    }

    FrameList::iterator it = FindOldestCompleteContinuousFrame(false);
    if (it == _frameList.end())
    {
        if (maxWaitTimeMS == 0)
        {
            _critSect->Leave();
            return NULL;
        }
        const WebRtc_Word64 endWaitTimeMs = _clock->MillisecondTimestamp()
                                            + maxWaitTimeMS;
        WebRtc_Word64 waitTimeMs = maxWaitTimeMS;
        while (waitTimeMs > 0)
        {
            _critSect->Leave();
            const EventTypeWrapper ret =
                  _frameEvent.Wait(static_cast<WebRtc_UWord32>(waitTimeMs));
            _critSect->Enter();
            if (ret == kEventSignaled)
            {
                // are we closing down the Jitter buffer
                if (!_running)
                {
                    _critSect->Leave();
                    return NULL;
                }

                // Finding oldest frame ready for decoder, but check
                // sequence number and size
                CleanUpOldFrames();
                it = FindOldestCompleteContinuousFrame(false);
                if (it == _frameList.end())
                {
                    waitTimeMs = endWaitTimeMs -
                                 _clock->MillisecondTimestamp();
                }
                else
                {
                    break;
                }
            }
            else
            {
                _critSect->Leave();
                return NULL;
            }
        }
        // Inside critSect
    }
    else
    {
        // we already have a frame reset the event
        _frameEvent.Reset();
    }

    if (it == _frameList.end())
    {
        // Even after signaling we're still missing a complete continuous frame
        _critSect->Leave();
        return NULL;
    }

    VCMFrameBuffer* oldestFrame = *it;
    it = _frameList.erase(it);

    // Update jitter estimate
    const bool retransmitted = (oldestFrame->GetNackCount() > 0);
    if (retransmitted)
    {
        _jitterEstimate.FrameNacked();
    }
    else if (oldestFrame->Length() > 0)
    {
        // Ignore retransmitted and empty frames.
        UpdateJitterAndDelayEstimates(*oldestFrame, false);
    }

    oldestFrame->SetState(kStateDecoding);

    CleanUpOldFrames();

    if (oldestFrame->FrameType() == kVideoFrameKey)
    {
        _waitingForKeyFrame = false;
    }

    _critSect->Leave();

    // We have a frame - update decoded state with frame info.
    _lastDecodedState.SetState(oldestFrame);

    return oldestFrame;
}

WebRtc_UWord32
VCMJitterBuffer::GetEstimatedJitterMS()
{
    CriticalSectionScoped cs(_critSect);
    return GetEstimatedJitterMsInternal();
}

WebRtc_UWord32
VCMJitterBuffer::GetEstimatedJitterMsInternal()
{
    WebRtc_UWord32 estimate = VCMJitterEstimator::OPERATING_SYSTEM_JITTER;

    // Compute RTT multiplier for estimation
    // _lowRttNackThresholdMs == -1 means no FEC.
    double rttMult = 1.0f;
    if (_nackMode == kNackHybrid && (_lowRttNackThresholdMs >= 0 &&
        static_cast<int>(_rttMs) > _lowRttNackThresholdMs))
    {
        // from here we count on FEC
        rttMult = 0.0f;
    }
    estimate += static_cast<WebRtc_UWord32>
                (_jitterEstimate.GetJitterEstimate(rttMult) + 0.5);
    return estimate;
}

void
VCMJitterBuffer::UpdateRtt(WebRtc_UWord32 rttMs)
{
    CriticalSectionScoped cs(_critSect);
    _rttMs = rttMs;
    _jitterEstimate.UpdateRtt(rttMs);
}

// wait for the first packet in the next frame to arrive
WebRtc_Word64
VCMJitterBuffer::GetNextTimeStamp(WebRtc_UWord32 maxWaitTimeMS,
                                  FrameType& incomingFrameType,
                                  WebRtc_Word64& renderTimeMs)
{
    if (!_running)
    {
        return -1;
    }

    _critSect->Enter();

    // Finding oldest frame ready for decoder, check sequence number and size
    CleanUpOldFrames();

    FrameList::iterator it = _frameList.begin();

    if (it == _frameList.end())
    {
        _packetEvent.Reset();
        _critSect->Leave();

        if (_packetEvent.Wait(maxWaitTimeMS) == kEventSignaled)
        {
            // are we closing down the Jitter buffer
            if (!_running)
            {
                return -1;
            }
            _critSect->Enter();

            CleanUpOldFrames();
            it = _frameList.begin();
        }
        else
        {
            _critSect->Enter();
        }
    }

    if (it == _frameList.end())
    {
        _critSect->Leave();
        return -1;
    }
    // we have a frame

    // return frame type
    // All layers are assumed to have the same type
    incomingFrameType = (*it)->FrameType();

    renderTimeMs = (*it)->RenderTimeMs();

    const WebRtc_UWord32 timestamp = (*it)->TimeStamp();

    _critSect->Leave();

    // return current time
    return timestamp;
}

// Answers the question:
// Will the packet sequence be complete if the next frame is grabbed for
// decoding right now? That is, have we lost a frame between the last decoded
// frame and the next, or is the next
// frame missing one or more packets?
bool
VCMJitterBuffer::CompleteSequenceWithNextFrame()
{
    CriticalSectionScoped cs(_critSect);
    // Finding oldest frame ready for decoder, check sequence number and size
    CleanUpOldFrames();

    if (_frameList.empty())
      return true;

    VCMFrameBuffer* oldestFrame = _frameList.front();
    if (_frameList.size() <= 1 &&
        oldestFrame->GetState() != kStateComplete)
    {
        // Frame not ready to be decoded.
        return true;
    }
    if (!oldestFrame->Complete())
    {
        return false;
    }

    // See if we have lost a frame before this one.
    if (_lastDecodedState.init())
    {
        // Following start, reset or flush -> check for key frame.
        if (oldestFrame->FrameType() != kVideoFrameKey)
        {
            return false;
        }
    }
    else if (oldestFrame->GetLowSeqNum() == -1)
    {
        return false;
    }
    else if (!_lastDecodedState.ContinuousFrame(oldestFrame))
    {
        return false;
    }
    return true;
}

// Returns immediately
VCMEncodedFrame*
VCMJitterBuffer::GetFrameForDecoding()
{
    CriticalSectionScoped cs(_critSect);
    if (!_running)
    {
        return NULL;
    }

    if (WaitForNack())
    {
        return GetFrameForDecodingNACK();
    }

    CleanUpOldFrames();

    if (_frameList.empty()) {
      return NULL;
    }

    VCMFrameBuffer* oldestFrame = _frameList.front();
    if (_frameList.size() <= 1 &&
        oldestFrame->GetState() != kStateComplete) {
      return NULL;
    }

    // Incomplete frame pulled out from jitter buffer,
    // update the jitter estimate with what we currently know.
    // This frame shouldn't have been retransmitted, but if we recently
    // turned off NACK this might still happen.
    const bool retransmitted = (oldestFrame->GetNackCount() > 0);
    if (retransmitted)
    {
        _jitterEstimate.FrameNacked();
    }
    else if (oldestFrame->Length() > 0)
    {
        // Ignore retransmitted and empty frames.
        // Update with the previous incomplete frame first
        if (_waitingForCompletion.latestPacketTime >= 0)
        {
            UpdateJitterAndDelayEstimates(_waitingForCompletion, true);
        }
        // Then wait for this one to get complete
        _waitingForCompletion.frameSize = oldestFrame->Length();
        _waitingForCompletion.latestPacketTime =
                              oldestFrame->LatestPacketTimeMs();
        _waitingForCompletion.timestamp = oldestFrame->TimeStamp();
    }
    _frameList.erase(_frameList.begin());

    // Look for previous frame loss
    VerifyAndSetPreviousFrameLost(*oldestFrame);

    // The state must be changed to decoding before cleaning up zero sized
    // frames to avoid empty frames being cleaned up and then given to the
    // decoder.
    // Set as decoding. Propagates the missingFrame bit.
    oldestFrame->SetState(kStateDecoding);

    CleanUpOldFrames();

    if (oldestFrame->FrameType() == kVideoFrameKey)
    {
        _waitingForKeyFrame = false;
    }

    _packetsNotDecodable += oldestFrame->NotDecodablePackets();

    // We have a frame - update decoded state with frame info.
    _lastDecodedState.SetState(oldestFrame);

    return oldestFrame;
}

VCMEncodedFrame*
VCMJitterBuffer::GetFrameForDecodingNACK()
{
    // when we use NACK we don't release non complete frames
    // unless we have a complete key frame.
    // In hybrid mode, we may release decodable frames (non-complete)

    // Clean up old frames and empty frames
    CleanUpOldFrames();

    // First look for a complete _continuous_ frame.
    // When waiting for nack, wait for a key frame, if a continuous frame cannot
    // be determined (i.e. initial decoding state).
    if (_lastDecodedState.init()) {
      _waitingForKeyFrame = true;
    }

    // Allow for a decodable frame when in Hybrid mode.
    bool enableDecodable = _nackMode == kNackHybrid ? true : false;
    FrameList::iterator it = FindOldestCompleteContinuousFrame(enableDecodable);
    if (it == _frameList.end())
    {
        // If we didn't find one we're good with a complete key/decodable frame.
        it = find_if(_frameList.begin(), _frameList.end(),
                     CompleteDecodableKeyFrameCriteria());
        if (it == _frameList.end())
        {
            return NULL;
        }
    }
    VCMFrameBuffer* oldestFrame = *it;
    // Update jitter estimate
    const bool retransmitted = (oldestFrame->GetNackCount() > 0);
    if (retransmitted)
    {
        _jitterEstimate.FrameNacked();
    }
    else if (oldestFrame->Length() > 0)
    {
        // Ignore retransmitted and empty frames.
        UpdateJitterAndDelayEstimates(*oldestFrame, false);
    }
    it = _frameList.erase(it);

    // Look for previous frame loss
    VerifyAndSetPreviousFrameLost(*oldestFrame);

    // The state must be changed to decoding before cleaning up zero sized
    // frames to avoid empty frames being cleaned up and then given to the
    // decoder.
    oldestFrame->SetState(kStateDecoding);

    // Clean up old frames and empty frames
    CleanUpOldFrames();

    if (oldestFrame->FrameType() == kVideoFrameKey)
    {
        _waitingForKeyFrame = false;
    }

    // We have a frame - update decoded state with frame info.
    _lastDecodedState.SetState(oldestFrame);

    return oldestFrame;
}

// Must be called under the critical section _critSect. Should never be called
// with retransmitted frames, they must be filtered out before this function is
// called.
void
VCMJitterBuffer::UpdateJitterAndDelayEstimates(VCMJitterSample& sample,
                                               bool incompleteFrame)
{
    if (sample.latestPacketTime == -1)
    {
        return;
    }
    if (incompleteFrame)
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId), "Received incomplete frame "
                     "timestamp %u frame size %u at time %u",
                     sample.timestamp, sample.frameSize,
                     MaskWord64ToUWord32(sample.latestPacketTime));
    }
    else
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId), "Received complete frame "
                     "timestamp %u frame size %u at time %u",
                     sample.timestamp, sample.frameSize,
                     MaskWord64ToUWord32(sample.latestPacketTime));
    }
    UpdateJitterAndDelayEstimates(sample.latestPacketTime,
                                  sample.timestamp,
                                  sample.frameSize,
                                  incompleteFrame);
}

// Must be called under the critical section _critSect. Should never be
// called with retransmitted frames, they must be filtered out before this
// function is called.
void
VCMJitterBuffer::UpdateJitterAndDelayEstimates(VCMFrameBuffer& frame,
                                               bool incompleteFrame)
{
    if (frame.LatestPacketTimeMs() == -1)
    {
        return;
    }
    // No retransmitted frames should be a part of the jitter
    // estimate.
    if (incompleteFrame)
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                   "Received incomplete frame timestamp %u frame type %d "
                   "frame size %u at time %u, jitter estimate was %u",
                   frame.TimeStamp(), frame.FrameType(), frame.Length(),
                   MaskWord64ToUWord32(frame.LatestPacketTimeMs()),
                   GetEstimatedJitterMsInternal());
    }
    else
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),"Received complete frame "
                     "timestamp %u frame type %d frame size %u at time %u, "
                     "jitter estimate was %u",
                     frame.TimeStamp(), frame.FrameType(), frame.Length(),
                     MaskWord64ToUWord32(frame.LatestPacketTimeMs()),
                     GetEstimatedJitterMsInternal());
    }
    UpdateJitterAndDelayEstimates(frame.LatestPacketTimeMs(), frame.TimeStamp(),
                                  frame.Length(), incompleteFrame);
}

// Must be called under the critical section _critSect. Should never be called
// with retransmitted frames, they must be filtered out before this function
// is called.
void
VCMJitterBuffer::UpdateJitterAndDelayEstimates(WebRtc_Word64 latestPacketTimeMs,
                                               WebRtc_UWord32 timestamp,
                                               WebRtc_UWord32 frameSize,
                                               bool incompleteFrame)
{
    if (latestPacketTimeMs == -1)
    {
        return;
    }
    WebRtc_Word64 frameDelay;
    // Calculate the delay estimate
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(_vcmId, _receiverId),
                 "Packet received and sent to jitter estimate with: "
                 "timestamp=%u wallClock=%u", timestamp,
                 MaskWord64ToUWord32(latestPacketTimeMs));
    bool notReordered = _delayEstimate.CalculateDelay(timestamp,
                                                      &frameDelay,
                                                      latestPacketTimeMs);
    // Filter out frames which have been reordered in time by the network
    if (notReordered)
    {
        // Update the jitter estimate with the new samples
        _jitterEstimate.UpdateEstimate(frameDelay, frameSize, incompleteFrame);
    }
}

WebRtc_UWord16*
VCMJitterBuffer::GetNackList(WebRtc_UWord16& nackSize,bool& listExtended)
{
    return CreateNackList(nackSize,listExtended);
}

// Assume called internally with critsect
WebRtc_Word32
VCMJitterBuffer::GetLowHighSequenceNumbers(WebRtc_Word32& lowSeqNum,
                                           WebRtc_Word32& highSeqNum) const
{
    // TODO (mikhal/stefan): refactor to use lastDecodedState
    WebRtc_Word32 i = 0;
    WebRtc_Word32 seqNum = -1;

    highSeqNum = -1;
    lowSeqNum = -1;
    if (!_lastDecodedState.init())
      lowSeqNum = _lastDecodedState.sequence_num();

    // find highest seq numbers
    for (i = 0; i < _maxNumberOfFrames; ++i)
    {
        seqNum = _frameBuffers[i]->GetHighSeqNum();

        // Ignore free / empty frames
        VCMFrameBufferStateEnum state = _frameBuffers[i]->GetState();

        if ((kStateFree != state) &&
            (kStateEmpty != state) &&
            (kStateDecoding != state) &&
             seqNum != -1)
        {
            bool wrap;
            highSeqNum = LatestSequenceNumber(seqNum, highSeqNum, &wrap);
        }
    } // for
    return 0;
}

WebRtc_UWord16*
VCMJitterBuffer::CreateNackList(WebRtc_UWord16& nackSize, bool& listExtended)
{
    // TODO (mikhal/stefan): Refactor to use lastDecodedState.
    CriticalSectionScoped cs(_critSect);
    int i = 0;
    WebRtc_Word32 lowSeqNum = -1;
    WebRtc_Word32 highSeqNum = -1;
    listExtended = false;

    // Don't create list, if we won't wait for it
    if (!WaitForNack())
    {
        nackSize = 0;
        return NULL;
    }

    // Find the lowest (last decoded) sequence number and
    // the highest (highest sequence number of the newest frame)
    // sequence number. The nack list is a subset of the range
    // between those two numbers.
    GetLowHighSequenceNumbers(lowSeqNum, highSeqNum);

    // write a list of all seq num we have
    if (lowSeqNum == -1 || highSeqNum == -1)
    {
        // This happens if we lose the first packet, nothing is popped
        if (highSeqNum == -1)
        {
            // we have not received any packets yet
            nackSize = 0;
        }
        else
        {
            // signal that we want a key frame request to be sent
            nackSize = 0xffff;
        }
        return NULL;
    }

    int numberOfSeqNum = 0;
    if (lowSeqNum > highSeqNum)
    {
        if (lowSeqNum - highSeqNum > 0x00ff)
        {
            // wrap
            numberOfSeqNum = (0xffff-lowSeqNum) + highSeqNum + 1;
        }
    }
    else
    {
        numberOfSeqNum = highSeqNum - lowSeqNum;
    }

    if (numberOfSeqNum > kNackHistoryLength)
    {
        // Nack list is too big, flush and try to restart.
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                     "Nack list too large, try to find a key frame and restart "
                     "from seq: %d. Lowest seq in jb %d", highSeqNum,lowSeqNum);

        // This nack size will trigger a key request...
        bool foundKeyFrame = false;

        while (numberOfSeqNum > kNackHistoryLength)
        {
            foundKeyFrame = RecycleFramesUntilKeyFrame();

            if (!foundKeyFrame)
            {
                break;
            }

            // Check if we still have too many packets in JB
            lowSeqNum = -1;
            highSeqNum = -1;
            GetLowHighSequenceNumbers(lowSeqNum, highSeqNum);

            if (highSeqNum == -1)
            {
                assert(lowSeqNum != -1); // This should never happen
                // We can't calculate the nack list length...
                return NULL;
            }

            numberOfSeqNum = 0;
            if (lowSeqNum > highSeqNum)
            {
                if (lowSeqNum - highSeqNum > 0x00ff)
                {
                    // wrap
                    numberOfSeqNum = (0xffff-lowSeqNum) + highSeqNum + 1;
                    highSeqNum=lowSeqNum;
                }
            }
            else
            {
                numberOfSeqNum = highSeqNum - lowSeqNum;
            }

        } // end while

        if (!foundKeyFrame)
        {
            // No key frame in JB.

            // Set the last decoded sequence number to current high.
            // This is to not get a large nack list again right away
            _lastDecodedState.SetSeqNum(static_cast<uint16_t>(highSeqNum));
            // Set to trigger key frame signal
            nackSize = 0xffff;
            listExtended = true;
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, -1,
                    "\tNo key frame found, request one. _lastDecodedSeqNum[0] "
                    "%d", _lastDecodedState.sequence_num());
        }
        else
        {
            // We have cleaned up the jb and found a key frame
            // The function itself has set last decoded seq.
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, -1,
                    "\tKey frame found. _lastDecodedSeqNum[0] %d",
                    _lastDecodedState.sequence_num());
            nackSize = 0;
        }

        return NULL;
    }

    WebRtc_UWord16 seqNumberIterator = (WebRtc_UWord16)(lowSeqNum + 1);
    for (i = 0; i < numberOfSeqNum; i++)
    {
        _NACKSeqNumInternal[i] = seqNumberIterator;
        seqNumberIterator++;
    }

    // now we have a list of all sequence numbers that could have been sent

    // zero out the ones we have received
    for (i = 0; i < _maxNumberOfFrames; i++)
    {
        // loop all created frames
        // We don't need to check if frame is decoding since lowSeqNum is based
        // on _lastDecodedSeqNum
        // Ignore free frames
        VCMFrameBufferStateEnum state = _frameBuffers[i]->GetState();

        if ((kStateFree != state) &&
            (kStateEmpty != state) &&
            (kStateDecoding != state))
        {
            // Reaching thus far means we are going to update the nack list
            // When in hybrid mode, we use the soft NACKing feature.
            if (_nackMode == kNackHybrid)
            {
                _frameBuffers[i]->BuildSoftNackList(_NACKSeqNumInternal,
                                                    numberOfSeqNum,
                                                    _rttMs);
            }
            else
            {
                // Used when the frame is being processed by the decoding thread
                // don't need to use that info in this loop.
                _frameBuffers[i]->BuildHardNackList(_NACKSeqNumInternal,
                                                    numberOfSeqNum);
            }
        }
    }

    // compress list
    int emptyIndex = -1;
    for (i = 0; i < numberOfSeqNum; i++)
    {
        if (_NACKSeqNumInternal[i] == -1 || _NACKSeqNumInternal[i] == -2 )
        {
            // this is empty
            if (emptyIndex == -1)
            {
                // no empty index before, remember this position
                emptyIndex = i;
            }
        }
        else
        {
            // this is not empty
            if (emptyIndex == -1)
            {
                // no empty index, continue
            }
            else
            {
                _NACKSeqNumInternal[emptyIndex] = _NACKSeqNumInternal[i];
                _NACKSeqNumInternal[i] = -1;
                emptyIndex++;
            }
        }
    } // for

    if (emptyIndex == -1)
    {
        // no empty
        nackSize = numberOfSeqNum;
    }
    else
    {
        nackSize = emptyIndex;
    }

    if (nackSize > _NACKSeqNumLength)
    {
        // Larger list: nack list was extended since the last call.
        listExtended = true;
    }

    for (WebRtc_UWord32 j = 0; j < nackSize; j++)
    {
        // Check if the list has been extended since it was last created. I.e,
        // new items have been added
        if (_NACKSeqNumLength > j && !listExtended)
        {
            WebRtc_UWord32 k = 0;
            for (k = j; k < _NACKSeqNumLength; k++)
            {
                // Found the item in the last list, i.e, no new items found yet.
                if (_NACKSeqNum[k] == (WebRtc_UWord16)_NACKSeqNumInternal[j])
                {
                   break;
                }
            }
            if (k == _NACKSeqNumLength) // New item not found in last list.
            {
                listExtended = true;
            }
        }
        else
        {
            listExtended = true;
        }
        _NACKSeqNum[j] = (WebRtc_UWord16)_NACKSeqNumInternal[j];
    }

    _NACKSeqNumLength = nackSize;

    return _NACKSeqNum;
}

// Release frame when done with decoding. Should never be used to release
// frames from within the jitter buffer.
void
VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame)
{
    CriticalSectionScoped cs(_critSect);
    VCMFrameBuffer* frameBuffer = static_cast<VCMFrameBuffer*>(frame);
    if (frameBuffer != NULL)
        frameBuffer->SetState(kStateFree);
}

WebRtc_Word64
VCMJitterBuffer::LastPacketTime(VCMEncodedFrame* frame,
                                bool& retransmitted) const
{
    CriticalSectionScoped cs(_critSect);
    retransmitted = (static_cast<VCMFrameBuffer*>(frame)->GetNackCount() > 0);
    return static_cast<VCMFrameBuffer*>(frame)->LatestPacketTimeMs();
}

WebRtc_Word64
VCMJitterBuffer::LastDecodedTimestamp() const
{
    CriticalSectionScoped cs(_critSect);
    return _lastDecodedState.time_stamp();
}

// Insert packet
// Takes crit sect, and inserts packet in frame buffer, possibly does logging
VCMFrameBufferEnum
VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
{
    CriticalSectionScoped cs(_critSect);
    WebRtc_Word64 nowMs = _clock->MillisecondTimestamp();
    VCMFrameBufferEnum bufferReturn = kSizeError;
    VCMFrameBufferEnum ret = kSizeError;
    VCMFrameBuffer* frame = static_cast<VCMFrameBuffer*>(buffer);

    // We are keeping track of the first seq num, the latest seq num and
    // the number of wraps to be able to calculate how many packets we expect.
    if (_firstPacket)
    {
        // Now it's time to start estimating jitter
        // reset the delay estimate.
        _delayEstimate.Reset(_clock->MillisecondTimestamp());
        _firstPacket = false;
    }

    // Empty packets may bias the jitter estimate (lacking size component),
    // therefore don't let empty packet trigger the following updates:
    if (packet.frameType != kFrameEmpty)
    {
        if (_waitingForCompletion.timestamp == packet.timestamp)
        {
            // This can get bad if we have a lot of duplicate packets,
            // we will then count some packet multiple times.
            _waitingForCompletion.frameSize += packet.sizeBytes;
            _waitingForCompletion.latestPacketTime = nowMs;
        }
        else if (_waitingForCompletion.latestPacketTime >= 0 &&
                 _waitingForCompletion.latestPacketTime + 2000 <= nowMs)
        {
            // A packet should never be more than two seconds late
            UpdateJitterAndDelayEstimates(_waitingForCompletion, true);
            _waitingForCompletion.latestPacketTime = -1;
            _waitingForCompletion.frameSize = 0;
            _waitingForCompletion.timestamp = 0;
        }
    }

    if (frame != NULL)
    {
        VCMFrameBufferStateEnum state = frame->GetState();
        _lastDecodedState.UpdateOldPacket(&packet);
        // Insert packet
        // Check for first packet
        // High sequence number will be -1 if neither an empty packet nor
        // a media packet has been inserted.
        bool first = (frame->GetHighSeqNum() == -1);
        // When in Hybrid mode, we allow for a decodable state
        // Note: Under current version, a decodable frame will never be
        // triggered, as the body of the function is empty.
        // TODO (mikhal): Update when decodable is enabled.
        bufferReturn = frame->InsertPacket(packet, nowMs,
                                           _nackMode == kNackHybrid,
                                           _rttMs);
        ret = bufferReturn;

        if (bufferReturn > 0)
        {
            _incomingBitCount += packet.sizeBytes << 3;

            // Has this packet been nacked or is it about to be nacked?
            if (IsPacketRetransmitted(packet))
            {
                frame->IncrementNackCount();
            }

            // Insert each frame once on the arrival of the first packet
            // belonging to that frame (media or empty)
            if (state == kStateEmpty && first)
            {
                ret = kFirstPacket;
                FrameList::reverse_iterator rit = std::find_if(
                    _frameList.rbegin(), _frameList.rend(),
                    FrameSmallerTimestamp(frame->TimeStamp()));
                _frameList.insert(rit.base(), frame);
            }
        }
    }
    switch(bufferReturn)
    {
    case kStateError:
    case kTimeStampError:
    case kSizeError:
        {
            if (frame != NULL)
            {
                // Will be released when it gets old.
                frame->Reset();
                frame->SetState(kStateEmpty);
            }
            break;
        }
    case kCompleteSession:
        {
            // Only update return value for a JB flush indicator.
            if (UpdateFrameState(frame) == kFlushIndicator)
              ret = kFlushIndicator;
            // Signal that we have a received packet
            _packetEvent.Set();
            break;
        }
    case kDecodableSession:
    case kIncomplete:
        {
          // Signal that we have a received packet
          _packetEvent.Set();
          break;
        }
    case kNoError:
    case kDuplicatePacket:
        {
            break;
        }
    default:
        {
            assert(false && "JitterBuffer::InsertPacket: Undefined value");
        }
    }
   return ret;
}

// Must be called from within _critSect
void
VCMJitterBuffer::UpdateOldJitterSample(const VCMPacket& packet)
{
    if (_waitingForCompletion.timestamp != packet.timestamp &&
        LatestTimestamp(_waitingForCompletion.timestamp, packet.timestamp,
                        NULL) == packet.timestamp)
    {
        // This is a newer frame than the one waiting for completion.
        _waitingForCompletion.frameSize = packet.sizeBytes;
        _waitingForCompletion.timestamp = packet.timestamp;
    }
    else
    {
        // This can get bad if we have a lot of duplicate packets,
        // we will then count some packet multiple times.
        _waitingForCompletion.frameSize += packet.sizeBytes;
        _jitterEstimate.UpdateMaxFrameSize(_waitingForCompletion.frameSize);
    }
}

// Must be called from within _critSect
bool
VCMJitterBuffer::IsPacketRetransmitted(const VCMPacket& packet) const
{
    if (_NACKSeqNumLength > 0)
    {
        for (WebRtc_UWord16 i = 0; i < _NACKSeqNumLength; i++)
        {
            if (packet.seqNum == _NACKSeqNum[i])
            {
                return true;
            }
        }
    }
    return false;
}

// Get nack status (enabled/disabled)
VCMNackMode
VCMJitterBuffer::GetNackMode() const
{
    CriticalSectionScoped cs(_critSect);
    return _nackMode;
}

// Set NACK mode
void
VCMJitterBuffer::SetNackMode(VCMNackMode mode,
                             int lowRttNackThresholdMs,
                             int highRttNackThresholdMs)
{
    CriticalSectionScoped cs(_critSect);
    _nackMode = mode;
    assert(lowRttNackThresholdMs >= -1 && highRttNackThresholdMs >= -1);
    assert(highRttNackThresholdMs == -1 ||
           lowRttNackThresholdMs <= highRttNackThresholdMs);
    assert(lowRttNackThresholdMs > -1 || highRttNackThresholdMs == -1);
    _lowRttNackThresholdMs = lowRttNackThresholdMs;
    _highRttNackThresholdMs = highRttNackThresholdMs;
    if (_nackMode == kNoNack)
    {
        _jitterEstimate.ResetNackCount();
    }
}

// Recycle oldest frames up to a key frame, used if JB is completely full
bool
VCMJitterBuffer::RecycleFramesUntilKeyFrame()
{
    // Remove up to oldest key frame
    while (_frameList.size() > 0)
    {
        // Throw at least one frame.
        _dropCount++;
        FrameList::iterator it = _frameList.begin();
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                     VCMId(_vcmId, _receiverId),
                     "Jitter buffer drop count:%d, lowSeq %d", _dropCount,
                     (*it)->GetLowSeqNum());
        RecycleFrame(*it);
        it = _frameList.erase(it);
        if (it != _frameList.end() && (*it)->FrameType() == kVideoFrameKey)
        {
            // Fake the lastDecodedState to match this key frame.
            _lastDecodedState.SetStateOneBack(*it);
            return true;
        }
    }
    _waitingForKeyFrame = true;
    _lastDecodedState.Reset(); // TODO (mikhal): no sync
    return false;
}

// Must be called under the critical section _critSect.
void VCMJitterBuffer::CleanUpOldFrames() {
  while (_frameList.size() > 0) {
    VCMFrameBuffer* oldestFrame = _frameList.front();
    bool nextFrameEmpty = (_lastDecodedState.ContinuousFrame(oldestFrame) &&
        oldestFrame->GetState() == kStateEmpty);
    if (_lastDecodedState.IsOldFrame(oldestFrame) ||
        (nextFrameEmpty && _frameList.size() > 1)) {
      ReleaseFrameInternal(_frameList.front());
      _frameList.erase(_frameList.begin());
    } else {
      break;
    }
  }
}

// Used in GetFrameForDecoding
void VCMJitterBuffer::VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame) {
  frame.MakeSessionDecodable();  // Make sure the session can be decoded.
  if (frame.FrameType() == kVideoFrameKey)
    return;

  if (!_lastDecodedState.ContinuousFrame(&frame))
    frame.SetPreviousFrameLoss();
}

bool
VCMJitterBuffer::WaitForNack()
{
     // NACK disabled -> can't wait
     if (_nackMode == kNoNack)
     {
         return false;
     }
     // NACK only -> always wait
     else if (_nackMode == kNackInfinite)
     {
         return true;
     }
     // else: hybrid mode, evaluate
     // RTT high, don't wait
     if (_highRttNackThresholdMs >= 0 &&
         _rttMs >= static_cast<unsigned int>(_highRttNackThresholdMs))
     {
         return false;
     }
     // Either NACK only or hybrid
     return true;
}

}  // namespace webrtc


text:
package pr07.interfaces;

public interface Machine {

    String getModel();
}


text:
@import UIKit;

typedef void(^JTSActionBlock)(void);

@interface JTSActionSheetItem : NSObject

@property (copy, nonatomic, readonly) NSString *title;
@property (copy, nonatomic, readonly) JTSActionBlock actionBlock;
@property (assign, nonatomic, readonly) BOOL destructive;

+ (instancetype)itemWithTitle:(NSString *)title
                       action:(JTSActionBlock)actionBlock
                isDestructive:(BOOL)isDestructive;

@end


text: Various Logo for OR-Tools


text:
import { Link } from 'react-router-dom';
import ListErrors from './ListErrors';
import React from 'react';
import { inject, observer } from 'mobx-react';

@inject('authStore')
@observer
export default class Register extends React.Component {

  componentWillUnmount() {
    this.props.authStore.reset();
  }

  handleUsernameChange = e => this.props.authStore.setUsername(e.target.value);
  handleEmailChange = e => this.props.authStore.setEmail(e.target.value);
  handlePasswordChange = e => this.props.authStore.setPassword(e.target.value);
  handleSubmitForm = (e) => {
    e.preventDefault();
    this.props.authStore.register()
      .then(() => this.props.history.replace('/'));
  };

  render() {
    const { values, errors, inProgress } = this.props.authStore;

    return (

Sign Up

                <Link to="login">
                  Have an account?
                </Link>

              <ListErrors errors={errors} />

              <form onSubmit={this.handleSubmitForm}>
                <fieldset>

                  <fieldset className="form-group">
                    <input
                      className="form-control form-control-lg"
                      type="text"
                      placeholder="Username"
                      value={values.username}
                      onChange={this.handleUsernameChange}
                    />
                  </fieldset>

                  <fieldset className="form-group">
                    <input
                      className="form-control form-control-lg"
                      type="email"
                      placeholder="Email"
                      value={values.email}
                      onChange={this.handleEmailChange}
                    />
                  </fieldset>

                  <fieldset className="form-group">
                    <input
                      className="form-control form-control-lg"
                      type="password"
                      placeholder="Password"
                      value={values.password}
                      onChange={this.handlePasswordChange}
                    />
                  </fieldset>

                  <button
                    className="btn btn-lg btn-primary pull-xs-right"
                    type="submit"
                    disabled={inProgress}
                  >
                    Sign in
                  </button>

                </fieldset>
              </form>

    );
  }
}


text:
package io.gatling.http.cache

import io.gatling.BaseSpec
import io.gatling.commons.util.DefaultClock
import io.gatling.core.CoreComponents
import io.gatling.core.EmptySession
import io.gatling.core.config.GatlingConfiguration
import io.gatling.core.session.Session
import io.gatling.http.client.{ Request, RequestBuilder }
import io.gatling.http.client.uri.Uri
import io.gatling.http.engine.HttpEngine
import io.gatling.http.engine.tx.HttpTx
import io.gatling.http.protocol.{ HttpProtocol, HttpProtocolDnsPart }
import io.gatling.http.request.{ HttpRequest, HttpRequestConfig }

import io.netty.handler.codec.http.{ DefaultHttpHeaders, HttpHeaderNames, HttpHeaderValues, HttpMethod }
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.when

class CacheSupportSpec extends BaseSpec with EmptySession {
  private val configuration = GatlingConfiguration.loadForTest()
  private val coreComponents = new CoreComponents(null, null, null, null, null, new DefaultClock, null, configuration)
  private val httpCaches = new HttpCaches(coreComponents)

  class CacheContext {
    def getResponseExpire(headers: Seq[(CharSequence, CharSequence)]): Option[Long] = {
      val httpHeaders = new DefaultHttpHeaders
      headers.foreach { case (headerName, headerValue) => httpHeaders.add(headerName, headerValue) }
      httpCaches.getResponseExpires(httpHeaders)
    }
  }

  "getResponseExpires()" should "correctly support Pragma header" in new CacheContext {
    getResponseExpire(List(HttpHeaderNames.PRAGMA -> HttpHeaderValues.NO_CACHE)) shouldBe None
  }

  it should "correctly support Cache-Control header" in new CacheContext {
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> "max-age=1")) shouldBe Symbol("defined")
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> "private, max-age=3600, must-revalidate")) shouldBe Symbol("defined")
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> "public, no-cache")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> "public, max-age=-1")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> "public, max-age=0")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.CACHE_CONTROL -> HttpHeaderValues.NO_STORE)) shouldBe None
  }

  it should "correctly support Expires header" in new CacheContext {
    getResponseExpire(List(HttpHeaderNames.EXPIRES -> "Sun, 16 Oct 2033 21:56:44 GMT")) shouldBe Symbol("defined")
  }

  it should "give priority to Cache-Control over Expires" in new CacheContext {
    getResponseExpire(
      List(HttpHeaderNames.EXPIRES -> "Tue, 19 Jan 2038 03:14:06 GMT", HttpHeaderNames.CACHE_CONTROL -> HttpHeaderValues.NO_STORE)
    ) shouldBe None
    getResponseExpire(List(HttpHeaderNames.EXPIRES -> "Tue, 19 Jan 2038 03:14:06 GMT", HttpHeaderNames.CACHE_CONTROL -> "max-age=-1")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.EXPIRES -> "Tue, 19 Jan 2038 03:14:06 GMT", HttpHeaderNames.CACHE_CONTROL -> "max-age=0")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.EXPIRES -> "Tue, 19 Jan 2038 03:14:06 GMT", HttpHeaderNames.CACHE_CONTROL -> "max-age=567")) shouldBe Symbol(
      "defined"
    )
  }

  it should "Pragma has priority over Cache-Control" in new CacheContext {
    getResponseExpire(List(HttpHeaderNames.PRAGMA -> HttpHeaderValues.NO_CACHE, HttpHeaderNames.CACHE_CONTROL -> "max-age=3600")) shouldBe None
    getResponseExpire(List(HttpHeaderNames.PRAGMA -> HttpHeaderValues.NO_CACHE, HttpHeaderNames.EXPIRES -> "3600")) shouldBe None
  }

  "extractExpiresValue()" should "supports Expires field format" in {
    httpCaches.extractExpiresValue("Thu, 01 Dec 1994 16:00:00 GMT") shouldBe Some(786297600000L)
    httpCaches.extractExpiresValue("Tue, 19 Jan 2038 03:14:06 GMT") shouldBe Some(2147483646000L)
  }

  it should "defaults to false if it's not Expires field format" in {
    httpCaches.extractExpiresValue("fail") shouldBe None
  }

  "extractMaxAgeValue()" should "tell if there is a 'max-age' control and gets its value if superior to zero" in {
    httpCaches.extractMaxAgeValue("public") shouldBe None
    httpCaches.extractMaxAgeValue("private, max-age=3600, must-revalidate") shouldBe Some(3600)
    httpCaches.extractMaxAgeValue("private, max-age=nicolas, must-revalidate") shouldBe None
    httpCaches.extractMaxAgeValue("private, max-age=0, must-revalidate") shouldBe Some(0)
    httpCaches.extractMaxAgeValue("max-age=-1") shouldBe Some(-1)
    httpCaches.extractMaxAgeValue("max-age=-123") shouldBe Some(-1)
    httpCaches.extractMaxAgeValue("max-age=5") shouldBe Some(5)
    httpCaches.extractMaxAgeValue("max-age=567") shouldBe Some(567)
  }

  class RedirectContext {
    var session: Session = emptySession

    def addRedirect(from: String, to: String): Unit = {
      val request = new RequestBuilder("request", HttpMethod.GET, Uri.create(from), null)
        .build()
      session = httpCaches.addRedirect(session, request, Uri.create(to))
    }
  }

  "redirect memoization" should "return transaction with no redirect cache" in new RedirectContext {
    val tx = txTo("http://example.com/", session, redirectCount = 0, cache = true)
    val actualTx = httpCaches.applyPermanentRedirect(tx)

    actualTx shouldBe tx
  }

  it should "return updated transaction with single redirect" in new RedirectContext {
    addRedirect("http://example.com/", "http://gatling.io/")

    val origTx = txTo("http://example.com/", session, redirectCount = 0, cache = true)
    val tx = httpCaches.applyPermanentRedirect(origTx)

    tx.request.clientRequest.getUri shouldBe Uri.create("http://gatling.io/")
    tx.redirectCount shouldBe 1
  }

  it should "return updated transaction with several redirects" in new RedirectContext {
    addRedirect("http://example.com/", "http://gatling.io/")
    addRedirect("http://gatling.io/", "http://gatling2.io/")
    addRedirect("http://gatling2.io/", "http://gatling3.io/")

    val origTx = txTo("http://example.com/", session, redirectCount = 0, cache = true)
    val tx = httpCaches.applyPermanentRedirect(origTx)

    tx.request.clientRequest.getUri shouldBe Uri.create("http://gatling3.io/")
    tx.redirectCount shouldBe 3
  }

  it should "return updated transaction with several redirects, with redirectCount preset" in new RedirectContext {
    addRedirect("http://example.com/", "http://gatling.io/")
    addRedirect("http://gatling.io/", "http://gatling2.io/")
    addRedirect("http://gatling2.io/", "http://gatling3.io/")

    // Redirect count is already 2
    val origTx = txTo("http://example.com/", session, 2, cache = true)
    val tx = httpCaches.applyPermanentRedirect(origTx)

    tx.request.clientRequest.getUri shouldBe Uri.create("http://gatling3.io/")
    // After 3 more redirects it is now equal to 5
    tx.redirectCount shouldBe 5
  }

  private def txTo(uri: String, session: Session, redirectCount: Int, cache: Boolean) = {
    val protocol = HttpProtocol(configuration)
    val request = mock[Request]
    val caches = mock[HttpCaches]

    when(request.getUri) thenReturn Uri.create(uri)
    when(request.getHeaders) thenReturn new DefaultHttpHeaders
    when(caches.setNameResolver(any[HttpProtocolDnsPart], any[HttpEngine])) thenReturn identity[Session] _

    HttpTx(
      session,
      request = HttpRequest(
        requestName = "mockHttpTx",
        clientRequest = request,
        requestConfig = HttpRequestConfig(
          checks = Nil,
          responseTransformer = None,
          throttled = false,
          silent = None,
          followRedirect = true,
          digests = Map.empty,
          storeBodyParts = false,
          defaultCharset = configuration.core.charset,
          httpProtocol = protocol,
          explicitResources = Nil
        )
      ),
      next = null,
      resourceTx = None,
      redirectCount = redirectCount
    )
  }
}


text:
@interface PDKTCollectionViewWaterfallLayout()
@property (nonatomic, assign) NSInteger itemCount;
@property (nonatomic, strong) NSMutableArray *columnHeights;
@property (nonatomic, strong) NSMutableArray *itemAttributes;
@property (nonatomic, strong) NSMutableArray *supplementaryViewsAttibutes;
@end

@implementation PDKTCollectionViewWaterfallLayout

#pragma mark - Accessors
- (void)setColumnCount:(NSUInteger)columnCount{
    if (_columnCount != columnCount) {
        _columnCount = columnCount;
        [self invalidateLayout];
    }
}

- (void)setSectionInset:(UIEdgeInsets)sectionInset{
    if (!UIEdgeInsetsEqualToEdgeInsets(_sectionInset, sectionInset)) {
        _sectionInset = sectionInset;
        [self invalidateLayout];
    }
}

#pragma mark - Init
- (void)commonInit{
    _columnCount = 2;
    _itemSpacing = 0.0;
    _sectionInset = UIEdgeInsetsZero;
    if (!_delegate && [self.collectionView.delegate conformsToProtocol:@protocol(PDKTCollectionViewWaterfallLayoutDelegate)]) {
        _delegate = (id<PDKTCollectionViewWaterfallLayoutDelegate>)self.collectionView.delegate;
    }
}
- (void)prepareLayout{
    [super prepareLayout];
    [self commonInit];
    self.itemCount=[self totalItemsCountInCollectionView];
    [self initGeometryInformationCollections];
    for (NSInteger section = 0; section<[[self collectionView]numberOfSections]; section++){
        [self calculateItemsGeometryInSection:section];
    }
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    NSMutableArray *attributes = [NSMutableArray arrayWithArray:[super layoutAttributesForElementsInRect:rect]];
    [self addVisibleItemAttributesToLayoutAttributes:attributes inRect:rect];
    [self addVisibleSupplementaryViewsAttributesToLayoutAttributes:attributes inRect:rect];
    [self addVisibleHeadersToLayoutAttributes:attributes fromVisibleSectionsWithoutHeader:[self visibleSectionsWithoutHeaderInAttributes:attributes]];
    [self updateStickedHeadersAttributesInLayoutAttributes:attributes];
    return attributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
    return self.itemAttributes[indexPath.section][indexPath.item];
}
- (void)addVisibleItemAttributesToLayoutAttributes:(NSMutableArray *)attributes inRect:(CGRect)rect{
    for (NSArray *itemAttributesArray in self.itemAttributes) {
        NSArray *filteredAttributes=[itemAttributesArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
            return CGRectIntersectsRect(rect, [evaluatedObject frame]);
        }]];
        [attributes addObjectsFromArray:filteredAttributes];
    }
}
- (void)addVisibleSupplementaryViewsAttributesToLayoutAttributes:(NSMutableArray *)attributes inRect:(CGRect)rect{
    for (NSDictionary *itemAttributesArray in self.supplementaryViewsAttibutes) {
        if (itemAttributesArray) {
            NSArray *filteredAttributes=[[itemAttributesArray allValues] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
                return CGRectIntersectsRect(rect, [evaluatedObject frame]);
            }]];
            [attributes addObjectsFromArray:filteredAttributes];
        }
    }
}
- (NSArray *)visibleSectionsWithoutHeaderInAttributes:(NSArray *)attributes{
    NSMutableArray *visibleSectionsWithoutHeader = [NSMutableArray array];
    for (UICollectionViewLayoutAttributes *itemAttributes in attributes) {
        if (![visibleSectionsWithoutHeader containsObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]]) {
            [visibleSectionsWithoutHeader addObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]];
        }
        if (itemAttributes.representedElementKind==UICollectionElementKindSectionHeader) {
            NSUInteger indexOfSectionObject=[visibleSectionsWithoutHeader indexOfObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]];
            if (indexOfSectionObject!=NSNotFound) {
                [visibleSectionsWithoutHeader removeObjectAtIndex:indexOfSectionObject];
            }
        }
    }
    return visibleSectionsWithoutHeader;
}
- (void)addVisibleHeadersToLayoutAttributes:(NSMutableArray *)attributes fromVisibleSectionsWithoutHeader:(NSArray *)visibleSectionsWithoutHeader{
    for (NSNumber *sectionNumber in visibleSectionsWithoutHeader) {
        if ([self shouldStickHeaderToTopInSection:[sectionNumber integerValue]]) {
            UICollectionViewLayoutAttributes *headerAttributes=[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:[sectionNumber integerValue]]];
            if (headerAttributes.frame.size.width>0 && headerAttributes.frame.size.height>0) {
                [attributes addObject:headerAttributes];
            }
        }
    }
}
- (void)updateStickedHeadersAttributesInLayoutAttributes:(NSMutableArray *)attributes{
    for (UICollectionViewLayoutAttributes *itemAttributes in attributes) {
        if (itemAttributes.representedElementKind==UICollectionElementKindSectionHeader) {
            UICollectionViewLayoutAttributes *headerAttributes = itemAttributes;
            if ([self shouldStickHeaderToTopInSection:headerAttributes.indexPath.section]) {
                CGRect frame = headerAttributes.frame;
                frame = [self correctStickedHeaderFrame:frame relativeToContentOffsetWithHeaderAttributes:headerAttributes];
                frame = [self correctStickedHeaderFrame:frame relativeToSameSectionFooterWithHeaderAttributes:headerAttributes];
                frame = [self correctStickedHeaderFrame:frame relativeToNextSectionHeaderWithHeaderAttributes:headerAttributes];
                frame = [self correctStickedHeaderFrame:frame relativeToBottomLimitInSameSectionWithHeaderAttributes:headerAttributes];
                headerAttributes.frame = frame;
            }
            headerAttributes.zIndex = 1024;
        }
    }
}

- (CGRect)correctStickedHeaderFrame:(CGRect)frame relativeToContentOffsetWithHeaderAttributes:(UICollectionViewLayoutAttributes *)headerAttributes{
    CGPoint contentOffset = self.collectionView.contentOffset;
    CGPoint originInCollectionView=CGPointMake(headerAttributes.frame.origin.x-contentOffset.x, headerAttributes.frame.origin.y-contentOffset.y);
    originInCollectionView.y-=self.collectionView.contentInset.top;
    if (originInCollectionView.y<0) {
        frame.origin.y+=(originInCollectionView.y*-1);
    }
    return frame;
}
- (CGRect)correctStickedHeaderFrame:(CGRect)frame relativeToSameSectionFooterWithHeaderAttributes:(UICollectionViewLayoutAttributes *)headerAttributes{
    UICollectionViewLayoutAttributes *sameSectionFooterAttributes=[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:headerAttributes.indexPath.section]];
    if (sameSectionFooterAttributes) {
        CGFloat maxY=sameSectionFooterAttributes.frame.origin.y;
        if (CGRectGetMaxY(frame)>=maxY) {
            frame.origin.y=maxY-frame.size.height;
        }
    }
    return frame;
}
- (CGRect)correctStickedHeaderFrame:(CGRect)frame relativeToNextSectionHeaderWithHeaderAttributes:(UICollectionViewLayoutAttributes *)headerAttributes{
    NSUInteger numberOfSections=[self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView];
    if (numberOfSections>headerAttributes.indexPath.section+1) {
        UICollectionViewLayoutAttributes *nextHeaderAttributes=[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:headerAttributes.indexPath.section+1]];
        CGFloat maxY=nextHeaderAttributes.frame.origin.y;
        if (CGRectGetMaxY(frame)>=maxY) {
            frame.origin.y=maxY-frame.size.height;
        }
    }
    return frame;
}
- (CGRect)correctStickedHeaderFrame:(CGRect)frame relativeToBottomLimitInSameSectionWithHeaderAttributes:(UICollectionViewLayoutAttributes *)headerAttributes{
    NSUInteger longestColumnIndex = [self longestColumnIndexInSection:headerAttributes.indexPath.section];
    CGFloat maxYOffsetInSection=[(self.columnHeights[headerAttributes.indexPath.section][longestColumnIndex]) floatValue] + [self insetsForSection:headerAttributes.indexPath.section].bottom;
    if (CGRectGetMaxY(frame)>=maxYOffsetInSection) {
        frame.origin.y=maxYOffsetInSection-frame.size.height;
    }
    return frame;
}

- (NSUInteger)totalItemsCountInCollectionView{
    NSUInteger itemsCount = 0;
    for (NSInteger i=0; i<[self.collectionView numberOfSections];i++) {
        itemsCount+=[[self collectionView] numberOfItemsInSection:i];
    }
    return itemsCount;
}

- (void)initGeometryInformationCollections{
    self.itemAttributes = [NSMutableArray array];
    self.columnHeights = [NSMutableArray array];
    self.supplementaryViewsAttibutes = [NSMutableArray array];
}

- (void)calculateItemsGeometryInSection:(NSUInteger)section{
    NSUInteger columnCountInSection = [self.delegate collectionView:self.collectionView layout:self numberOfColumnsInSection:section];
    if(columnCountInSection){
        UIEdgeInsets sectionInset=[self insetsForSection:section];
        CGFloat itemSpacing=[self itemSpacingInSection:section];
        CGFloat itemWidth=floorf((self.collectionView.bounds.size.width-sectionInset.left-sectionInset.right-((columnCountInSection-1)*itemSpacing))/(CGFloat)columnCountInSection);
        NSInteger sectionItemsCount = [[self collectionView] numberOfItemsInSection:section];

        self.itemAttributes[section] = [NSMutableArray arrayWithCapacity:sectionItemsCount];
        self.columnHeights[section] = [NSMutableArray arrayWithCapacity:columnCountInSection];
        for (NSInteger idx = 0; idx < columnCountInSection; idx++) {
            [self.columnHeights[section] addObject:@(0)];
        }
        self.supplementaryViewsAttibutes[section] = [NSMutableDictionary dictionary];

        [self loadSectionHeaderAttributesInSection:section];

        if (sectionItemsCount == 0) {
            for (NSInteger idx = 0; idx < columnCountInSection; idx++) {
                CGFloat yOffset = [self verticalOffsetForItemAtColumn:idx section:section sectionInset:sectionInset itemSpacing:itemSpacing];
                self.columnHeights[section][idx] = @(yOffset);
            }
        } else {
            for (NSInteger idx = 0; idx < sectionItemsCount; idx++) {
                NSIndexPath *indexPath = [NSIndexPath indexPathForItem:idx inSection:section];
                CGFloat itemHeight=[self itemHeightWithItemWidth:itemWidth AtIndexPath:indexPath];
                NSUInteger columnIndex = [self shortestColumnIndexInSection:section];
                CGFloat xOffset=sectionInset.left + ((itemWidth + itemSpacing) * columnIndex);
                CGFloat yOffset = [self verticalOffsetForItemAtColumn:columnIndex section:section sectionInset:sectionInset itemSpacing:itemSpacing];
                UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
                attributes.frame = CGRectMake(xOffset, yOffset, itemWidth, itemHeight);
                attributes.zIndex = 1;
                [self.itemAttributes[section] addObject:attributes];
                self.columnHeights[section][columnIndex] = @(yOffset + itemHeight);
            }
        }

        [self loadSectionFooterAttributesInSection:section];
    }
}
- (void)loadSectionHeaderAttributesInSection:(NSUInteger)section{
    CGFloat yOffset=0.0;
    if(section>0){
        NSUInteger longestColumnIndex = [self longestColumnIndexInSection:section-1];
        yOffset=[(self.columnHeights[section-1][longestColumnIndex]) floatValue] + [self insetsForSection:section-1].bottom;
        NSMutableDictionary *previousSectionSupplementaryViewsAttibutes=self.supplementaryViewsAttibutes[section-1];
        UICollectionViewLayoutAttributes *footerAttributes=[previousSectionSupplementaryViewsAttibutes objectForKey:UICollectionElementKindSectionFooter];
        if (footerAttributes) {
            yOffset+=footerAttributes.frame.size.height;
        }
    }
    CGSize sectionHeaderSize=[self headerSizeInSection:section kind:UICollectionElementKindSectionHeader];
    if (!CGSizeEqualToSize(sectionHeaderSize, CGSizeZero)) {
        UICollectionViewLayoutAttributes *headerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
        headerAttributes.frame = CGRectMake(0, yOffset, sectionHeaderSize.width, sectionHeaderSize.height);
        headerAttributes.zIndex = 1;
        NSMutableDictionary *sectionSupplementaryViewsAttributes=self.supplementaryViewsAttibutes[section];
        [sectionSupplementaryViewsAttributes setObject:headerAttributes forKey:UICollectionElementKindSectionHeader];
    }
}
- (CGSize)sectionHeaderSizeInSection:(NSUInteger)section{
    CGSize headerSize=CGSizeZero;
    NSMutableDictionary *sectionSupplementaryViewsAttributes=self.supplementaryViewsAttibutes[section];
    if ([sectionSupplementaryViewsAttributes objectForKey:UICollectionElementKindSectionHeader]) {
        UICollectionViewLayoutAttributes *headerAttributes=[sectionSupplementaryViewsAttributes objectForKey:UICollectionElementKindSectionHeader];
        headerSize=headerAttributes.frame.size;
    }
    return headerSize;
}
- (void)loadSectionFooterAttributesInSection:(NSUInteger)section{
    CGSize sectionFooterSize=[self headerSizeInSection:section kind:UICollectionElementKindSectionFooter];
    if (!CGSizeEqualToSize(sectionFooterSize, CGSizeZero)) {
        NSUInteger columnIndex = [self longestColumnIndexInSection:section];
        CGFloat height = [self.columnHeights[section][columnIndex] floatValue];
        UICollectionViewLayoutAttributes *footerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
        footerAttributes.frame = CGRectMake(0, height+[self insetsForSection:section].bottom, sectionFooterSize.width, sectionFooterSize.height);
        footerAttributes.zIndex = 1;
        NSMutableDictionary *sectionSupplementaryViewsAttributes=self.supplementaryViewsAttibutes[section];
        [sectionSupplementaryViewsAttributes setObject:footerAttributes forKey:UICollectionElementKindSectionFooter];
    }
}
- (CGFloat)itemHeightWithItemWidth:(CGFloat)itemWidth AtIndexPath:(NSIndexPath *)indexPath{
    CGFloat itemHeight=0.0;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:aspectRatioForIndexPath:)]) {
        itemHeight=floorf(itemWidth/[self.delegate collectionView:self.collectionView layout:self aspectRatioForIndexPath:indexPath]);
    }else if([self.delegate respondsToSelector:@selector(collectionView:layout:heightItemAtIndexPath:)]){
        itemHeight=floorf([self.delegate collectionView:self.collectionView layout:self heightItemAtIndexPath:indexPath]);
    }else if ([self.delegate respondsToSelector:@selector(collectionView:layout:heightItemAtIndexPath:withWidth:)]){
        itemHeight=floorf([self.delegate collectionView:self.collectionView layout:self heightItemAtIndexPath:indexPath withWidth:itemWidth]);
    }else{
        NSAssert(NO, @"PDKTCollectionViewWaterfallLayout : At least one of collectionView:layout:heightItemAtIndexPath: or collectionView:layout:aspectRatioForIndexPath: methods must be implemented by the layout delegate");
    }
    return itemHeight;
}
- (CGFloat)verticalOffsetForItemAtColumn:(NSUInteger)columnIndex section:(NSUInteger)section sectionInset:(UIEdgeInsets)sectionInset itemSpacing:(CGFloat)itemSpacing{
    CGFloat initialOffsetY=0.0;
    CGFloat yOffset=[(self.columnHeights[section][columnIndex]) floatValue];
    if (yOffset==initialOffsetY) {
        if(section>0){
            NSUInteger longestColumnIndex = [self longestColumnIndexInSection:section-1];
            yOffset=[(self.columnHeights[section-1][longestColumnIndex]) floatValue] + [self insetsForSection:section-1].bottom;
            NSMutableDictionary *previousSectionSupplementaryViewsAttibutes=self.supplementaryViewsAttibutes[section-1];
            UICollectionViewLayoutAttributes *footerAttributes=[previousSectionSupplementaryViewsAttibutes objectForKey:UICollectionElementKindSectionFooter];
            if (footerAttributes) {
                yOffset+=footerAttributes.frame.size.height;
            }
        }
        yOffset+=sectionInset.top;
        yOffset+=[self sectionHeaderSizeInSection:section].height;
        return yOffset;
    }
    yOffset+=itemSpacing;
    return yOffset;
}

- (CGSize)collectionViewContentSize
{
    if (self.itemCount == 0) {
        return CGSizeZero;
    }
    UIEdgeInsets sectionInset=[self insetsForSection:self.columnHeights.count-1];
    CGSize contentSize = self.collectionView.frame.size;
    NSUInteger columnIndex = [self longestColumnIndexInSection:self.columnHeights.count-1];
    CGFloat height = [self.columnHeights[self.columnHeights.count-1][columnIndex] floatValue];
    contentSize.height = height + sectionInset.bottom;
    NSDictionary *supplementaryViewsAttributes=self.supplementaryViewsAttibutes[self.columnHeights.count-1];
    UICollectionViewLayoutAttributes *footerAttributes=[supplementaryViewsAttributes objectForKey:UICollectionElementKindSectionFooter];
    if (footerAttributes) {
        contentSize.height+=footerAttributes.frame.size.height;
    }
    return contentSize;
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return !(CGSizeEqualToSize(newBounds.size, self.collectionView.frame.size));
}

#pragma mark - Private Methods
- (CGSize)headerSizeInSection:(NSUInteger)section kind:(NSString *)kind{
    CGSize size=CGSizeZero;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:sizeForSupplementaryViewInSection:kind:)]) {
        size=[self.delegate collectionView:self.collectionView layout:self sizeForSupplementaryViewInSection:section kind:kind];
    }
    return size;
}
- (UIEdgeInsets)insetsForSection:(NSUInteger)section{
    UIEdgeInsets insets;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:sectionInsetForSection:)]) {
        insets=[self.delegate collectionView:self.collectionView layout:self sectionInsetForSection:section];
    }else{
        insets=self.sectionInset;
    }
    return insets;
}
- (CGFloat)itemSpacingInSection:(NSUInteger)section{
    CGFloat itemSpacing;
    if([self.delegate respondsToSelector:@selector(collectionView:layout:itemSpacingInSection:)]){
        itemSpacing=[self.delegate collectionView:self.collectionView layout:self itemSpacingInSection:section];
    }else{
        itemSpacing=self.itemSpacing;
    }
    return itemSpacing;
}

- (NSUInteger)shortestColumnIndexInSection:(NSUInteger)section
{
    NSUInteger index = 0;
    CGFloat shortestHeight = MAXFLOAT;
    if (self.columnHeights.count>section) {
        NSUInteger idx=0;
        for (id obj in self.columnHeights[section]) {
            CGFloat height = [obj floatValue];
            if (height < shortestHeight) {
                shortestHeight = height;
                index = idx;
            }
            idx++;
        }
    }
    return index;
}

- (NSUInteger)longestColumnIndexInSection:(NSUInteger)section
{
    NSUInteger index = 0;
    CGFloat longestHeight = 0;
    if (self.columnHeights.count>section) {
        NSUInteger idx=0;
        for (id obj in self.columnHeights[section]) {
            CGFloat height = [obj floatValue];
            if (height > longestHeight) {
                longestHeight = height;
                index = idx;
            }
            idx++;
        }
    }
    return index;
}

#pragma mark - Supplementary Views
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    NSDictionary *supplementaryViewsAttibutes=self.supplementaryViewsAttibutes[indexPath.section];
    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
        return [supplementaryViewsAttibutes objectForKey:UICollectionElementKindSectionHeader];
    }else if([kind isEqualToString:UICollectionElementKindSectionFooter]){
        return [supplementaryViewsAttibutes objectForKey:UICollectionElementKindSectionFooter];
    }else{
        NSAssert(NO, @"Invalid supplementary view kind (%@)",kind);
        return nil;
    }
}

#pragma mark - Sticky Header

- (BOOL)shouldStickHeaderToTopInSection:(NSUInteger)section{
    if ([self.collectionView.delegate respondsToSelector:@selector(shouldStickHeaderToTopInSection:)]) {
        return [((id<PDKTCollectionViewWaterfallLayoutDelegate>)self.collectionView.delegate) shouldStickHeaderToTopInSection:section];
    }
    return NO;
}

@end


text:
title: Server extensions and choices
weight: 4
---

## Server extensions
Zipkin server bundles extension for span collection and storage. By default spans can be collected over http, Kafka or RabbitMQ transports and stored in-memory or in MySQL, Cassandra or Elasticsearch.

The following modules add storage or transport extensions to the default server build.
Please refer to their individual documentation for setup and configuration guides.

### OpenZipkin supported

The following extensions are supported by the OpenZipkin team and are hosted at
the [OpenZipkin GitHub](https://github.com/openzipkin/) group. You can reach out to
the team on [Zipkin Gitter](https://gitter.im/openzipkin/zipkin/) chat.

| Type | Module | Related product | Other notes |
|:-----|:--------|:----------------|:------------|{% for extension in site.data.extensions %}
| {{ extension.type }} | {{ extension.module }} | {{extension.product}} | {{ extension.notes }} |{% endfor %}
{: .wide-table}

### Community supported

| Type | Module | Related product | Other notes |
|:-----|:--------|:----------------|:------------|{% for extension in site.data.community_extensions %}
| {{ extension.type }} | {{ extension.module }} | {{extension.product}} | {{ extension.notes }} |{% endfor %}
{: .wide-table}

## Alternative servers

The OpenZipkin team publish apis, data formats, and shared libraries that allow alternate backends to process the
same data sent to the default Zipkin server.

### Community supported

Listed below are alternative backends that accept Zipkin format. Some use the same code as Zipkin on the same endpoints while others are on alternative endpoints or partially support features. In any case, the following aim to allow existing zipkin clients to use backends the OpenZipkin team does not support. Hence, direct questions to their respective communities.

 - [Apache SkyWalking](https://skywalking.apache.org/)
   - When [zipkin trace component]([https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/backend/backend-receivers.md](https://skywalking.apache.org/docs/main/next/en/setup/backend/zipkin-trace/)) is enabled, Skywalking exposes the same HTTP POST endpoints and Kafka topic Zipkin does
     - http port 9411 accepts `/api/v1/spans` (thrift, json) and `/api/v2/spans` (json, proto) POST requests.
     - Kafka `zipkin` topic, and `zipkin` group ID accepts v2 spans encoded as a thrift/json/proto list per message.
     - this extension uses the same encoding library and same endpoints as Zipkin does.
 - [Jaeger](https://github.com/jaegertracing/jaeger)
   - When `COLLECTOR_ZIPKIN_HTTP_PORT=9411` is set, Jaeger exposes a partial implementation of Zipkin's HTTP POST endpoints
     - http port 9411 accepts `/api/v1/spans` (thrift, json) and `/api/v2/spans` (json, proto) POST requests.
   - When `SPAN_STORAGE_TYPE=kafka` and `zipkin-thrift`, Jaeger reads Zipkin v1 thrift encoded span messages from a Kafka topic.
     - Note: The above is a [deprecated practice](https://github.com/openzipkin/zipkin/tree/master/zipkin-collector/kafka#legacy-encoding) in Zipkin. Most instrumentation bundle multiple spans per message in v2 format.
 - [Pitchfork](https://github.com/HotelsDotCom/pitchfork)
   - Pitchfork exposes the same HTTP POST endpoints Zipkin does
     - http port 9411 accepts `/api/v1/spans` (thrift, json) and `/api/v2/spans` (json, proto) POST requests.

Did we miss a server extension or alternative? Please open a pull-request to
[openzipkin.github.io](https://github.com/openzipkin/openzipkin.github.io).