implement the full function