working version.
lacks testing