Index: /trunk/nv/ecs/component.hh
===================================================================
--- /trunk/nv/ecs/component.hh	(revision 537)
+++ /trunk/nv/ecs/component.hh	(revision 538)
@@ -29,39 +29,59 @@
 	{
 
-		template < typename Ecs, typename Component >
+		template < 
+			typename Ecs,
+			typename Component,
+			template < typename, typename > class IndexTable = index_table
+		>
 		class component : public Ecs::component_interface
 		{
 		public:
-			typedef Ecs                                      ecs_type;
-			typedef typename ecs_type::message               message_type;
-			typedef typename ecs_type::handle_type           handle_type;
-			typedef typename ecs_type::time_type             time_type;
-			typedef Component                                value_type;
-			typedef Component                                component_type;
-			typedef index_storage< handle_type, value_type > storage_type;
-			typedef typename storage_type::index_type        index_type;
+			typedef Ecs                                    ecs_type;
+			typedef typename ecs_type::message             message_type;
+			typedef typename ecs_type::handle_type         handle_type;
+			typedef typename ecs_type::time_type           time_type;
+			typedef IndexTable< handle_type, sint32 >      index_table_type;
+			typedef Component                              value_type;
+			typedef Component                              component_type;
+			typedef vector< value_type >                   storage_type;
+			typedef typename index_table_type::index_type  index_type;
 
-			typedef typename storage_type::iterator          iterator;
-			typedef typename storage_type::const_iterator    const_iterator;
-			typedef typename storage_type::reference         reference;
-			typedef typename storage_type::const_reference   const_reference;
+			typedef typename storage_type::iterator        iterator;
+			typedef typename storage_type::const_iterator  const_iterator;
+			typedef typename storage_type::reference       reference;
+			typedef typename storage_type::const_reference const_reference;
 
 			component( ecs_type& a_ecs, string_view a_name, uint32 reserve = 0 ) 
-				: m_ecs( a_ecs ), m_data( reserve )
+				: m_ecs( a_ecs )
 			{
 				m_ecs.register_component<component_type>( a_name, this );
+				if ( reserve != 0 )
+				{
+					m_data.reserve( reserve );
+				}
 			}
 
-			inline value_type& insert( handle_type h ) { return m_data.insert( h ); }
+			inline value_type& insert( handle_type h )
+			{
+				index_type i = m_index.insert( h );
+				NV_ASSERT( i == index_type( m_data.size() ), "Fail!" );
+				NV_UNUSED( i );
+				m_data.emplace_back();
+				return m_data.back();
+			}
 
 			template < typename ...Args >
 			value_type& insert( handle_type h, Args&&... args )
 			{
-				return m_data.insert( h, nv::forward<Args>( args )... );
+				index_type i = m_index.insert( h );
+				NV_ASSERT( i == index_type( m_data.size() ), "Fail!" );
+				NV_UNUSED( i );
+				m_data.emplace_back( nv::forward<Args>( args )... );
+				return m_data.back();
 			}
 
 			bool exists( handle_type h )
 			{
-				return m_data.exists( h );
+				return m_index.exists( h );
 			}
 
@@ -73,11 +93,20 @@
 			virtual void clear()
 			{
-				for ( uint32 i = 0; i < size(); ++i )
+				for ( uint32 i = 0; i < m_data.size(); ++i )
 					destroy( &m_data[i] );
+				m_index.clear();
 				m_data.clear();
 			}
 
-			value_type* get( handle_type h ) { return m_data.get(h); }
-			const value_type* get( handle_type h ) const { return m_data.get( h ); }
+			value_type* get( handle_type h )
+			{
+				index_type i = m_index.get( h );
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
+			const value_type* get( handle_type h ) const
+			{
+				index_type i = m_index.get( h );
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
 
 			void* get_raw( handle_type h ) { return get( h ); }
@@ -86,8 +115,14 @@
 			virtual void remove( handle_type h )
 			{
-				value_type* v = m_data.get( h );
+				value_type* v = get( h );
 				if ( v == nullptr ) return;
 				destroy( v );
-				m_data.remove( h );
+				index_type dead_eindex = m_index.remove_swap( h );
+				if ( dead_eindex == -1 ) return;
+				if ( dead_eindex != static_cast<index_type>( m_data.size() - 1 ) )
+				{
+					m_data[unsigned( dead_eindex )] = move( m_data.back() );
+				}
+				m_data.pop_back();
 			}
 
@@ -106,7 +141,6 @@
 				clear();
 			}
-
-
-			inline handle_type get_handle( index_type i ) const { return m_data.get_handle( i ); }
+			
+			inline handle_type get_handle( index_type i ) const { return m_index.get_handle( i ); }
 
 			inline const value_type& operator[] ( index_type i ) const { return m_data[i]; }
@@ -124,4 +158,5 @@
 		protected:
 			ecs_type&        m_ecs;
+			index_table_type m_index;
 			storage_type     m_data;
 		};
Index: /trunk/nv/ecs/component_storage.hh
===================================================================
--- /trunk/nv/ecs/component_storage.hh	(revision 537)
+++ /trunk/nv/ecs/component_storage.hh	(revision 538)
@@ -18,4 +18,5 @@
 #include <nv/stl/index_table.hh>
 #include <nv/stl/handle_manager.hh>
+#include <nv/stl/hash_map.hh>
 
 namespace nv
@@ -32,6 +33,5 @@
 			typedef Component                              value_type;
 			typedef vector< value_type >                   storage_type;
-			typedef index_table< handle_type >             index_table_type;
-			typedef typename index_table_type::index_type  index_type;
+			typedef sint32                                 index_type;
 			typedef typename storage_type::iterator        iterator;
 			typedef typename storage_type::const_iterator  const_iterator;
@@ -297,7 +297,92 @@
 
 		class direct_storage;
-		class hash_storage;
+		/*
+		template < typename Handle, typename Component >
+		class hash_storage
+		{
+		public:
+			typedef Handle                                 handle_type;
+			typedef Component                              value_type;
+			typedef vector< value_type >                   storage_type;
+			typedef typename storage_type::iterator        iterator;
+			typedef typename storage_type::const_iterator  const_iterator;
+			typedef typename storage_type::reference       reference;
+			typedef typename storage_type::const_reference const_reference;
+		
+			explicit hash_storage( uint32 reserve = 0 )
+			{
+				if ( reserve != 0 )
+				{
+					m_data.reserve( reserve );
+				}
+			}
+
+			inline value_type& insert( handle_type h )
+			{
+				auto result = m_data.insert_key( h );
+				NV_ASSERT( result.second, "Reinsert of handle!" );
+				m_data.emplace_back();
+				return m_data.back();
+			}
+
+			template < typename ...Args >
+			inline value_type& insert( handle_type h, Args&&... args )
+			{
+				insert_index( h );
+				m_data.emplace_back( nv::forward<Args>( args )... );
+				return m_data.back();
+			}
+
+			inline bool exists( handle_type h )
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() ) return false;
+				return m_indexes[h.index()] >= 0;
+			}
+
+			value_type* get( handle_type h )
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
+				index_type i = m_indexes[h.index()];
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
+
+			const value_type* get( handle_type h ) const
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
+				index_type i = m_indexes[h.index()];
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
+
+			void clear()
+			{
+				m_data.clear();
+			}
+
+			void remove( handle_type h )
+			{
+
+
+			}
+
+			inline handle_type get_handle( sint32 i ) const { return m_handles[unsigned( i )]; }
+
+			inline const value_type& operator[] ( index_type i ) const { return m_data[i]; }
+			inline value_type& operator[] ( index_type i ) { return m_data[i]; }
+
+			inline size_t size() const { return m_data.size(); }
+
+			inline iterator        begin() { return m_data.begin(); }
+			inline const_iterator  begin()  const { return m_data.cbegin(); }
+
+			inline iterator        end() { return m_data.end(); }
+			inline const_iterator  end()  const { return m_data.cend(); }
+
+		protected:
+			vector< value_type > m_data;
+		};
+
+
 		class hash_multi_storage;
-
+		*/
 	}
 
Index: /trunk/nv/lua/lua_iterator.hh
===================================================================
--- /trunk/nv/lua/lua_iterator.hh	(revision 538)
+++ /trunk/nv/lua/lua_iterator.hh	(revision 538)
@@ -0,0 +1,115 @@
+// Copyright (C) 2017-2017 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+#ifndef NV_LUA_ITERATOR_HH
+#define NV_LUA_ITERATOR_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/iterator.hh>
+#include <nv/lua/lua_proxy.hh>
+
+namespace nv
+{
+
+	namespace lua
+	{
+		class state;
+		class lua_iterator_provider;
+
+		class iterator_base 
+		{
+		public:
+			explicit iterator_base( state* state = nullptr, sint32 index = -1 );
+
+			iterator_base& operator++ ()
+			{
+				next();
+				return *this;
+			}
+
+			bool operator!= ( const iterator_base& ) const
+			{
+				return m_state != nullptr;
+			}
+		protected:
+			void next();
+
+			state* m_state;
+			sint32 m_index;
+		};
+
+		class kv_iterator : public iterator_base
+		{
+		public:
+			using iterator_base::iterator_base;
+			kv_proxy operator* () const { return kv_proxy( m_state ); }
+		};
+
+		class key_iterator : public iterator_base
+		{
+		public:
+			using iterator_base::iterator_base;
+			stack_proxy operator* () const { return stack_proxy( m_state, -2 ); }
+		};
+
+		class value_iterator : public iterator_base
+		{
+		public:
+			using iterator_base::iterator_base;
+			stack_proxy operator* () const { return stack_proxy( m_state, -1 ); }
+		};
+
+		class iterator_provider_base
+		{
+		public:
+			iterator_provider_base( state* parent, int index );
+			iterator_provider_base( const iterator_provider_base& ) = delete;
+			iterator_provider_base& operator=( const iterator_provider_base& ) = delete;
+			iterator_provider_base( iterator_provider_base&& other )
+			{
+				m_parent = other.m_parent;
+				m_index = other.m_index;
+				m_level = other.m_level;
+				other.m_parent = nullptr;
+			}
+			iterator_provider_base& operator=( iterator_provider_base&& other )
+			{
+				if ( this != &other )
+				{
+					m_parent = other.m_parent;
+					m_index = other.m_index;
+					m_level = other.m_level;
+					other.m_parent = nullptr;
+				}
+				return *this;
+			}
+			~iterator_provider_base();
+		protected:
+			friend class iterator_base;
+
+			state* m_parent;
+			int m_level;
+			int m_index;
+		};
+
+
+		template < typename Iterator >
+		class iterator_provider : public iterator_provider_base
+		{
+		public:
+			using iterator_provider_base::iterator_provider_base;
+
+			Iterator begin() { return Iterator( m_parent, m_index ); }
+			Iterator end() { return Iterator(); }
+		};
+
+
+	};
+
+}
+
+#endif // NV_LUA_PROXY_HH
Index: /trunk/nv/lua/lua_proxy.hh
===================================================================
--- /trunk/nv/lua/lua_proxy.hh	(revision 538)
+++ /trunk/nv/lua/lua_proxy.hh	(revision 538)
@@ -0,0 +1,55 @@
+// Copyright (C) 2017-2017 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+#ifndef NV_LUA_PROXY_HH
+#define NV_LUA_PROXY_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+
+namespace nv
+{
+	namespace lua
+	{
+		class state;
+
+		class stack_proxy
+		{
+		public:
+			stack_proxy( state* state, sint32 index ) : m_state( state ), m_index( index ) {}
+			stack_proxy( const stack_proxy& ) = delete;
+			stack_proxy& operator=( const stack_proxy& ) = delete;
+			stack_proxy( stack_proxy&& ) = default;
+			stack_proxy& operator=( stack_proxy&& ) = default;
+			string64 get_string64() const;
+			string64 to_string64();
+			// TO FUCKING DO : non-copyable stringview
+//			string_view get_string_view() const;
+//			string_view to_string_view();
+		protected:
+			state* m_state;
+			sint32 m_index;
+		};
+
+		class kv_proxy
+		{
+		public:
+			kv_proxy( state* state ) : m_state( state ) {}
+			kv_proxy( const kv_proxy& ) = delete;
+			kv_proxy& operator=( const kv_proxy& ) = delete;
+			kv_proxy( kv_proxy&& ) = default;
+			kv_proxy& operator=( kv_proxy&& ) = default;
+			const stack_proxy key() const { return stack_proxy( m_state, -2 ); }
+			stack_proxy value() const { return stack_proxy( m_state, -1 ); }
+		protected:
+			state* m_state;
+		};
+
+	}
+
+}
+
+#endif // NV_LUA_PROXY_HH
Index: /trunk/nv/lua/lua_raw.hh
===================================================================
--- /trunk/nv/lua/lua_raw.hh	(revision 537)
+++ /trunk/nv/lua/lua_raw.hh	(revision 538)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2015 ChaosForge Ltd
+// Copyright (C) 2012-2017 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: /trunk/nv/lua/lua_state.hh
===================================================================
--- /trunk/nv/lua/lua_state.hh	(revision 537)
+++ /trunk/nv/lua/lua_state.hh	(revision 538)
@@ -19,4 +19,6 @@
 #include <nv/stl/type_traits/function.hh>
 
+#include <nv/lua/lua_proxy.hh>
+#include <nv/lua/lua_iterator.hh>
 #include <nv/lua/lua_handle.hh>
 #include <nv/lua/lua_path.hh>
@@ -37,4 +39,5 @@
 
 		class state;
+		class lua_iterator_provider;
 
 		using lua_rtti_read_function  = bool(*)( state*, const type_entry*, void*, int index );
@@ -201,4 +204,7 @@
 
 			const type_data* get_type_data() const { return m_lua_types; }
+
+
+
 
 		protected:
@@ -256,4 +262,5 @@
 			int get_stack_size();
 			void log_stack();
+
 			lua_State* get_raw();
 			ref register_object( void* o, string_view lua_name );
@@ -363,4 +370,7 @@
 		};
 
+
+
+
 		class table_guard : public state_wrapper
 		{
@@ -370,5 +380,24 @@
 			virtual ~table_guard();
 			uint32 get_size();
-			
+			iterator_provider< kv_iterator > pairs()
+			{
+				return iterator_provider< kv_iterator >( m_parent, -1 );
+			}
+			iterator_provider< key_iterator > keys()
+			{
+				return iterator_provider< key_iterator >( m_parent, -1 );
+			}
+			iterator_provider< value_iterator > values()
+			{
+				return iterator_provider< value_iterator >( m_parent, -1 );
+			}
+
+// TO FUCKING DO:
+//			const stack_proxy operator[]( const string_view& key ) const;
+//			const stack_proxy operator[]( sint32 key ) const;
+//			stack_proxy operator[]( const string_view& key );
+//			stack_proxy operator[]( sint32 key );
+
+
 			bool has_field( string_view element );
 			
Index: /trunk/nv/stl/handle.hh
===================================================================
--- /trunk/nv/stl/handle.hh	(revision 537)
+++ /trunk/nv/stl/handle.hh	(revision 538)
@@ -16,4 +16,5 @@
 #include <nv/stl/vector.hh>
 #include <nv/stl/index_table.hh>
+#include <nv/stl/functional/hash.hh>
 
 namespace nv
@@ -46,6 +47,6 @@
 
 		constexpr T index() const { return m_index; }
-		//uint32 hash() const { return hash<T>()( T( m_counter << IBITS | m_index ) ); }
-		constexpr uint32 hash() const { NV_ASSERT( false, "UNIMPLEMENTED!" ); return 0; }
+		template < typename H = uint64 >
+		constexpr H hash() const { return nv::hash<T,H>()( T( m_counter << IBITS | m_index ) ); }
 	protected:
 		T m_index   : IBITS;
@@ -57,4 +58,20 @@
 	};
 
+	template < 
+		typename H,
+		typename T,
+		unsigned IBITS,
+		unsigned CBITS,
+		typename TAG
+	>
+	struct hash< handle< T, IBITS, CBITS, TAG >, H > 
+		: detail::hash_base< handle< T, IBITS, CBITS, TAG >, H >
+	{
+		static constexpr H get( const handle< T, IBITS, CBITS, TAG >& value )
+		{
+			return value.hash<H>();
+		}
+		inline H operator()( const handle< T, IBITS, CBITS, TAG >& value ) const { return get( value ); }
+	};
 
 }
Index: /trunk/nv/stl/index_table.hh
===================================================================
--- /trunk/nv/stl/index_table.hh	(revision 537)
+++ /trunk/nv/stl/index_table.hh	(revision 538)
@@ -16,4 +16,5 @@
 #include <nv/common.hh>
 #include <nv/stl/vector.hh>
+#include <nv/stl/hash_map.hh>
 
 namespace nv
@@ -116,4 +117,90 @@
 	};
 
+	template <
+		typename Handle,
+		typename Index = sint32
+	>
+		class hashed_index_table
+	{
+	public:
+		typedef Handle              handle_type;
+		typedef Index               index_type;
+
+		hashed_index_table() {}
+		hashed_index_table( uint32 reserve )
+		{
+			m_indexes.reserve( reserve );
+		}
+
+		index_type insert( handle_type h )
+		{
+			NV_ASSERT( m_indexes.find( h ) == m_indexes.end(), "Reinserting handle!" );
+			index_type lindex = m_handles.size();
+			m_indexes[h] = index_type( lindex );
+			m_handles.push_back( h );
+			return lindex;
+		}
+
+		bool exists( handle_type h ) const
+		{
+			auto ih = m_indexes.find( h );
+			return ( ih != m_indexes.end() );
+		}
+
+		index_type get( handle_type h ) const
+		{
+			auto ih = m_indexes.find( h );
+			if ( ih == m_indexes.end() ) return -1;
+			return ih->second;
+		}
+
+		index_type remove_swap( handle_type h )
+		{
+			if ( h.is_nil() ) return -1;
+			auto ih = m_indexes.find( h );
+			if ( ih == m_indexes.end() ) return -1;
+			handle_type swap_handle = m_handles.back();
+			index_type  dead_eindex = ih->second;
+			if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) )
+			{
+				m_handles[unsigned( dead_eindex )] = swap_handle;
+				m_indexes[swap_handle] = dead_eindex;
+			}
+			m_handles.pop_back();
+			m_indexes.erase( h );
+			return dead_eindex;
+		}
+
+// 		index_type remove_swap( index_type dead_eindex )
+// 		{
+// 			if ( uint32( dead_eindex ) >= m_handles.size() ) return -1;
+// 			handle_type h = m_handles[dead_eindex];
+// 			handle_type swap_handle = m_handles.back();
+// 			if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) )
+// 			{
+// 				m_handles[unsigned( dead_eindex )] = swap_handle;
+// 				m_indexes[swap_handle] = dead_eindex;
+// 			}
+// 			m_handles.pop_back();
+// 			m_indexes.erase( h );
+// 			return dead_eindex;
+// 		}
+
+
+		void clear()
+		{
+			m_handles.clear();
+			m_indexes.clear();
+		}
+
+		handle_type get_handle( index_type i ) const { return m_handles[unsigned( i )]; }
+
+		uint32 size() const { return m_handles.size(); }
+
+	private:
+
+		vector< handle_type > m_handles;
+		hash_map< handle_type, index_type > m_indexes;
+	};
 
 }
Index: /trunk/src/lua/lua_iterator.cc
===================================================================
--- /trunk/src/lua/lua_iterator.cc	(revision 538)
+++ /trunk/src/lua/lua_iterator.cc	(revision 538)
@@ -0,0 +1,43 @@
+// Copyright (C) 2017-2017 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+#include "nv/lua/lua_iterator.hh"
+
+#include "nv/lua/lua_raw.hh"
+#include "nv/lua/lua_state.hh"
+
+using namespace nv;
+using namespace nv::lua;
+
+nv::lua::iterator_provider_base::iterator_provider_base( state* parent, int index )
+{
+	m_parent = parent;
+	m_index = nlua_absindex( *m_parent, index );
+	m_level = lua_gettop( *m_parent );
+	lua_pushnil( *m_parent );
+}
+
+nv::lua::iterator_provider_base::~iterator_provider_base()
+{
+	if ( m_parent )
+		lua_settop( *m_parent, m_level );
+}
+
+void nv::lua::iterator_base::next()
+{
+	if ( !m_state ) return;
+	lua_pop( *( m_state ), 1 );
+	if ( lua_next( *( m_state ), m_index ) == 0 )
+		m_state = nullptr;
+}
+
+nv::lua::iterator_base::iterator_base( state* state, sint32 index )
+	: m_state( state ), m_index( index )
+{
+	if ( m_state )
+		if ( lua_next( *( m_state ), m_index ) == 0 )
+			m_state = nullptr;
+}
Index: /trunk/src/lua/lua_proxy.cc
===================================================================
--- /trunk/src/lua/lua_proxy.cc	(revision 538)
+++ /trunk/src/lua/lua_proxy.cc	(revision 538)
@@ -0,0 +1,32 @@
+// Copyright (C) 2017-2017 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+#include "nv/lua/lua_proxy.hh"
+
+#include "nv/lua/lua_raw.hh"
+#include "nv/lua/lua_state.hh"
+
+using namespace nv;
+using namespace nv::lua;
+
+nv::string64 nv::lua::stack_proxy::get_string64() const
+{
+	size_t l = 0;
+	const char* str = nullptr;
+	if ( lua_type( *m_state, m_index ) == LUA_TSTRING )
+	{
+		str = lua_tolstring( *m_state, m_index, &l );
+	}
+	return string64( str, static_cast<uint32>( l ) );
+}
+
+nv::string64 nv::lua::stack_proxy::to_string64()
+{
+	size_t l = 0;
+	const char* str = nullptr;
+	str = lua_tolstring( *m_state, m_index, &l );
+	return string64( str, static_cast<uint32>( l ) );
+}
Index: /trunk/src/lua/lua_state.cc
===================================================================
--- /trunk/src/lua/lua_state.cc	(revision 537)
+++ /trunk/src/lua/lua_state.cc	(revision 538)
@@ -938,2 +938,3 @@
 //	insert<nv::uint64>( nlua_rtti_floating_push<nv::uint64>, nlua_rtti_floating_read<nv::uint64> );
 }
+
