Ported to C, may or may not works