public ActionResult Index(string csharp, TranslateOptions options)
        {
            _log.Debug("Starting converting class with options: {0}, class to convert:\n{1}", options.ToFormattedJson(), csharp);

            var x = new NRefactoryCodeConvertion();
            var z = x.ToKnockoutVm(csharp, options);

            //var result = csharp.ToKnockout(options);

            _log.Debug("Returning converted class:\n{0}", z.ToFormattedJson());

            return Json(z, DefaultJsonSettings);
        }
        public string Write(VisitorResult result, TranslateOptions options = null)
        {
            if(result == null)
            {
                return null;
            }

            if(result.Types.Count == 0)
            {
                return null;
            }

            if(options == null)
            {
                options = TranslateOptions.Defaults;
            }

            _options = options;

            IEnumerable<VisitorResult.TypeResult> types = result.Types;

            if(_options.SortProps.IsTrue())
            {
                types = types.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase);
            }

            foreach(var type in types)
            {
                if(_options.IncludeEmptyType.IsFalse() && type.Elements.Count == 0)
                {
                    continue;
                }

                if(type.IsEnum)
                {
                    WriteEnumDeclaration(type);
                }
                else
                {
                    WriteClassDeclaration(type);
                }
            }

            var code = _console.ToString();

            // remove last line
            code = code.RemoveEmptyLastLine();

            return code;
        }
        public static object ToKnockout(this string @this, TranslateOptions options)
        {
            if(string.IsNullOrWhiteSpace(@this))
            {
                return new
                {
                    success = false,
                    message = "I see dead code - add some and try again"
                };
            }

            try
            {
                var result = new StringBuilder();
                var textReader = new StringReader(@this);
                var parser = new CSharpParser();
                var cu = parser.Parse(textReader, "dummy.cs");

                bool shouldExit;
                var errors = cu.GetErrors(out shouldExit);

                if(shouldExit)
                {
                    return new
                    {
                        success = false,
                        message = "Error parsning code file",
                        errors = errors
                    };
                }

                var types = cu.GetUsableTypes(options.IncludeEnums.Value);
                foreach(var type in types)
                {
                    if(type.ClassType == ClassType.Enum)
                    {
                        var enumMembers = type.GetEnums();
                        dynamic enumExpando = enumMembers.SetMembers(options.SortProps);
                        string enumSerialized = JsonConvert.SerializeObject(enumExpando, Formatting.Indented, options.ToJsonSettings());
                        result.AppendLine(enumSerialized.ToJsEnum(type.Name));
                    }
                    else
                    {
                        var members = type.GetProperties(options.PublicOnly.Value, options.PublicGetter.Value).ToList();

                        dynamic expando = members.SetMembers(options.SortProps);
                        string serialized = JsonConvert.SerializeObject(expando, Formatting.Indented, options.ToJsonSettings());
                        result.AppendLine(serialized.ToKnockoutViewModel(options, type.Name, expando as IDictionary<string, object>));
                    }
                }

                return new
                {
                    success = true,
                    message = result.ToString(),
                    errors = errors
                };
            }
            catch(Exception ex)
            {
                return new
                {
                    success = false,
                    message = ex.Message
                };
            }
        }
        public static string ToKnockoutViewModel(this string @this, TranslateOptions options, string name, IDictionary<string, object> orginal = null)
        {
            JObject o = JObject.Parse(@this);
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("var {0} = function (data) {{", name);
            sb.AppendLine();
            sb.AppendLine("\tvar self = this;");
            sb.AppendLine();
            sb.AppendLine("\tif (!data) {");
            sb.AppendLine("\t\tdata = { };");
            sb.AppendLine("\t}");
            sb.AppendLine();

            foreach(var item in o.Children())
            {
                var property = item.ToObject<JProperty>();
                string key = property.Name;

                if(orginal != null && options.CamelCase.Value && !options.ForceCamelCase.Value)
                {
                    var orginalKey = orginal
                        .Where(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase))
                        .Select(x => x.Key)
                        .FirstOrDefault();

                    if(orginalKey.IsNotNullOrEmpty())
                    {
                        key = orginalKey;
                    }
                }

                if(o[property.Name] is JArray)
                {
                    sb.AppendFormat("\tself.{0} = ko.observableArray(data.{1});", property.Name, key);

                }
                else
                {
                    sb.AppendFormat("\tself.{0} = ko.observable(data.{1});", property.Name, key);

                }
                sb.AppendLine();
            }

            sb.AppendLine("};");

            return sb.ToString();
        }