all code except the demo, should be tested