diff --git a/tools/cooja/java/se/sics/cooja/util/ArrayQueue.java b/tools/cooja/java/se/sics/cooja/util/ArrayQueue.java
new file mode 100644
index 000000000..e18a1be29
--- /dev/null
+++ b/tools/cooja/java/se/sics/cooja/util/ArrayQueue.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2010, BotBox AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ArrayQueue.java,v 1.1 2010/09/09 19:51:53 nifi Exp $
+ */
+
+package se.sics.cooja.util;
+
+import java.util.AbstractList;
+import java.util.RandomAccess;
+
+/**
+ * The ArrayQueue class implements a simple queue using a rotating, resizable
+ * array. Permits all elements, including null.
+ *
+ * The usage is basically the same as for ArrayList but this implementation
+ * is optimized for adding last and removing first element while the ArrayList
+ * shifts the data when removing first element.
+ *
+ *
+ * Note that this implementation is not synchronized and if an ArrayQueue
+ * instance is accessed by several threads concurrently, and at least one
+ * thread modifies the queue, it must be synchronized externally.
+ *
+ *
+ * @author Joakim Eriksson (joakime@sics.se)
+ * @author Niclas Finne (nfi@sics.se)
+ */
+public class ArrayQueue extends AbstractList implements RandomAccess, Cloneable, java.io.Serializable {
+
+ private static final long serialVersionUID = 5791745982858131414L;
+
+ private transient E[] queueData;
+ private transient int first = 0;
+ private transient int last = 0;
+ private int size = 0;
+
+ public ArrayQueue() {
+ this(16);
+ }
+
+ public ArrayQueue(int initialCapacity) {
+ if (initialCapacity < 0) {
+ throw new IllegalArgumentException("illegal capacity: " +
+ initialCapacity);
+ }
+ queueData = allocate(initialCapacity);
+ }
+
+ @SuppressWarnings("unchecked")
+ private E[] allocate(int size) {
+ return (E[]) new Object[size];
+ }
+
+ public void ensureCapacity(int minCapacity) {
+ int capacity = queueData.length;
+ if (capacity < minCapacity) {
+// int newCapacity = (capacity * 3) / 2 + 1;
+ int newCapacity = capacity * 2;
+ set(newCapacity < minCapacity ? minCapacity : newCapacity);
+ }
+ modCount++;
+ }
+
+ /**
+ * Copies all data in the queue to a new data array of the specified
+ * size (MUST be large enough) and replaces the old data array.
+ */
+ private void set(int newCapacity) {
+ E[] newData = allocate(newCapacity);
+ copy(newData);
+ // The data is always in the beginning after allocating new data array
+ first = 0;
+ last = size;
+ queueData = newData;
+ }
+
+ /**
+ * Copies all data in the queue to the new data array (must be large enough!)
+ */
+ private void copy(Object[] newData) {
+ if (first < last) {
+ // No wrap ([...1,2,3,4...])
+ System.arraycopy(queueData, first, newData, 0, size);
+ } else if (size > 0) {
+ // Wrapped queue ([4,5,6,......,1,2,3])
+ int firstSize = queueData.length - first;
+ // At least one element must exist since size > 0
+ System.arraycopy(queueData, first, newData, 0, firstSize);
+ System.arraycopy(queueData, 0, newData, firstSize, last);
+ } else {
+ // Empty queue i.e. do nothing
+ }
+ }
+
+ public void trimToSize() {
+ if (size < queueData.length) {
+ // Make sure only the needed space is occupied
+ set(size);
+ modCount++;
+ }
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ public boolean contains(Object element) {
+ return indexOf(element) >= 0;
+ }
+
+ public int indexOf(Object element) {
+ return indexOf(element, 0);
+ }
+
+ public int indexOf(Object element, int index) {
+ if ((index < 0) || (index >= size)) {
+ return -1;
+ }
+
+ final int capacity = queueData.length;
+ if (element == null) {
+ for(; index < size; index++) {
+ if (queueData[(first + index) % capacity] == null) {
+ return index;
+ }
+ }
+
+ } else {
+ for(; index < size; index++) {
+ if (element.equals(queueData[(first + index) % capacity])) {
+ return index;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public int lastIndexOf(Object element) {
+ final int capacity = queueData.length;
+ if (element == null) {
+ for(int index = size - 1; index >= 0; index--) {
+ if (queueData[(first + index) % capacity] == null) {
+ return index;
+ }
+ }
+
+ } else {
+ for(int index = size - 1; index >= 0; index--) {
+ if (element.equals(queueData[(first + index) % capacity])) {
+ return index;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public E get(int index) {
+ // getPos() will ensure that the index is valid
+ return queueData[getPos(index)];
+ }
+
+ public E set(int index, E element) {
+ int pos = getPos(index);
+ E oldValue = queueData[pos];
+ queueData[pos] = element;
+ return oldValue;
+ }
+
+ public void add(int index, E element) {
+ // Make sure there is space for the new element.
+ ensureCapacity(size + 1);
+ if (index == size) {
+ // Add to the end of the queue
+ queueData[last] = element;
+ last = (last + 1) % queueData.length;
+ size++;
+ } else {
+ // This will make sure the index is valid (0 <= index < size)
+ index = getPos(index);
+
+ if (index == first) {
+ // Add to the beginning of the queue
+ if (first > 0) {
+ first--;
+ } else {
+ // first == 0 => move first to the end of the data array
+ first = queueData.length - 1;
+ }
+ index = first;
+ } else if (index < last) {
+ // Non wrapped queue or index is in the lower part of the data array
+ System.arraycopy(queueData, index, queueData, index + 1, last - index);
+ last = (last + 1) % queueData.length;
+ } else {
+ // Wrapped queue (index in the end of the data array)
+ // first > 0 because last < first (there is at least one free position)
+ System.arraycopy(queueData, first, queueData, first - 1,
+ index - first);
+ index--;
+ first--;
+ }
+ queueData[index] = element;
+ size++;
+ }
+ }
+
+ public E remove(int index) {
+ E value;
+ // This method also checks that the index is valid
+ index = getPos(index);
+
+ value = queueData[index];
+ if (index == first) {
+ // Remove first element. The most common case for a queue.
+ queueData[first] = null;
+ first = (first + 1) % queueData.length;
+
+ } else if (index < last) {
+ // Non wrapped queue or index is in the lower part of the data array.
+ last--;
+ if (index < last) {
+ // An element in the middle is removed
+ System.arraycopy(queueData, index + 1, queueData, index, last - index);
+ }
+ queueData[last] = null;
+
+ } else if ((last == 0) && (index == queueData.length - 1)) {
+ // Minor optimization: no elements at the beginning of the data
+ // array and the removed index is last in the data array.
+ queueData[index] = null;
+ last = queueData.length - 1;
+
+ } else {
+ // Wrapped queue (index in the end of the data array)
+ System.arraycopy(queueData, first, queueData, first + 1, index - first);
+ queueData[first++] = null;
+ }
+ size--;
+ modCount++;
+ return value;
+ }
+
+ public boolean remove(Object element) {
+ int index = indexOf(element);
+ if (index >= 0) {
+ remove(index);
+ return true;
+ }
+ return false;
+ }
+
+ public void clear() {
+ final int capacity = queueData.length;
+ for (int i = 0; i < size; i++) {
+ queueData[(first + i) % capacity] = null;
+ }
+ first = last = size = 0;
+ modCount++;
+ }
+
+ /**
+ * Returns a shallow copy of this queue (the elements themselves are not
+ * copied).
+ */
+ @SuppressWarnings("unchecked")
+ public ArrayQueue clone() {
+ try {
+ ArrayQueue v = (ArrayQueue) super.clone();
+ // The set method will always create a new array which gives the
+ // cloned queue its own copy of the data array.
+ v.set(v.size);
+ v.modCount = 0;
+ return v;
+ } catch (CloneNotSupportedException e) {
+ // Should never happen
+ throw new InternalError();
+ }
+ }
+
+ public Object[] toArray() {
+ Object[] array = new Object[size];
+ copy(array);
+ return array;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T[] toArray(T[] array) {
+ if (array.length < size) {
+ array = (T[]) java.lang.reflect
+ .Array.newInstance(array.getClass().getComponentType(), size);
+ }
+ copy(array);
+ if (array.length > size) {
+ array[size] = null;
+ }
+ return array;
+ }
+
+ private int getPos(int index) {
+ if ((index >= 0) && (index < size)) {
+ return (first + index) % queueData.length;
+ }
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getClass().getName()).append('[')
+ .append(first).append(',').append(last)
+ .append(',').append(size)
+ .append(",[");
+ if (queueData.length < 32) {
+ for (int i = 0, n = queueData.length; i < n; i++) {
+ if (i > 0) sb.append(',');
+ sb.append(queueData[i]);
+ }
+ } else {
+ sb.append("...");
+ }
+ sb.append("]]");
+ return sb.toString();
+ }
+
+ // -------------------------------------------------------------------
+ // Serialization
+ // -------------------------------------------------------------------
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException
+ {
+ int queueLen = queueData.length;
+ out.defaultWriteObject();
+ out.writeInt(queueLen);
+ for (int i = 0, index = first; i < size; i++) {
+ out.writeObject(queueData[index]);
+ index = (index + 1) % queueLen;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ queueData = (E[]) new Object[in.readInt()];
+ for (int i = 0; i < size; i++) {
+ queueData[i] = (E) in.readObject();
+ }
+ first = 0;
+ last = size;
+ }
+
+} // ArrayQueue