Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 269)
+++ trunk/src/gui/gui_environment.cc	(revision 270)
@@ -26,5 +26,5 @@
 
 nv::gui::environment::environment( window* w, const std::string& shader_path )
-	: m_renderer( nullptr ), m_window( w ), m_first_free(-1), m_last_free(-1)
+	: m_renderer( nullptr ), m_window( w )
 {
 	m_area.dim( dimension( w->get_width(), w->get_height() ) );
@@ -62,46 +62,6 @@
 {
 	m_elements.emplace_back();
-	m_elements.back().m_this = create_index( uint16( m_elements.size() - 1 ) );
+	m_elements.back().m_this = m_indexes.create_handle( sint32( m_elements.size() - 1 ) );
 	return m_elements.back().m_this;
-}
-
-nv::gui::handle nv::gui::environment::create_index( sint16 element_id )
-{
-	uint16 i   = get_free_index();
-	index& idx = m_indices[i];
-	idx.element_id = element_id;
-	idx.counter++;
-	return handle( i, idx.counter );
-}
-
-nv::uint16 nv::gui::environment::get_free_index()
-{
-	if ( m_first_free != -1 )
-	{
-		uint16 result = (uint16)m_first_free;
-		m_first_free = m_indices[result].next_free;
-		m_indices[result].next_free = -1;
-		if ( m_first_free == -1 ) m_last_free = -1;
-		return result;
-	}
-	m_indices.emplace_back();
-	return uint16( m_indices.size() - 1 );
-}
-
-void nv::gui::environment::free_index( uint16 idx_index )
-{
-	// TODO: reuse
-	index& idx = m_indices[ idx_index ];
-	idx.element_id = -1;
-	idx.next_free  = -1;
-	if ( m_last_free == -1 )
-	{
-		m_first_free = m_last_free = idx_index;
-	}
-	else
-	{
-		m_indices[ m_last_free ].next_free = idx_index;
-		m_last_free = idx_index;
-	}
 }
 
@@ -117,14 +77,13 @@
 	dead_element->m_parent = handle();
 
-	uint16 dead_index    = m_indices[ e.m_index ].element_id;
-	if ( dead_index != m_elements.size()-1 )
-	{
-		m_elements[ dead_index ] = m_elements.back();
-		m_elements.pop_back();
-		m_indices[ m_elements[ dead_index ].m_this.m_index ].element_id = dead_index;
-	}
-	else
-		m_elements.pop_back();
-	free_index( e.m_index );
+	handle swap_handle    = m_elements.back().m_this;
+	sint32 dead_eindex    = m_indexes.get_index( e );
+	if ( dead_eindex != (sint32)m_elements.size()-1 )
+	{
+		m_elements[ dead_eindex ] = m_elements.back();
+	}
+	m_elements.pop_back();
+	m_indexes.swap_indices( e, swap_handle );
+	m_indexes.free_handle( e );
 }
 
@@ -219,5 +178,5 @@
 {
 	element* el = get_element( e );
-	return el && el->m_parent.m_index ? process_io_event( el->m_parent, ev ) : false;
+	return el && el->m_parent.is_valid() ? process_io_event( el->m_parent, ev ) : false;
 }
 
@@ -230,6 +189,6 @@
 {
 	if ( h.is_nil() ) return nullptr;
-	const index& idx = m_indices[ h.m_index ];
-	return idx.counter == h.m_counter && idx.element_id >= 0 ? &m_elements[ idx.element_id ] : nullptr;
+	sint32 eindex = m_indexes.get_index( h );
+	return eindex >= 0 ? &m_elements[ eindex ] : nullptr;
 }
 
@@ -245,5 +204,5 @@
 	{
 		result = get_deepest_child( *it, p );
-		if ( result.m_index ) return result;
+		if ( result.is_valid() ) return result;
 		++it;
 	}
