main implementation