full working solution, some polish/cleanup still needed