code was rewritten, may be errors