Add documentation and some refractoring