Based on a quick test in something I've got running ATM, that last bit of code I posted:
velocity2 = ( 2 * surface_normal * surface_normal.dot( velocity1 ) ) - velocity1;
Should probably be:
velocity2 = velocity1 - ( 2 * surface_normal * surface_normal.dot( velocity1 ) );
!
Plato forgot the nullahedron..