works now, needs optimization