added more flexible function support