diff --git a/.gitignore b/.gitignore
index a326e396ed35e9edee85b322f8fb4b9ea8fda3d5..77c6695cb968bd971748e1b08b89ec41adc9b09d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@ build/
 cmake-build-debug/
 cmake-build-debug-coverage/
 .idea/
+.cache/
 imgui.ini
diff --git a/demo/main.cpp b/demo/main.cpp
index 3aaa99b9288314fa327232faa562edc11ce4172a..f02bb32726d3533b206d7abfa78a63cb71baa4f1 100644
--- a/demo/main.cpp
+++ b/demo/main.cpp
@@ -12,7 +12,6 @@
 #include <fggl/math/ecs.hpp>
 
 #include <fggl/data/procedural.hpp>
-#include <fggl/ecs/ecs.hpp>
 #include <fggl/debug/debug.h>
 #include <fggl/data/storage.hpp>
 
@@ -55,7 +54,7 @@ enum camera_type { cam_free, cam_arcball };
 camera_type cam_mode = cam_free;
 
 //TODO proper input system
-void process_camera(fggl::gfx::Window& window, fggl::ecs2::World& ecs, fggl::gfx::Input& input, fggl::ecs::entity_t cam) {
+void process_camera(fggl::gfx::Window& window, fggl::ecs2::World& ecs, fggl::gfx::Input& input) {
 
 	if ( glfwGetKey(window.handle(), GLFW_KEY_F2) == GLFW_PRESS ) {
 		cam_mode = cam_free; 
@@ -132,12 +131,19 @@ constexpr float ROT_SPEED = 0.05f;
 constexpr float PAN_SPEED = 0.05f;
 constexpr glm::mat4 MAT_IDENTITY(1.0f);
 
-void process_freecam(fggl::gfx::Window& window, fggl::ecs::ECS& ecs, fggl::gfx::Input& input, fggl::ecs::entity_t cam) {
+void process_freecam(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) {
+	CameraHacks* hacks = (CameraHacks*)( it.ctx() );
+	const fggl::gfx::Window& window = hacks->window;
+	const fggl::gfx::Input& input = hacks->input;
+
+	auto& camTransform = t[0];
+	auto& camComp = c[0];
+
 	float rotationValue = 0.0f;
 	glm::vec3 translation(0.0f);
 
 	// calulate rotation (user input)
-	if ( glfwGetKey(window.handle(), GLFW_KEY_Q) == GLFW_PRESS ) {
+/*	if ( glfwGetKey(window.handle(), GLFW_KEY_Q) == GLFW_PRESS ) {
 		rotationValue = ROT_SPEED; 
 	} else if ( glfwGetKey(window.handle(), GLFW_KEY_E) == GLFW_PRESS ) {
 		rotationValue = -ROT_SPEED;
@@ -158,14 +164,10 @@ void process_freecam(fggl::gfx::Window& window, fggl::ecs::ECS& ecs, fggl::gfx::
 
 	if ( glfwGetKey(window.handle(), GLFW_KEY_A) == GLFW_PRESS ) {
 		translation -= fggl::math::FORWARD;
-	}
-
-	// apply rotation/movement
-	auto camTransform = ecs.getComponent<fggl::math::Transform>(cam);
-	auto camComp = ecs.getComponent<fggl::gfx::Camera>(cam);
+	}*/
 
-	glm::vec4 position( camTransform->origin(), 1.0f );
-	glm::vec4 pivot( camComp->target, 1.0f );
+	glm::vec4 position( camTransform.origin(), 1.0f );
+	glm::vec4 pivot( camComp.target, 1.0f );
 
 	// apply movement
 	if ( translation != glm::vec3(0.0f) ) {
@@ -186,8 +188,8 @@ void process_freecam(fggl::gfx::Window& window, fggl::ecs::ECS& ecs, fggl::gfx::
 		position = ( rotation * ( position - pivot ) ) + pivot;
 	}
 
-	camTransform->origin( position );
-	camComp->target = pivot;
+	camTransform.origin( position );
+	camComp.target = pivot;
 }
 
 void loadShader(fggl::gfx::ShaderCache& cache, const char* name, bool hasGeom) {
diff --git a/fggl/CMakeLists.txt b/fggl/CMakeLists.txt
index ffc795c92f2e3ae72fba3db93edb3f6e3fc8493c..4bea6138e7769bdadf705c7b45e5dc2f2b682b03 100644
--- a/fggl/CMakeLists.txt
+++ b/fggl/CMakeLists.txt
@@ -1,7 +1,6 @@
 configure_file(FgglConfig.h.in FgglConfig.h)
 
 add_library(fggl fggl.cpp
-	ecs/ecs.cpp
 	data/model.cpp
 	data/procedural.cpp
 )
diff --git a/fggl/ecs/component.hpp b/fggl/ecs/component.hpp
deleted file mode 100644
index b84fbe859be57aaff22476d961b0b65d2f0572e8..0000000000000000000000000000000000000000
--- a/fggl/ecs/component.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef FGGL_ECS_COMPONENT_H
-#define FGGL_ECS_COMPONENT_H
-
-#include "utility.hpp"
-
-#include <new>
-#include <utility>
-
-#include <vector>
-#include <unordered_map>
-
-namespace fggl::ecs {
-
-	class ComponentBase {
-		public:
-			using data_t = unsigned char;
-			virtual ~ComponentBase() {};
-
-			virtual void destroy(data_t* data) const = 0;
-			virtual void move(data_t* src, data_t* dest) const = 0;
-			virtual void construct(data_t* data) const = 0;
-
-			virtual std::size_t size() const = 0;
-	};
-
-	template<class C>
-	class Component : public ComponentBase {
-		public:
-			virtual void destroy(data_t* data) const override {
-				C* location = std::launder(reinterpret_cast<C*>(data));
-				location->~C();
-			}
-
-			virtual void construct(unsigned char* data) const override {
-//				new (&data[0]) C();
-			}
-
-			virtual void move(data_t* src, data_t* dest) const override {
-				new (&dest[0]) C(std::move(*reinterpret_cast<C*>(src)));
-			}
-
-			virtual std::size_t size() const {
-				return sizeof(C);
-			}
-
-			static component_type_t typeID() {
-				return TypeIdGenerator<ComponentBase>::GetNewID<C>();
-			}
-	};
-
-}
-
-#endif
diff --git a/fggl/ecs/ecs.cpp b/fggl/ecs/ecs.cpp
deleted file mode 100644
index d986991b68ce89775f36fb95647b068c5edaabd1..0000000000000000000000000000000000000000
--- a/fggl/ecs/ecs.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "ecs.hpp"
-
-#include <iostream>
-
-using namespace fggl::ecs;
-
-Archetype::Archetype(const archToken_t& token ) : type(token) {
-	for ( archToken_t::size_type i = 0; i < token.size(); ++i ) {
-		data.push_back( new unsigned char[default_cap] );
-		dataSizes.push_back( default_cap );
-	}
-}
-
-ECS::ECS() : m_entityIDCounter(1) {}
-
-ECS::~ECS() {
-	for( Archetype* arch : m_archetypes ) {
-		for ( std::size_t i=0; i < arch->type.size(); ++i ) {
-			const ComponentBase* const comp = m_componentMap[arch->type[i]];
-			const std::size_t& size = comp->size();
-
-			for ( std::size_t e=0; e<arch->entities.size(); ++e ) {
-				comp->destroy(&arch->data[i][e*size]);
-			}
-			delete[] arch->data[i];
-		}
-		delete arch;
-	}
-
-	for( componentmap_t::value_type& p : m_componentMap )
-		delete p.second;
-}
-
-entity_t ECS::getNewID() {
-	return m_entityIDCounter++;
-}
-
-entity_t ECS::createEntity( ) {
-	auto eid = getNewID();
-
-	Record dummy;
-	dummy.archetype = nullptr;
-	dummy.index = 0;
-	m_entityArchtypes[ eid ] = dummy;
-
-	return eid;
-}
-
-Archetype* ECS::getArchetype(const archToken_t& id) {
-	for ( auto* arch : m_archetypes ) {
-		if ( arch->type == id ) {
-			return arch;
-		}
-	}
-
-	// didn't exist, need to make one
-	Archetype* arch = new Archetype(id);
-	m_archetypes.push_back( arch );
-
-	return arch;
-}
diff --git a/fggl/ecs/ecs.hpp b/fggl/ecs/ecs.hpp
deleted file mode 100644
index e62b6836bd46a38264915f159714ec08cacae18e..0000000000000000000000000000000000000000
--- a/fggl/ecs/ecs.hpp
+++ /dev/null
@@ -1,287 +0,0 @@
-#ifndef FGGL_ECS_H
-#define FGGL_ECS_H
-
-#include "utility.hpp"
-#include "component.hpp"
-
-#include <iostream>
-#include <algorithm>
-#include <cassert>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
-namespace fggl::ecs {
-	using archToken_t = std::vector<component_type_t>;
-
-	struct Archetype {
-		constexpr static unsigned int default_cap = 0;
-		const archToken_t type;
-		std::vector<ComponentBase::data_t*> data;
-		std::vector<std::size_t> dataSizes;
-		std::vector<entity_t> entities;
-
-		Archetype(const archToken_t& type_a);
-
-		inline archToken_t create( const component_type_t cid ) const {
-			assert( !contains(cid) );
-
-			// create the new type
-			auto newType = type;
-			newType.push_back( cid );
-			std::sort( newType.begin(), newType.end() );
-			return newType;
-		}
-
-		inline bool contains( const component_type_t cid ) const {
-			return ( std::find( type.begin(), type.end(), cid ) != type.end() );
-		}
-	};
-
-	class ECS {
-		struct Record {
-			Archetype* archetype;
-			std::size_t index;
-		};
-		using componentmap_t = std::unordered_map<component_type_t, ComponentBase*>;
-		using entitymap_t = std::unordered_map<entity_t, Record>;
-		using archetype_t = std::vector<Archetype*>;
-
-		public:
-			ECS();
-			~ECS();
-
-			entity_t getNewID();
-			entity_t createEntity();
-			void removeEntity(const entity_t eid);
-
-			template<class C>
-			void registerComponent() {
-				component_type_t type = Component<C>::typeID();
-				if ( m_componentMap.find( type ) != m_componentMap.end() )
-					return;
-				m_componentMap.emplace( type, new Component<C> );
-			}
-
-			template<class C>
-			bool isComponentRegistered() {
-				component_type_t type = Component<C>::typeID();
-				return ( m_componentMap.find(type) != m_componentMap.end() );
-			}
-
-			template<class C, typename... Args>
-			C* addComponent(const entity_t& id, Args&&... args) {
-				component_type_t type = Component<C>::typeID();
-				assert( isComponentRegistered<C>() );
-
-				Record& record = m_entityArchtypes[id];
-				Archetype* oldArch = record.archetype;
-				C* newComp = nullptr;
-				Archetype* newArch = nullptr;
-
-				if ( !oldArch ) {
-					archToken_t newID(1, type);
-					const ComponentBase* const newCompType = m_componentMap[ type ];
-
-					// fetch type
-					newArch = getArchetype( newID );
-					assert( newArch->type.size() == 1 );
-
-					// calculate if we have enouph space to allocate
-					std::size_t emplacementPos = ensureCapacity( newArch, 0, newCompType );
-					newComp = new (&newArch->data[0][emplacementPos])C(std::forward<Args>(args)...);
-				} else {
-					// check if the arch contains the component
-					if ( oldArch->contains(type) ) {
-						return nullptr;
-					}
-
-					// create a new archetype with the component
-					auto newID = oldArch->create( type );
-					newArch = getArchetype( newID );
-
-					// relocate the old data to the new archetype
-					for ( std::size_t j=0; j < newID.size(); ++j ){
-						const component_type_t compType = newID[j];
-						const ComponentBase* const comp = m_componentMap.at(compType);
-
-
-						// TODO this seems a little suspect - surely we could allocate all blocks at once?
-						// if per component the arrays could become out of sync...
-						int newOffset = ensureCapacity(newArch, j, comp);
-						int oldIdx = getComponentIdx(oldArch, compType);
-
-						if ( oldIdx != -1 ) {
-							assert( oldArch->contains(compType) );
-							const std::size_t compSize = comp->size();
-							const std::size_t oldOffset = record.index * compSize;
-
-							comp->move( &oldArch->data[oldIdx][oldOffset],
-								    &newArch->data[j][newOffset] );
-							comp->destroy( &oldArch->data[oldIdx][oldOffset] );
-						} else {
-							assert( !oldArch->contains(compType) );
-							newComp = new (&newArch->data[j][newOffset])
-									C(std::forward<Args>(args)...);
-						}
-					}
-
-					// ensure the old archetype is still contigious
-					const int lastEnt = oldArch->entities.size() - 1;
-					if ( lastEnt != record.index )  {
-						for ( std::size_t i=0;  i < oldArch->type.size(); ++i ) {
-							const component_type_t typeID = oldArch->type[i];
-							const ComponentBase* const comp = m_componentMap[typeID];
-							const std::size_t& compSize = comp->size();
-
-							// shift the empty record to the end of the list
-							std::size_t slotOffset = record.index * compSize;
-							std::size_t lastOffset = lastEnt * compSize;
-
-							// if we're not the last entity, swap
-							if ( slotOffset != lastOffset ) {
-								comp->move( &oldArch->data[i][lastOffset],
-									    &oldArch->data[i][slotOffset] );
-								comp->destroy( &oldArch->data[i][lastOffset] );
-							}
-						}
-
-						// fix the position
-						oldArch->entities[ record.index ] = oldArch->entities[ lastEnt ];
-					}
-					oldArch->entities.pop_back();
-				}
-
-				// register the new data with the new archetype
-				newArch->entities.push_back( id );
-				record.index = newArch->entities.size() - 1;
-				record.archetype = newArch;
-				return newComp;
-			}
-
-			template<class C>
-			void removeComponent(const entity_t& entityId);
-
-			template<class C>
-			bool hasComponent(const entity_t& entityId) const {
-				const component_type_t componentID = Component<C>::typeID();
-				const auto* arch = m_entityArchtypes.at(entityId).archetype;
-				if ( arch == nullptr ) {
-					return false;
-				}
-				return ( std::find( arch->type.begin(), arch->type.end(), componentID) !=
-						arch->type.end() );
-			}
-
-			template<class C>
-			C* getComponent(const entity_t& entityId) {
-				assert( hasComponent<C>( entityId ) );
-				const auto type = Component<C>::typeID();
-
-				const ComponentBase* const newComp = m_componentMap[type];
-				const auto record = m_entityArchtypes.at(entityId);
-				const auto* arch = record.archetype;
-
-				// JWR: linear search... seems a little suspect, they're ordered after all
-				for ( std::size_t i=0; i < arch->type.size(); ++i ) {
-					if ( arch->type[i] == type ) {
-						return reinterpret_cast<C*>(& (arch->data[i][ record.index * newComp->size() ]) );
-					}
-				}
-
-				return nullptr;
-			}
-
-			template<class C>
-			const C* getComponent(const entity_t& entityId) const {
-                assert( hasComponent<C>( entityId ) );
-                const auto type = Component<C>::typeID();
-
-                const ComponentBase* const newComp = m_componentMap.at(type);
-                const auto record = m_entityArchtypes.at(entityId);
-                const auto* arch = record.archetype;
-
-                // JWR: linear search... seems a little suspect, they're ordered after all
-                for ( std::size_t i=0; i < arch->type.size(); ++i ) {
-                    if ( arch->type[i] == type ) {
-                        return reinterpret_cast<C*>(& (arch->data[i][ record.index * newComp->size() ]) );
-                    }
-                }
-
-                return nullptr;
-			}
-
-			template<class... Cs>
-			std::vector<entity_t> getEntityWith() const {
-				// construct the key
-				archToken_t key;
-				(key.push_back( Component<Cs>::typeID() ), ...);
-
-				// entities
-				std::vector<entity_t> entities;
-				for ( Archetype* arch : m_archetypes ) {
-					if ( std::includes( arch->type.begin(), arch->type.end(), key.begin(), key.end() ) ) {
-						if( !arch->entities.empty() ) {
-							entities.insert( entities.begin(), arch->entities.begin(), arch->entities.end() );
-						}
-					}
-				}
-
-				return entities;
-			}
-			
-		private:
-			entitymap_t m_entityArchtypes;
-			archetype_t m_archetypes;
-			entity_t m_entityIDCounter;
-			componentmap_t m_componentMap;
-			Archetype* getArchetype(const archToken_t& id);
-
-			inline std::string arch2str(Archetype* arch) {
-				std::string str;
-				for ( const auto& type : arch->type ) {
-					str += std::to_string( type );
-				}
-				return str;
-			}
-
-			inline std::size_t ensureCapacity(Archetype* arch, const int idx, const ComponentBase* const comp) {
-				const std::size_t& compSize = comp->size();
-				std::size_t currSize = arch->entities.size() * compSize;
-				std::size_t newSize = currSize + compSize;
-
-				std::size_t cap = arch->dataSizes[idx];
-
-				if ( newSize > arch->dataSizes[idx] ) {
-					arch->dataSizes[idx] *= 2;
-					arch->dataSizes[idx] += compSize;
-
-					// copy data over
-					unsigned char* newData = new unsigned char[arch->dataSizes[idx]];
-					for ( std::size_t e=0; e<arch->entities.size(); ++e ) {
-						const int offset = e * compSize;
-						comp->move( &arch->data[idx][offset], &newData[offset] );
-						comp->destroy( &arch->data[idx][offset] );
-					}
-
-					// free the old data and swap the pointers
-					delete[] arch->data[idx];
-					arch->data[idx] = newData;
-				}
-
-				return currSize;
-			}
-
-			inline int getComponentIdx(const Archetype* arch, const component_type_t goal) {
-				// JWR could do binary search for speedup
-				for ( std::size_t i=0; i < arch->type.size(); ++i ) {
-					if ( arch->type[i] == goal ) return i;
-				}
-				return -1;
-			}
-
-	};
-
-}
-
-#endif
diff --git a/fggl/ecs/utility.hpp b/fggl/ecs/utility.hpp
deleted file mode 100644
index 323074eded41677beae91209d01336d5b136b96c..0000000000000000000000000000000000000000
--- a/fggl/ecs/utility.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef FGGL_ECS_UTILITY_H
-#define FGGL_ECS_UTILITY_H
-
-#include <cstdint>
-
-namespace fggl::ecs {
-
-	using IDType = std::uint32_t;
-	using entity_t = IDType;
-	using component_type_t = IDType;
-
-	constexpr IDType NULL_ENTITY = 0;
-
-	template<class T>
-	class TypeIdGenerator {
-		private:
-			static IDType m_count;
-		public:
-			template<class U>
-			static const IDType GetNewID() {
-				static const IDType idCounter = m_count++;
-				return idCounter;
-			}
-	};
-	template<class T> IDType TypeIdGenerator<T>::m_count = 0;
-}
-
-#endif
diff --git a/fggl/gfx/renderer.cpp b/fggl/gfx/renderer.cpp
index d288dd30460730f1ccd721440fbf5e2b44b690d5..4f1b3c4208b496623b756c2acd1690be8be08bab 100644
--- a/fggl/gfx/renderer.cpp
+++ b/fggl/gfx/renderer.cpp
@@ -70,59 +70,6 @@ MeshRenderer::token_t MeshRenderer::upload(fggl::data::Mesh& mesh) {
 	return token;
 }
 
-void MeshRenderer::render(const Window& window, const fggl::ecs::ECS& ecs, const ecs::entity_t camera, float dt) {
-    if ( camera == ecs::NULL_ENTITY ) return;
-
-    auto entities = ecs.getEntityWith<MeshRenderer::token_t>();
-    if ( entities.size() == 0 ) return;
-
-    total += dt;
-
-    // make sure the correct rendering context is active
-    window.activate();
-
-    glEnable(GL_CULL_FACE);
-    glCullFace(GL_BACK);
-
-    glEnable(GL_DEPTH_TEST);
-
-    // camera logic
-    const auto camTransform = ecs.getComponent<math::Transform>(camera);
-    const auto camComp = ecs.getComponent<gfx::Camera>(camera);
-    glm::mat4 proj = glm::perspective( camComp->fov, camComp->aspectRatio, camComp->nearPlane, camComp->farPlane);
-    glm::mat4 view = glm::lookAt( camTransform->origin(), camComp->target, camTransform->up() );
-
-    // lighting
-    glm::vec3 lightPos(20.0f, 20.0f, 15.0f);
-
-    // TODO better performance if grouped by vao first
-    // TODO the nvidia performance presentation said I shouldn't use uniforms for large data
-    for ( auto& entity : entities ) {
-	    const auto& transform = ecs.getComponent<fggl::math::Transform>(entity);
-	    const auto& mesh = ecs.getComponent<MeshRenderer::token_t>(entity);
-
-	    glm::mat4 model = transform->model();
-//	    model = glm::rotate(model, glm::radians(total/2048.0f * 360.0f), glm::vec3(0.0f,1.0f,0.0f));
-
-	    auto shader = mesh->pipeline;
-	    glUseProgram( shader );
-
-	    glUniformMatrix4fv( glGetUniformLocation(shader, "model"), 1, GL_FALSE, glm::value_ptr( model ) );
-	    glUniformMatrix4fv( glGetUniformLocation(shader, "view"), 1, GL_FALSE, glm::value_ptr( view ) );
-	    glUniformMatrix4fv( glGetUniformLocation(shader, "projection"), 1, GL_FALSE, glm::value_ptr( proj ) );
-
-	    // lighting
-	    GLint lightID = glGetUniformLocation(shader, "lightPos");
-	    if ( lightID != -1 )
-		    glUniform3fv( lightID, 1, glm::value_ptr( lightPos ) );
-
-	    glBindVertexArray( mesh->vao );
-	    glDrawElements( GL_TRIANGLES, mesh->idxSize, GL_UNSIGNED_INT, reinterpret_cast<void*>(mesh->idxOffset) );
-    }
-
-    glBindVertexArray(0);
-
-}
 
 namespace fggl::systems {
 	void fglPopulateVertex(flecs::iter& it, const fggl::components::Transform* t, fggl::components::GfxMat* mats) {
diff --git a/fggl/gfx/renderer.hpp b/fggl/gfx/renderer.hpp
index e606cf9769c4f6baa04a22fc0cbd692e3d881ac0..6f638c46a1afe9a3843815f3927ca66881d3a8b7 100644
--- a/fggl/gfx/renderer.hpp
+++ b/fggl/gfx/renderer.hpp
@@ -4,7 +4,6 @@
 #include <vector>
 
 #include <fggl/data/model.hpp>
-#include <fggl/ecs/ecs.hpp>
 #include <fggl/gfx/ogl.hpp>
 
 #include <fggl/gfx/ecs.hpp>
@@ -18,7 +17,7 @@ namespace fggl::gfx {
 			token_t upload(fggl::data::Mesh& mesh);
 
 			// are VAO safe across opengl contexts? :S
-			void render(const Window& window, const ecs::ECS& ecs, const ecs::entity_t camera, float dt);
+			//void render(const Window& window, const ecs::ECS& ecs, const ecs::entity_t camera, float dt);
 
 			float total;
 	};
diff --git a/tests/testfggl/CMakeLists.txt b/tests/testfggl/CMakeLists.txt
index d7015641f74cd37d57892e911c478a6797d05b12..3e2cad18775d3e9a510b9bfc14b27241c7c85b7a 100644
--- a/tests/testfggl/CMakeLists.txt
+++ b/tests/testfggl/CMakeLists.txt
@@ -3,7 +3,7 @@ enable_testing()
 add_executable(
 	fggl_test
 	#	TestFggl.cpp
-	ecs/ecs.cpp
+	#	ecs/ecs.cpp
 	math/types.cpp
 )
 target_include_directories(fggl_test PUBLIC ${PROJECT_BINARY_DIR})
diff --git a/tests/testfggl/ecs/ecs.cpp b/tests/testfggl/ecs/ecs.cpp
deleted file mode 100644
index 4b2ffdbff3c2e19ef7f71c0931501608054453b4..0000000000000000000000000000000000000000
--- a/tests/testfggl/ecs/ecs.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include <fggl/ecs/ecs.hpp>
-
-using fggl::ecs::Component;
-
-namespace {
-
-	class DummyComp1 : public Component<DummyComp1> {
-	};
-
-	class DummyComp2 : public Component<DummyComp2> {
-		public:
-			int x;
-			DummyComp2(int tmp) : x(tmp) {
-			}
-			DummyComp2( DummyComp2&& other ) : x(other.x) {}
-	};
-
-	TEST(ecs, createEntity) {
-		fggl::ecs::ECS ecs;
-		auto eid = ecs.createEntity();
-
-		EXPECT_EQ( 1, eid );
-	}
-
-	TEST(ecs, addComponent) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto eid = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(eid);
-
-		EXPECT_EQ(1, eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-	}
-
-	TEST(ecs, addDuplicateComponent) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto eid = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-
-		auto dumpComp = ecs.addComponent<DummyComp1>(eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-		EXPECT_EQ(nullptr, dumpComp);
-	}
-
-	TEST(ecs, addTwoComponents) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-		ecs.registerComponent<DummyComp2>();
-
-		auto eid = ecs.createEntity();
-		auto comp = ecs.addComponent<DummyComp2>(eid, 0xB33F);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp2>(eid));
-		EXPECT_EQ(0xB33F, comp->x);
-
-		ecs.addComponent<DummyComp1>(eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp2>(eid));
-		// danger: comp is now invalid (dangling) ptr
-		
-		auto comp2 = ecs.getComponent<DummyComp2>(eid);
-		EXPECT_EQ(0xB33F, comp2->x);
-	}
-
-	TEST(ecs, addComponentRemoveAdd) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto eid = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-
-		ecs.addComponent<DummyComp1>(eid);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(eid));
-	}
-
-	TEST(ecs, hasComponentAddition) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto e1 = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(e1);
-
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(e1));
-	}
-
-	TEST(ecs, getWithComponentBlank) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto ents = ecs.getEntityWith<DummyComp1>();
-
-		EXPECT_EQ( 0, ents.size() );
-	}
-
-	TEST(ecs, listWithOneComponent) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-		ecs.registerComponent<DummyComp2>();
-
-		// has target component
-		auto ent1 = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(ent1);
-
-		// has another component
-		auto ent2 = ecs.createEntity();
-		ecs.addComponent<DummyComp2>(ent2, 0x4040);
-
-		// has no components
-		auto ent3 = ecs.createEntity();
-
-		auto ents = ecs.getEntityWith<DummyComp1>();
-
-		EXPECT_EQ( 1, ents.size() );
-		EXPECT_EQ( ent1, ents[0] );
-	}
-
-	TEST(ecs, listWithTwoComponents) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-		ecs.registerComponent<DummyComp2>();
-
-		// has no components
-		auto ent0 = ecs.createEntity();
-
-		// has target component
-		auto ent1 = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(ent1);
-
-		// has target + another component
-		auto ent2 = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(ent2);
-		ecs.addComponent<DummyComp2>(ent2, 0x8080);
-
-		auto ents = ecs.getEntityWith<DummyComp1>();
-
-		EXPECT_EQ( 2, ents.size() );
-		EXPECT_THAT( ents, testing::Contains( ent1 ) );
-		EXPECT_THAT( ents, testing::Contains( ent2 ) );
-	}
-
-	TEST(ecs, addComponentCurruption) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-		ecs.registerComponent<DummyComp2>();
-
-		// create the two ents first
-		auto ent1 = ecs.createEntity();
-		auto ent2 = ecs.createEntity();
-
-		// add comp2 in a way that forces reallocation
-		// this should force a shuffle on comp1's records
-		ecs.addComponent<DummyComp2>(ent2, 0x1313);
-		ecs.addComponent<DummyComp2>(ent1, 0x4242);
-
-		// check the values survived insersion
-		auto dc2 = ecs.getComponent<DummyComp2>(ent2);
-		auto dc1 = ecs.getComponent<DummyComp2>(ent1);
-		EXPECT_EQ( 0x1313, dc2->x );
-		EXPECT_EQ( 0x4242, dc1->x );
-
-		// add comp1 to force more shuffling (ent2 should be first in list, forcing a swap)
-		ecs.addComponent<DummyComp1>(ent2);
-
-		dc2 = ecs.getComponent<DummyComp2>(ent2);
-		dc1 = ecs.getComponent<DummyComp2>(ent1);
-		EXPECT_EQ( 0x1313, dc2->x );
-		EXPECT_EQ( 0x4242, dc1->x );
-	}
-
-
-	TEST(ecs, hasComponentRemoval) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto e1 = ecs.createEntity();
-		ecs.addComponent<DummyComp1>(e1);
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(e1));
-
-		//TODO implement removal
-		//ecs.removeComponent<DummyComp1>(e1);
-		//EXPECT_EQ(false, ecs.hasComponent<DummyComp1>(e1));
-	}
-
-	TEST(ecs, hasComponentEmpty) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto e1 = ecs.createEntity();
-		EXPECT_EQ(false, ecs.hasComponent<DummyComp1>(e1));
-	}
-
-
-	TEST(ecs, hasComponentOther) {
-		fggl::ecs::ECS ecs;
-		ecs.registerComponent<DummyComp1>();
-
-		auto e1 = ecs.createEntity();
-		auto e2 = ecs.createEntity();
-
-		ecs.addComponent<DummyComp1>(e1);
-
-		EXPECT_EQ(true, ecs.hasComponent<DummyComp1>(e1));
-		EXPECT_EQ(false, ecs.hasComponent<DummyComp1>(e2));
-	}
-
-}