Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 535)
+++ trunk/src/gl/gl_context.cc	(revision 543)
@@ -97,15 +97,22 @@
 void nv::gl_context::release( vertex_array va )
 {
-	gl_vertex_array_info* info = m_vertex_arrays.get( va );
+	if ( gl_vertex_array_info* info = m_vertex_arrays.get( va ) )
+	{
+		release( info );
+		m_vertex_arrays.destroy( va );
+	}
+}
+
+void nv::gl_context::release( gl_vertex_array_info* info )
+{
 	if ( info )
 	{
 		for ( uint32 i = 0; i < info->count; ++i )
 		{
-			if ( info->attr[i].owner ) 
+			if ( info->attr[i].owner )
 				release( info->attr[i].vbuffer );
 		}
-		if ( info->index.is_valid() && info->index_owner) release( info->index );
+		if ( info->index.is_valid() && info->index_owner ) release( info->index );
 		glDeleteVertexArrays( 1, &info->glid );
-		m_vertex_arrays.destroy( va );
 	}
 }
@@ -113,5 +120,13 @@
 void nv::gl_context::release( framebuffer f )
 {
-	gl_framebuffer_info* info = m_framebuffers.get( f );
+	if ( gl_framebuffer_info* info = m_framebuffers.get( f ) )
+	{
+		release( info );
+		m_framebuffers.destroy( f );
+	}
+}
+
+void nv::gl_context::release( gl_framebuffer_info* info )
+{
 	if ( info )
 	{
@@ -122,5 +137,4 @@
 			glDeleteRenderbuffers( 1, &info->depth_rb_glid );
 		glDeleteFramebuffers( 1, &info->glid );
-		m_framebuffers.destroy( f );
 	}
 }
@@ -881,8 +895,8 @@
 nv::gl_context::~gl_context()
 {
-	while ( m_framebuffers.size() > 0 )
-		release( m_framebuffers.get_handle(0) );
-	while ( m_vertex_arrays.size() > 0 )
-		release( m_vertex_arrays.get_handle(0) );
+	for ( auto& info : m_framebuffers )
+		release( &info );
+	for ( auto& info : m_vertex_arrays )
+		release( &info );
 }
 
Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 535)
+++ trunk/src/gl/gl_device.cc	(revision 543)
@@ -69,12 +69,12 @@
 gl_device::~gl_device()
 {
-	while ( m_textures.size() > 0 )
-		release( m_textures.get_handle(0) );
-	while ( m_buffers.size() > 0 )
-		release( m_buffers.get_handle(0) );
-	while ( m_programs.size() > 0 )
-		release( m_programs.get_handle(0) );
-	while ( m_shaders.size() > 0 )
-		release( m_shaders.get_handle( 0 ) );
+	for ( auto& t : m_textures )
+		release( &t );
+	for ( auto& b : m_buffers )
+		release( &b );
+	for ( auto& p : m_programs )
+		release( &p );
+	for ( auto& s : m_shaders )
+		release( &s );
 }
 
@@ -131,24 +131,64 @@
 void nv::gl_device::release( texture t )
 {
-	gl_texture_info* info = m_textures.get( t );
-	if ( info )
-	{
-		if ( info->glid != 0 )
-		{
-			glDeleteTextures( 1, &(info->glid) );
-		}
+	if ( auto info = m_textures.get( t ) )
+	{
+		release( info );
 		m_textures.destroy( t );
 	}
 }
 
+void nv::gl_device::release( gl_shader_info* s )
+{
+	if ( s && s->ref == 0 && s->glid != 0 )
+		glDeleteShader( s->glid );
+}
+
+void nv::gl_device::release( gl_program_info* p )
+{
+	if ( p && p->glid != 0 )
+	{
+		for ( auto& i : *p->m_uniform_map )
+			delete i.second;
+
+		gl_shader_info* vi = m_shaders.get( p->vertex );
+		gl_shader_info* fi = m_shaders.get( p->fragment );
+		if ( vi )
+		{
+			glDetachShader( p->glid, vi->glid );
+			vi->ref--;
+			release( vi );
+		}
+		if ( fi )
+		{
+			glDetachShader( p->glid, fi->glid );
+			fi->ref--;
+			release( fi );
+		}
+		glDeleteProgram( p->glid );
+
+		delete p->m_attribute_map;
+		delete p->m_engine_uniforms;
+		delete p->m_uniform_map;
+	}
+
+}
+
+void nv::gl_device::release( gl_texture_info* t )
+{
+	if ( t && t->glid != 0 )
+		glDeleteTextures( 1, &( t->glid ) );
+}
+
+void nv::gl_device::release( gl_buffer_info* b )
+{
+	if ( b && b->glid != 0 )
+		glDeleteBuffers( 1, &( b->glid ) );
+}
+
 void nv::gl_device::release( buffer b )
 {
-	gl_buffer_info* info = m_buffers.get( b );
-	if ( info )
-	{
-		if ( info->glid != 0 )
-		{
-			glDeleteBuffers( 1, &(info->glid) );
-		}
+	if ( auto info = m_buffers.get( b ) )
+	{
+		release( info );
 		m_buffers.destroy( b );
 	}
@@ -204,18 +244,7 @@
 void nv::gl_device::release( program p )
 {
-	gl_program_info* info = m_programs.get( p );
-	if ( info )
-	{
-		for ( auto& i : *info->m_uniform_map )
-			delete i.second;
-
-		detach( p, info->vertex );
-		detach( p, info->fragment );
-		glDeleteProgram( info->glid );
-
-		delete info->m_attribute_map;
-		delete info->m_engine_uniforms;
-		delete info->m_uniform_map;
-
+	if ( auto info = m_programs.get( p ) )
+	{
+		release( info );
 		m_programs.destroy( p );
 	}
@@ -224,8 +253,7 @@
 void nv::gl_device::release( shader s )
 {
-	gl_shader_info* info = m_shaders.get( s );
-	if ( info && info->ref == 0 )
-	{
-		glDeleteShader( info->glid );
+	if ( auto info = m_shaders.get( s ) )
+	{
+		release( info );
 		m_shaders.destroy( s );
 	}
