Index: /trunk/nv/core/transform.hh
===================================================================
--- /trunk/nv/core/transform.hh	(revision 544)
+++ /trunk/nv/core/transform.hh	(revision 545)
@@ -109,4 +109,15 @@
 	}
 
+	inline bool operator==( const transform& lhs, const transform& rhs )
+	{
+		return lhs.get_position() == rhs.get_position() && lhs.get_orientation() == rhs.get_orientation();
+	}
+
+	inline bool operator!=( const transform& lhs, const transform& rhs )
+	{
+		return !( lhs == rhs );
+	}
+
+
 	template <> struct enum_to_type< TRANSFORM > { typedef transform type; };
 	template <> struct type_to_enum< transform > { static const datatype type = TRANSFORM; };
Index: /trunk/nv/ecs/component.hh
===================================================================
--- /trunk/nv/ecs/component.hh	(revision 544)
+++ /trunk/nv/ecs/component.hh	(revision 545)
@@ -58,6 +58,6 @@
 			typedef typename storage_type::const_reference  const_reference;
 
-			component( ecs_type& a_ecs, string_view a_name, uint32 reserve = 0 ) 
-				: m_ecs( a_ecs )
+			component( ecs_type& a_ecs, string_view a_name, bool relational = false, uint32 reserve = 0 ) 
+				: m_ecs( a_ecs ), m_relational( relational )
 			{
 				m_ecs.register_component<component_type, Handler>( a_name, this );
@@ -134,4 +134,6 @@
 				}
 				m_data.pop_back();
+				if ( m_relational )
+					relational_rebuild( dead_eindex );
 			}
 
@@ -147,4 +149,6 @@
 				}
 				m_data.pop_back();
+				if ( m_relational )
+					relational_rebuild( dead_eindex );
 			}
 
@@ -189,4 +193,38 @@
 			storage_type     m_data;
 		private:
+			void swap( handle_type a, handle_type b )
+			{
+				index_type ai = m_index.get( a );
+				index_type bi = m_index.get( b );
+				m_index.swap( a, b );
+				value_type t = nv::move( m_data[ai] );
+				m_data[ai] = nv::move( m_data[bi] );
+				m_data[bi] = nv::move( t );
+			}
+
+			handle_type extract_owner( index_type i )
+			{
+				return *(handle_type*)( &( m_data[i] ) );
+			}
+
+			void relational_remove( handle_type a )
+			{
+				index_type i = m_index.get( a );
+				remove( a );
+				relational_rebuild( i );
+			}
+
+			void relational_rebuild( index_type i )
+			{
+				handle_type h = extract_owner( i );
+				handle_type p = m_ecs.get_parent( h );
+				if ( !p ) return;
+				if ( i < m_index.get( p ) )
+				{
+					swap( h, p );
+					relational_rebuild( i );
+				}
+			}
+			bool             m_relational;
 			index_table_type m_index;
 		};
Index: /trunk/nv/stl/index_table.hh
===================================================================
--- /trunk/nv/stl/index_table.hh	(revision 544)
+++ /trunk/nv/stl/index_table.hh	(revision 545)
@@ -59,4 +59,14 @@
 		}
 
+		void swap( handle_type a, handle_type b )
+		{
+			if ( a.is_nil() || a.index() >= m_indexes.size() || m_indexes[a.index()] == -1 ) return;
+			if ( b.is_nil() || b.index() >= m_indexes.size() || m_indexes[b.index()] == -1 ) return;
+			index_type a_idx = m_indexes[a.index()];
+			index_type b_idx = m_indexes[b.index()];
+			nv::swap( m_indexes[a.index()], m_indexes[b.index()] );
+			nv::swap( m_handles[a_idx], m_handles[b_idx] );
+		}
+		
 		index_type remove_swap( handle_type h )
 		{
@@ -153,33 +163,49 @@
 		}
 
+		void swap( handle_type a, handle_type b )
+		{
+			if ( a.is_nil() || b.is_nil() ) return;
+			auto ai = m_indexes.find( a.index() );
+			auto bi = m_indexes.find( b.index() );
+			if ( ai == m_indexes.end() || bi == m_indexes.end() ) return;
+			index_type a_idx = ai->second;
+			index_type b_idx = bi->second;
+			ai->second = b_idx;
+			bi->second = a_idx;
+			nv::swap( m_handles[a_idx], m_handles[b_idx] );
+		}
+
 		index_type remove_swap( handle_type h )
 		{
 			if ( h.is_nil() ) return -1;
-			auto ih = m_indexes.find( h.index() );
+			index_type dead_h_index = h.index();
+			auto ih = m_indexes.find( dead_h_index );
 			if ( ih == m_indexes.end() || ih->second == index_type(-1) ) return -1;
-			index_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.index() );
-			return dead_eindex;
-		}
-
-		index_type remove_swap( index_type dead_eindex )
+
+			index_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( dead_h_index );
+			return dead_eindex;
+		}
+
+		index_type remove_swap_by_index( index_type dead_eindex )
 		{
 			if ( uint32( dead_eindex ) >= m_handles.size() ) return -1;
-			index_type h = m_handles[dead_eindex];
-			index_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 );
+			index_type dead_h_index = m_handles[dead_eindex];
+
+			index_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( dead_h_index );
 			return dead_eindex;
 		}
@@ -200,5 +226,4 @@
 	};
 
-
 }
 
