almost complete (arrays untested)