nearly complete implementation, fixed som other functions