local Queue = {}
function Queue:Enqueue(element)
  local insertIndex = self.last + 1
  self.last = insertIndex
  self[insertIndex] = element
  self.count = self.count + 1
end
function Queue:EnqueueFront(element)
  local insertIndex = self.first - 1
  self[insertIndex] = element
  self.first = insertIndex
  self.count = self.count + 1
end
function Queue:Dequeue()
  assert(not (self.first > self.last))
  local removedElement = self[self.first]
  self[self.first] = nil
  self.first = self.first + 1
  self.count = self.count - 1
  return removedElement
end
function Queue:Peek()
  return self[self.first]
end
function Queue:Last()
  return self[self.last]
end
function Queue.New()
  local newTable = {
    first = 0,
    last = -1,
    count = 0
  }
  local mt = {__index = Queue}
  setmetatable(newTable, mt)
  return newTable
end
function Queue:GetCount()
  return self.count
end
function Queue:IsEmpty()
  return self.last == self.first - 1
end
function Queue:Clear()
  while not self:IsEmpty() do
    self:Dequeue()
  end
end
return {Queue = Queue}
