private static Function CreateAnimationFunction(Type type)
        {
            string body    = "";
            string thisref = "this";

            body += "var $animob = {};\r\n";

            // gets and annotate constructor parameter; annotations are stored in type.$inject
            var parameters = Angular.Injector().Annotate(type.GetConstructorFunction());

            // takes method into $scope, binding "$scope" to "this"
            foreach (string funcname in type.GetInstanceMethodNames())
            {
                body += String.Format("{2}.{1} = {0}.prototype.{1}.bind({2});\r\n", type.FullName, funcname, thisref);

                if (funcname == "Start" || funcname == "Setup" || funcname == "Cancel")
                {
                    body += String.Format("$animob.{0} = {2}.{1};\r\n", funcname.ToLower(), funcname, thisref);
                }
            }

            // put call at the end so that methods are defined first
            body += String.Format("{0}.apply({1},arguments);\r\n", type.FullName, thisref);
            body += String.Format("return $animob;\r\n");
            return(TypeExtensionMethods.CreateNewFunction(parameters, body));
        }
        public static Function BuildControllerFunction(this Type type, ThisMode this_mode, string return_function = null, bool return_function_call = false)
        {
            string body    = "";
            string thisref = "";

            if (this_mode == ThisMode.NewObject)
            {
                thisref = "$self";
            }
            else if (this_mode == ThisMode.ScopeStrict)
            {
                thisref = "_scope";
            }
            else if (this_mode == ThisMode.Scope)
            {
                thisref = "_scope";
            }
            else if (this_mode == ThisMode.This)
            {
                thisref = "this";
            }

            if (this_mode == ThisMode.NewObject)
            {
                body += "var $self = new Object();";
            }

            // gets and annotate constructor parameter; annotations are stored in type.$inject
            var parameters = Angular.Injector().Annotate(type.GetConstructorFunction());

            if (this_mode == ThisMode.ScopeStrict)
            {
                // verifies that "scope" is the first parameter in constructor
                if (parameters.Count < 1 || parameters[0] != "_scope")
                {
                    throw new Exception(String.Format("Controller {0} must specify '_scope' as first parameter in its constructor", type.Name));
                }
            }

            // takes method into $scope, binding "$scope" to "this"
            foreach (string funcname in type.GetInstanceMethodNames())
            {
                body += String.Format("{2}.{1} = {0}.prototype.{1}.bind({2});\r\n", type.FullName, funcname, thisref);
            }

            // put call at the end so that methods are defined first
            body += String.Format("{0}.apply({1},arguments);\r\n", type.FullName, thisref);

            if (return_function != null)
            {
                if (return_function_call)
                {
                    body += String.Format("return {1}.{0}();\r\n", return_function, thisref);
                }
                else
                {
                    body += String.Format("return {1}.{0}  ;\r\n", return_function, thisref);
                }

                if (!type.GetInstanceMethodNames().Contains(return_function))
                {
                    throw new Exception("function '" + return_function + "' not defined in controller '" + type.Name + "'");
                }
            }

            return(TypeExtensionMethods.CreateNewFunction(parameters, body));
        }
        private static Function CreateDirectiveFunction(DirectiveDefinition def)
        {
            object defob = def.CreateDefinitionObject();

            List <string> parameters = new List <string>();
            List <string> fnames     = new List <string>();

            Type type = def.DirectiveController;

            object SharedController = ((dynamic)defob).controller;

            if (type != null)
            {
                parameters = Angular.Injector().Annotate(type.GetConstructorFunction());
                fnames     = type.GetInstanceMethodNames();
            }

            string body = "";

            body += "var $obdef = " + Json.Stringify(defob) + ";\r\n";

            if (type != null)
            {
                if (fnames.Contains("Link"))
                {
                    body += "var $outer_arguments = arguments;\r\n";
                    body += "$obdef.link = function(_scope) { \r\n";

                    // save isolated scope bindings that would be overwritten by constructor initialization
                    foreach (ScopeBindings sb in def.ScopeAttributes)
                    {
                        body += String.Format("var $$saved_{0} = _scope.{0};\r\n", sb.AttributeName);
                    }

                    foreach (string funcname in fnames)
                    {
                        body += String.Format("   _scope.{1} = {0}.prototype.{1}.bind(_scope);\r\n", type.FullName, funcname);
                    }

                    body += String.Format("   {0}.apply(_scope,$outer_arguments);\r\n", type.FullName);

                    // retrieves back saved isolated scope bindings
                    foreach (ScopeBindings sb in def.ScopeAttributes)
                    {
                        body += String.Format("_scope.{0} = $$saved_{0};\r\n", sb.AttributeName);
                    }

                    body += "   _scope.Link.apply(_scope,arguments);\r\n";
                    body += "}\r\n";
                }
                else
                {
                    throw new Exception("Link() method not defined in directive controller");
                }
            }

            if (SharedController != null)
            {
                body += "$obdef.controller = " + SharedController.ToString() + ";";
            }

            body += "return $obdef;\r\n";

            return(TypeExtensionMethods.CreateNewFunction(parameters, body));
        }