Quantum Error Correction and Fault Tolerant Quantum Computing