port from java, initial version. Needs tuning