diff --git a/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java b/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java
new file mode 100644
index 00000000..7d503b2e
--- /dev/null
+++ b/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java
@@ -0,0 +1,143 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.shared;
+
+@SuppressWarnings({"unused", "UnusedReturnValue"})
+public class SizedStack {
+
+ private int maxSize;
+ private T[] data;
+ private int size;
+ private int head;
+
+ public SizedStack(int size) {
+ this.maxSize = size;
+ //noinspection unchecked
+ this.data = (T[]) new Object[this.maxSize];
+ this.head = 0;
+ this.size = 0;
+ }
+
+ public T push(final T element) {
+ this.data[this.head] = element;
+ this.increaseHead();
+ this.increaseSize();
+ return element;
+ }
+
+ public T pop() {
+ this.decreaseHead();
+ this.decreaseSize();
+ final T result = this.data[this.head];
+ this.data[this.head] = null;
+ return result;
+ }
+
+ public T peek() {
+ return this.data[this.head];
+ }
+
+ public boolean empty() {
+ return this.size == 0;
+ }
+
+ protected boolean canEqual(final Object other) {
+ return other instanceof SizedStack;
+ }
+
+ private void increaseHead() {
+ this.head++;
+ while (this.head > this.maxSize - 1) {
+ this.head -= this.maxSize;
+ }
+ }
+
+ private void decreaseHead() {
+ this.head--;
+ while (this.head < 0) {
+ this.head += this.maxSize;
+ }
+ }
+
+ private void increaseSize() {
+ if (this.size < this.maxSize) {
+ this.size++;
+ }
+ }
+
+ private void decreaseSize() {
+ if (this.size > 0) {
+ this.size--;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 59;
+ int result = 1;
+ result = result * PRIME + this.maxSize;
+ result = result * PRIME + this.toString().hashCode();
+ result = result * PRIME + this.size;
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof SizedStack)) {
+ return false;
+ }
+ final SizedStack> other = (SizedStack>) o;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (this.maxSize != other.maxSize) {
+ return false;
+ }
+ if (this.size != other.size) {
+ return false;
+ }
+ if (!this.data.getClass().equals(other.data.getClass())) {
+ return false;
+ }
+ return this.toString().equals(other.toString());
+ }
+
+ public int getMaxSize() {
+ return maxSize;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder result = new StringBuilder("[");
+ for (int i = 0; i < this.size - 1; i++) {
+ result.append(this.data[(this.head - i - 1 < 0) ? (this.head - i - 1 + this.maxSize) : (this.head - i - 1)]).append(",");
+ }
+ result.append(this.data[(this.head - this.size < 0) ? (this.head - this.size + this.maxSize) : (this.head - this.size)]);
+ result.append("]");
+ return result.toString();
+ }
+}