private static ElementDescriptor GetSubEditObject(this HtmlHelper html,
                                                          ActionContext targetActionContext,
                                                          ActionContext actionContext,
                                                          object subEditObject,
                                                          string propertyName) {
            var nakedObject = html.Facade().GetObject(subEditObject);

            Func<IAssociationFacade, bool> filterCollections = x => !x.IsCollection;

            TagBuilder elementSet = AddClassAndIdToElementSet(html.EditObjectFields(nakedObject, null, filterCollections, null, true),
                IdConstants.FieldContainerName,
                html.IdHelper().GetFieldContainerId((nakedObject)));
            html.AddAjaxDataUrlsToElementSet(nakedObject, elementSet);

            return new ElementDescriptor {
                TagType = "div",
                Value = html.Object(html.ObjectTitle(nakedObject.Object).ToString(), IdConstants.ViewAction, nakedObject.GetDomainObject()).ToString()
                        + elementSet
                        + GetSubmitButton(IdConstants.SaveButtonClass,
                            MvcUi.Save,
                            IdConstants.InvokeSaveAction,
                            html.GetButtonNameValues(targetActionContext, actionContext, nakedObject, propertyName)),
                Attributes = new RouteValueDictionary(new {
                    @class = html.ObjectEditClass(nakedObject.GetDomainObject()),
                    id = GetObjectType(nakedObject.GetDomainObject())
                })
            };
        }
        private static string GetEditValue(this HtmlHelper html,
                                           PropertyContext propertyContext,
                                           IList<ElementDescriptor> childElements,
                                           bool addToThis,
                                           bool noFinder) {
            string tooltip = propertyContext.Property.Description;
            string id = propertyContext.GetFieldInputId();
            if (propertyContext.Property.IsCollection) {
                propertyContext.IsPropertyEdit = false;
                return html.GetChildCollection(propertyContext);
            }
            var consent = propertyContext.Property.IsUsable(propertyContext.Target);
            if (consent.IsVetoed && !propertyContext.Target.IsTransient) {
                propertyContext.IsPropertyEdit = false;
                return html.GetViewField(propertyContext, consent.Reason);
            }

            bool readOnly = consent.IsVetoed && propertyContext.Target.IsTransient;

            // for the moment do not allow file properties to be edited 
            if (propertyContext.Property.Specification.IsFileAttachment) {
                // return html.GetFileProperty(propertyContext, id, tooltip);
                readOnly = true;
            }

            if (propertyContext.Property.Specification.IsParseable) {
                return html.GetTextField(propertyContext, id, tooltip, readOnly);
            }

            if (propertyContext.Property.IsInline) {
                var inlineNakedObject = propertyContext.GetValue(html.Facade());
                TagBuilder elementSet = ElementDescriptor.BuildElementSet(html.EditObjectFields(inlineNakedObject, propertyContext, x => true, null, true));
                html.AddAjaxDataUrlsToElementSet(inlineNakedObject, elementSet, propertyContext);

                return elementSet.ToString();
            }

            return html.GetReferenceField(propertyContext, id, tooltip, childElements, addToThis, readOnly, noFinder);
        }
        private static ElementDescriptor GetActionDialog(this HtmlHelper html,
                                                         ActionContext targetActionContext,
                                                         ActionContext actionContext,
                                                         IList<ElementDescriptor> paramElements,
                                                         string propertyName) {
            if (!paramElements.Any()) {
                return null;
            }

            var nameTag = new TagBuilder("div");
            nameTag.AddCssClass(IdConstants.ActionNameLabel);
            nameTag.SetInnerText(targetActionContext.Action.Name);

            TagBuilder parms = ElementDescriptor.BuildElementSet(paramElements);
            parms.AddCssClass(IdConstants.ParamContainerName);

            html.AddAjaxDataUrlsToElementSet(targetActionContext.Target, targetActionContext.Action, parms);

            return new ElementDescriptor {
                TagType = "div",
                Value = nameTag.ToString() + parms + GetSubmitButton(IdConstants.OkButtonClass,
                    MvcUi.OK,
                    IdConstants.InvokeFindAction,
                    html.GetButtonNameValues(targetActionContext, actionContext, null, propertyName)),
                Attributes = new RouteValueDictionary(new {
                    @class = IdConstants.ActionDialogName,
                    id = targetActionContext.GetActionDialogId()
                })
            };
        }
        private static string GetTextOrRefFieldValue(this HtmlHelper html, PropertyContext propertyContext, IObjectFacade valueNakedObject, bool inTable = false) {
            if (valueNakedObject.Specification.IsCollection) {
                valueNakedObject.Resolve();
            }

            string link = "{0}";

            if (!propertyContext.Property.Specification.IsParseable && !propertyContext.Property.IsCollection) {
                string displayType = html.ViewData.ContainsKey(propertyContext.GetFieldId()) ? (string)html.ViewData[propertyContext.GetFieldId()] : String.Empty;
                bool renderEagerly = RenderEagerly(propertyContext.Property);

                link = html.ObjectLink(link, IdConstants.ViewAction, valueNakedObject.Object) + (inTable ? "" : html.GetObjectDisplayLinks(propertyContext));

                if (displayType == IdConstants.MaxDisplayFormat || renderEagerly) {
                    var inlineNakedObject = propertyContext.GetValue(html.Facade());
                    bool anyEditableFields;
                    TagBuilder elementSet = ElementDescriptor.BuildElementSet(html.ViewObjectFields(inlineNakedObject, propertyContext, x => true, null, out anyEditableFields));

                    html.AddAjaxDataUrlsToElementSet(inlineNakedObject, elementSet, propertyContext);
                    elementSet.AddCssClass(IdConstants.FieldContainerName);
                    elementSet.GenerateId(html.IdHelper().GetFieldContainerId(inlineNakedObject));

                    link = link + html.GetEditButtonIfRequired(anyEditableFields, inlineNakedObject) + elementSet;
                }
            }

            string title = html.GetDisplayTitle(propertyContext.Property, valueNakedObject);

            if (propertyContext.Property.NumberOfLines > 1) {
                int typicalLength = propertyContext.Property.TypicalLength;
                int width = propertyContext.Property.Width;

                typicalLength = typicalLength == 0 ? 20 : typicalLength;
                width = width == 0 ? typicalLength : width;

                if (inTable) {
                    // truncate to width 
                    if (title.Length > width) {
                        const string elipsis = "...";
                        int length = width - elipsis.Length;
                        title = title.Substring(0, length > 0 ? length : 1) + elipsis;
                    }
                }
            }

            return String.Format(link, title);
        }