static string BuildSetterEnd(PropertyBinding.PropertyPath ppath)
    {
        if (ppath.Parts.Length == 1)
        {
            return(string.Format("        (({0})obj).{1} = ({2})value;",
                                 GetFullName(ppath.PPath[0].DeclaringType),
                                 ppath.Parts[0],
                                 GetFullName(ppath.PPath[0].PropertyType)));
        }

        var sb = new StringBuilder();

        sb.AppendFormat("        var v0 = (({0})obj).{1};", GetFullName(ppath.PPath[0].DeclaringType), ppath.Parts[0])
        .AppendLine();

        var i = 1;

        for (; i < ppath.Parts.Length - 1; i++)
        {
            sb.AppendFormat("        var v{0} = v{1}.{2}", i, i - 1, ppath.Parts[i])
            .AppendLine()
            .AppendFormat("        if (v{0} == null) return;", i)
            .AppendLine();
        }

        sb.AppendFormat("        v{0}.{1} = ({2})value;", i - 1, ppath.Parts[i], GetFullName(ppath.PPath.Last().PropertyType));

        return(sb.ToString());
    }
    private static void BuildPath(SerializedProperty prop, StringBuilder sw)
    {
        SerializedProperty cprop;
        SerializedProperty pprop;

        ComponentPathDrawer.GetCPathProperties(prop, out cprop, out pprop);

        var oval = cprop.objectReferenceValue;

        if (oval == null)
        {
            return;
        }

        var ppath = new PropertyBinding.PropertyPath(pprop.stringValue, oval.GetType());

        if (!ppath.IsValid)
        {
            return;
        }

        if (_paths.Contains(ppath.PPath))
        {
            return;
        }
        _paths.Add(ppath.PPath);

        sw.AppendFormat(@"  ppa.Register(
    new[]
    {{
{0}
    }},
    obj => 
    {{
        if(obj == null) return null; 
        var v0 = (({1})obj).{2};
{3}
    }},
    (obj, value) =>
    {{
{4}
    }});",
                        string.Join(",\r\n", ppath.PPath.Select(p =>
                                                                string.Format("        PropertyBinding.PropertyPath.GetProperty(typeof({0}), \"{1}\")",
                                                                              GetFullName(p.DeclaringType),
                                                                              p.Name))
                                    .ToArray()),
                        GetFullName(ppath.PPath[0].DeclaringType),
                        ppath.Parts[0],
                        BuildGetterEnd(ppath),
                        BuildSetterEnd(ppath))
        .AppendLine().AppendLine();
    }
    static string BuildGetterEnd(PropertyBinding.PropertyPath ppath)
    {
        if (ppath.Parts.Length == 1)
        {
            return(string.Format("        return v0;"));
        }

        var sb = new StringBuilder();
        var i  = 1;

        for (; i < ppath.Parts.Length - 1; i++)
        {
            sb.AppendFormat("        var v{0} = v{1}.{2}", i, i - 1, ppath.Parts[i])
            .AppendLine()
            .AppendFormat("        if (v{0} == null) return null;", i)
            .AppendLine();
        }

        sb.AppendFormat("        return v{0}.{1};", i - 1, ppath.Parts[i]);

        return(sb.ToString());
    }