Updated with better structure and many fixes.