final version with improvements