diff --git a/biotracker/Interfaces/IObject.cpp b/biotracker/Interfaces/IObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f339496b7828d755360600b093e08f4302cc4f1
--- /dev/null
+++ b/biotracker/Interfaces/IObject.cpp
@@ -0,0 +1,6 @@
+#include "IObject.h"
+
+IObject::IObject() :
+    IModel(0) {
+
+}
diff --git a/biotracker/Interfaces/IObject.h b/biotracker/Interfaces/IObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..c87bbc55153ec5f4c3a6f620010276ee164cb7b3
--- /dev/null
+++ b/biotracker/Interfaces/IObject.h
@@ -0,0 +1,17 @@
+#ifndef IOBJECT_H
+#define IOBJECT_H
+
+#include "Interfaces/imodel.h"
+
+#include <cereal/cereal.hpp>
+#include <cereal/access.hpp>
+
+#include "biotracker/util/platform.h"
+
+class IObject : public IModel {
+    Q_OBJECT
+  public:
+    IObject();
+};
+
+#endif // IOBJECT_H
diff --git a/biotracker/src/serialization/BioTracker3TrackedObject.cpp b/biotracker/src/serialization/BioTracker3TrackedObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dc851406f74e4504c37ec83ff4f7693fb16773bf
--- /dev/null
+++ b/biotracker/src/serialization/BioTracker3TrackedObject.cpp
@@ -0,0 +1,56 @@
+#include "biotracker/serialization/BioTracker3TrackedObject.h"
+
+
+
+#include <cassert>
+
+
+BioTracker3TrackedObject::BioTracker3TrackedObject(size_t id) :
+    _id(id),
+    m_maximumFrameNumber(0) {
+}
+
+BioTracker3TrackedObject::BioTracker3TrackedObject() {}
+
+void BioTracker3TrackedObject::add(const size_t framenumber,
+                                   std::shared_ptr<IObject> object) {
+    _objectsByFrame[framenumber] = object;
+    if (framenumber > m_maximumFrameNumber) {
+        m_maximumFrameNumber = framenumber;
+    }
+}
+
+void BioTracker3TrackedObject::push_back(std::shared_ptr<IObject> object) {
+    // get last idx with entry
+    const size_t lastIdx = _objectsByFrame.rbegin() == _objectsByFrame.rend() ?
+                           0 : _objectsByFrame.rbegin()->first;
+    // add object with next idx
+    _objectsByFrame.insert({lastIdx + 1, object});
+}
+
+size_t BioTracker3TrackedObject::count(const size_t framenumber) const {
+    return _objectsByFrame.count(framenumber);
+}
+
+std::shared_ptr<IObject> BioTracker3TrackedObject::get(const size_t framenumber)
+const {
+    assert(_objectsByFrame.count(framenumber));
+    return _objectsByFrame.at(framenumber);
+}
+
+std::shared_ptr<IObject> BioTracker3TrackedObject::top() const {
+    assert(!_objectsByFrame.empty());
+    return _objectsByFrame.rbegin()->second;
+}
+
+boost::optional<size_t> BioTracker3TrackedObject::getLastFrameNumber() const {
+    if (_objectsByFrame.empty()) {
+        return boost::optional<size_t>();
+    } else {
+        return _objectsByFrame.rbegin()->first;
+    }
+}
+
+size_t BioTracker3TrackedObject::maximumFrameNumber() const {
+    return m_maximumFrameNumber;
+}
diff --git a/biotracker/src/serialization/BioTracker3TrackedObject.h b/biotracker/src/serialization/BioTracker3TrackedObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2c20a1cecb1f60b8ace0fd58846a85c802efd31
--- /dev/null
+++ b/biotracker/src/serialization/BioTracker3TrackedObject.h
@@ -0,0 +1,11 @@
+#ifndef BIOTRACKER3TRACKEDOBJECT_H
+#define BIOTRACKER3TRACKEDOBJECT_H
+
+
+class BioTracker3TrackedObject
+{
+public:
+    BioTracker3TrackedObject();
+};
+
+#endif // BIOTRACKER3TRACKEDOBJECT_H
\ No newline at end of file