complete but buggy implementation