final version (some clean)