Example #1
0
        public ValidationResult <EmailReportRequest> Validate(EmailReportRequest request)
        {
            var result = new ValidationResult <EmailReportRequest>(request);

            if (request == null)
            {
                result.AddMessage("Request cannot be null");
            }
            else
            {
                if (request.ClubId.IsEmpty())
                {
                    result.AddMessage("ClubId cannot be null");
                }

                if (request.EventId.IsEmpty())
                {
                    result.AddMessage("EventId cannot be null");
                }

                if (request.EmailAddresses == null || !request.EmailAddresses.Any())
                {
                    result.AddMessage($"At least one recipient (player, email address or send me a copy) must be specified.");
                }

                foreach (var email in request.EmailAddresses)
                {
                    if (!email.IsEmpty() && !email.IsValidEmail())
                    {
                        result.AddMessage($"{email} is not a valid email");
                    }
                }
            }
            return(result);
        }
Example #2
0
        private void MultipleMessages()
        {
            ValidationResult result = new ValidationResult();

            result.AddMessage(MessageType.Error, "abd-fds", "asdf.asdfe.werk");
            result.AddMessage(MessageType.Warning, "ieow.se3", "iwer.asdfwerk.asdf");
            Assert.False(result.IsValid);
            Assert.True(result.HasMessages);
            Assert.True(result.HasWarnings);
            Assert.True(result.HasErrors);

            List <ValidationMessage> messages = result.ValidationMessages;

            Assert.NotNull(messages);
            Assert.Equal(2, messages.Count);

            Assert.Equal(MessageType.Error, messages[0].Type);
            Assert.Equal("abd-fds", messages[0].Field);
            Assert.Equal("asdf.asdfe.werk", messages[0].MessageKey);
            Assert.Null(messages[0].MessageParameters);

            Assert.Equal(MessageType.Warning, messages[1].Type);
            Assert.Equal("ieow.se3", messages[1].Field);
            Assert.Equal("iwer.asdfwerk.asdf", messages[1].MessageKey);
            Assert.Null(messages[1].MessageParameters);
        }
Example #3
0
        public ValidationResult Validate(Product product, bool requireUniqueSku)
        {
            var result = new ValidationResult();

            if (string.IsNullOrWhiteSpace(product.Sku))
            {
                result.AddMessage(nameof(product.Sku), "Product SKU is Required");
            }

            if (string.IsNullOrWhiteSpace(product.Name))
            {
                result.AddMessage(nameof(product.Name), "Product Name is Required");
            }

            if (product.Price < decimal.Zero)
            {
                result.AddMessage(nameof(product.Price), $"Product {nameof(product.Price)} must be greater then or equal to zero");
            }

            if (!requireUniqueSku)
            {
                return(result);
            }

            var unique = IsSkuUnique(product.Sku);

            if (!unique)
            {
                result.AddMessage(nameof(product.Sku), "Product SKU must be Unique");
            }

            return(result);
        }
Example #4
0
        public ValidationResult <NewEventReviewRequest> Validate(NewEventReviewRequest request)
        {
            var validationResult = new ValidationResult <NewEventReviewRequest>(request);

            if (request == null)
            {
                validationResult.AddMessage("Request cannot be null");
                return(validationResult);
            }

            if (request.ClubId.IsEmpty())
            {
                validationResult.AddMessage("ClubId cannot be empty");
            }

            if (request.CoachId.IsEmpty())
            {
                validationResult.AddMessage("CoachId cannot be empty");
            }

            if (request.EventId.IsEmpty())
            {
                validationResult.AddMessage("EventId cannot be empty");
            }

            if (request.DifferentNextTime.IsEmpty() && request.Opportunities.IsEmpty() && request.Successes.IsEmpty())
            {
                validationResult.AddMessage("No review meesage has been provided");
            }

            return(validationResult);
        }
        public ValidationResult <EventFeedbackRequest> Validate(EventFeedbackRequest request)
        {
            var result = new ValidationResult <EventFeedbackRequest>(request);

            if (request.SquadId.IsEmpty())
            {
                result.AddMessage("Squad Id cannot be empty");
            }

            if (request.ClubId.IsEmpty())
            {
                result.AddMessage("Club Id cannot be empty");
            }

            if (request.EventId.IsEmpty())
            {
                result.AddMessage("Event Id cannot be empty");
            }

            if (request.PlayerId.IsEmpty())
            {
                result.AddMessage("Player Id cannot be empty");
            }

            return(result);
        }
        public ValidationResult <NewAvailabilityRequest> Validate(NewAvailabilityRequest request)
        {
            var validationResult = new ValidationResult <NewAvailabilityRequest>(request);

            if (request == null)
            {
                validationResult.AddMessage("Request cannot be null");
                return(validationResult);
            }

            if (request.ClubId.IsEmpty())
            {
                validationResult.AddMessage("ClubId cannot be empty");
            }

            if (request.PlayerId.IsEmpty())
            {
                validationResult.AddMessage("PlayerId cannot be empty");
            }

            if (request.DateFrom <= DateTime.Today.AddDays(-30) || request.DateFrom >= DateTime.Today.AddMonths(3))
            {
                validationResult.AddMessage($"Date From must be between {DateTime.Today.AddDays(-30).ToString("dd MMM yyyy")} and {DateTime.Today.AddMonths(3).ToString("dd MMM yyyy")}");
            }

            if (request.DateTo.HasValue && (request.DateTo.Value < request.DateFrom))
            {
                validationResult.AddMessage("DateTo must be greater or equal to DateFrom");
            }

            return(validationResult);
        }
        public ValidationResult <TrainingMaterialRequest> Validate(TrainingMaterialRequest request)
        {
            var validationResult = new ValidationResult <TrainingMaterialRequest>(request);

            if (request == null)
            {
                validationResult.AddMessage("Request cannot be null");
                return(validationResult);
            }

            if (request.ClubId.IsEmpty())
            {
                validationResult.AddMessage("ClubId cannot be null");
            }

            if (request.Title.IsEmpty())
            {
                validationResult.AddMessage("Title cannot be null");
            }

            if (request.Description.IsEmpty())
            {
                validationResult.AddMessage("Description cannot be null");
            }


            return(validationResult);
        }
        /// <summary>
        /// basic validation rules which are always the same
        /// </summary>
        public ValidationResult Validate(ConfigSource source)
        {
            var result = new ValidationResult(source);

            if (source.Hoster != this.HosterName)
            {
                result.AddMessage(ErrorLevel.Error, string.Format(Resource.WrongHoster, source.Hoster));
            }

            if (source.Type != "user" && source.Type != "org")
            {
                result.AddMessage(ErrorLevel.Error, string.Format(Resource.WrongType, source.Type));
            }

            if (string.IsNullOrWhiteSpace(source.Name))
            {
                result.AddMessage(ErrorLevel.Error, Resource.NameEmpty);
            }

            bool authNameEmpty = string.IsNullOrWhiteSpace(source.AuthName);
            bool passwordEmpty = string.IsNullOrWhiteSpace(source.Password);

            if (authNameEmpty != passwordEmpty)
            {
                result.AddMessage(ErrorLevel.Error, Resource.AuthNameOrPasswortEmpty);
            }
            else if (authNameEmpty && passwordEmpty)
            {
                result.AddMessage(ErrorLevel.Warn, Resource.AuthNameAndPasswortEmpty);
            }

            this.ValidateSpecific(result, source);

            return(result);
        }
Example #9
0
 protected override void ActionForLinkedParameterIsNotInSimulation(ParameterIdentification parameterIdentification, ISimulation newSimulation, ParameterSelection linkedParameter, IdentificationParameter identificationParameter)
 {
     _validationResult.AddMessage(
         NotificationType.Warning,
         parameterIdentification,
         Captions.ParameterIdentification.SimulationDoesNotContainParameterWithPath(newSimulation.Name, linkedParameter.Path));
 }
        protected override void Context()
        {
            base.Context();

            _validationResult = new ValidationResult();
            _validationResult.AddMessage(NotificationType.Error, A.Fake <IObjectBase>().WithId("1"), string.Empty);
            _validationResult.AddMessage(NotificationType.Warning, A.Fake <IObjectBase>().WithId("2"), string.Empty);
        }
        protected override void Context()
        {
            base.Context();
            _userSettings.ShowPKSimObserverMessages = false;
            _validationResult = new ValidationResult();

            var staticObserver  = A.Fake <IObserverBuilder>().WithId("1").WithName(AppConstants.DefaultNames.PKSimStaticObservers[0]);
            var dynamicObserver = A.Fake <IObserverBuilder>().WithId("2").WithName($"{AppConstants.DefaultNames.PKSimDynamicObservers[0]}-HELLO");

            _validationResult.AddMessage(NotificationType.Error, staticObserver, string.Empty);
            _validationResult.AddMessage(NotificationType.Error, dynamicObserver, string.Empty);
            _validationResult.AddMessage(NotificationType.Warning, A.Fake <IObjectBase>().WithId("2"), string.Empty);
        }
Example #12
0
        protected ValidationResult ValidateBase()
        {
            var result = new ValidationResult();

            if (!ValidateName())
            {
                result.AddMessage(ProductValidationMessages.NAME);
            }
            if (!ValidatePrice())
            {
                result.AddMessage(ProductValidationMessages.PRICE);
            }
            return(result);
        }
Example #13
0
        public async Task <ValidationResult> Validate(UpdateAnswerCommand command)
        {
            var result = new ValidationResult();

            if (string.IsNullOrEmpty(command.Name))
            {
                result.AddMessage(AnswerValidationMessages.NAME);
            }
            else if (await _repository.VerifyExistence(command.Name, command.Id))
            {
                result.AddMessage(AnswerValidationMessages.NAME_EXISTS);
            }

            return(result);
        }
 protected override void ActionForMissingSensitivityParameterPaths(SensitivityAnalysis sensitivityAnalysis, ISimulation newSimulation, SensitivityParameter sensitivityParameter)
 {
     _validationResult.AddMessage(
         NotificationType.Warning,
         sensitivityAnalysis,
         Error.SensitivityAnalysis.SimulationDoesNotHaveParameterPath(newSimulation.Name, sensitivityParameter.ParameterSelection.Path));
 }
Example #15
0
        /// <summary>
        /// Convert an flow document list into its html representation.
        /// </summary>
        /// <param name="list">Flow document list.</param>
        /// <param name="htmlWriter">XmlTextWriter producing resulting html.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        private static void AddList(List list, XmlTextWriter htmlWriter, ValidationResult conversionResult)
        {
            if (list.MarkerStyle == System.Windows.TextMarkerStyle.Disc)
            {
                htmlWriter.WriteStartElement("ul");
            }
            else if (list.MarkerStyle == System.Windows.TextMarkerStyle.Decimal)
            {
                htmlWriter.WriteStartElement("ol");
            }
            else
            {
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Error, "Unknown list marker style: " + list.MarkerStyle.ToString()));
                }
                return;
            }

            // process list items
            foreach (ListItem item in list.ListItems)
            {
                htmlWriter.WriteStartElement("li");

                // process blocks
                foreach (Block block in item.Blocks)
                {
                    AddBlock(block, htmlWriter, conversionResult);
                }

                htmlWriter.WriteEndElement();
            }

            htmlWriter.WriteEndElement();
        }
Example #16
0
        public ValidationResult <DashboardRequest> Validate(DashboardRequest request)
        {
            var result = new ValidationResult <DashboardRequest>(request);

            if (request.UserEmail.IsEmpty() || !request.UserEmail.IsValidEmail())
            {
                result.AddMessage("User's email is not valid");
            }

            if (request.ClubId.IsEmpty())
            {
                result.AddMessage("Club Id is not valid");
            }

            return(result);
        }
Example #17
0
 public ValidationResult Validate(Guid id)
 {
     if (id.Equals(Guid.Empty))
     {
         result.AddMessage(ProductValidationMessages.ID);
     }
     return(result);
 }
Example #18
0
        public ValidationResult <PlayerRequest> Validate(PlayerRequest request)
        {
            var result = new ValidationResult <PlayerRequest>(request);

            if (request.SquadId.IsEmpty())
            {
                result.AddMessage("Squad Id cannot be empty");
            }

            if (request.FirstName.IsEmpty())
            {
                result.AddMessage("First Name cannot be empty");
            }

            if (request.LastName.IsEmpty())
            {
                result.AddMessage("Last Name cannot be empty");
            }

            if (request.Email.IsEmpty() || !request.Email.IsValidEmail())
            {
                result.AddMessage("Email is not valid");
            }

            if (request.DominantFoot.IsEmpty())
            {
                result.AddMessage("Dominant foot cannot be empty");
            }
            else if (!char.ToUpperInvariant(request.DominantFoot).Equals('R') &&
                     !char.ToUpperInvariant(request.DominantFoot).Equals('L'))
            {
                result.AddMessage("Dominant foot can be \"R\" (right) or \"L\" (left) only");
            }

            if (request.Nationality.IsEmpty())
            {
                result.AddMessage("Nationality cannot be empty");
            }

            if (!request.DateOfBirth.HasValue)
            {
                result.AddMessage("Date of Birth cannot be empty");
            }
            else if (request.DateOfBirth.Value > DateTime.Now)
            {
                result.AddMessage("Date of Birth cannot be in the future");
            }

            return(result);
        }
 public static ValidationResult GetResult(this global::FluentValidation.Results.ValidationResult result)
 {
     var finalResult = new ValidationResult();
     foreach (var message in result.Errors)
     {
         finalResult.AddMessage(message.PropertyName, message.ErrorMessage, Convert(message.Severity));
     }
     return finalResult;
 }
        protected override void Context()
        {
            base.Context();
            var validationResult = new ValidationResult();

            validationResult.AddMessage(NotificationType.Error, A.Fake <IObjectBase>(), "TOTO");
            sut.Handle(new ShowValidationResultsEvent(validationResult));
            sut.Handle(new FormulaInvalidEvent(A.Fake <IFormula>().WithId("INVALID"), _buildingBlock, "INVALID_MESSAGE"));
        }
Example #21
0
 protected override void Context()
 {
     base.Context();
     _newSimulation = A.Fake <ISimulation>();
     sut.EditSensitivityAnalysis(_sensitivityAnalysis);
     _validationResults = new ValidationResult();
     _validationResults.AddMessage(NotificationType.Warning, _sensitivityAnalysis, "Warning");
     A.CallTo(_sensitivityAnalysisTask).WithReturnType <ValidationResult>().Returns(_validationResults);
 }
 protected override void Context()
 {
     base.Context();
     _invalidObject    = A.Fake <IObjectBase>();
     _validationResult = new ValidationResult();
     _validationResult.AddMessage(NotificationType.Error, _invalidObject, "Object Invald", details: new [] { "Detail1", "Detail2" });
     sut = new ValidationResult();
     sut.AddMessage(NotificationType.Warning, _invalidObject, "Warning");
 }
        private void validateWeights(ParameterIdentification parameterIdentification, ValidationResult validationResult)
        {
            var allDataRepositoryWeights = allWeightedDataRepositoryWeights(parameterIdentification);
            var allPointWeights          = allDataPointWeights(parameterIdentification);

            if (allDataRepositoryWeights.Union(allPointWeights).Any(weight => weight < 0))
            {
                validationResult.AddMessage(NotificationType.Error, parameterIdentification, Error.WeightValueCannotBeNegative);
            }
        }
        public ValidationResult Validate(RemoveAnswerCommand command)
        {
            var result = new ValidationResult();

            if (!ValidateId(command.Id))
            {
                result.AddMessage(AnswerValidationMessages.ID);
            }
            return(result);
        }
        public ValidationResult Validate(StartQuizCommand command)
        {
            var result = new ValidationResult();

            if (string.IsNullOrEmpty(command.UserName))
            {
                result.AddMessage(QuizValidationMessages.NAME);
            }

            return(result);
        }
        private void addNotification(NotificationType notificationType, IObjectBase entityToValidate, string notification)
        {
            var builder = _buildConfiguration.BuilderFor(entityToValidate);

            if (!shouldShowNotification(entityToValidate, notification))
            {
                return;
            }

            _result.AddMessage(notificationType, builder, notification);
        }
        public ValidationResult Validate(FinishQuizCommand command)
        {
            var result = new ValidationResult();

            if (string.IsNullOrEmpty(command.UserName))
            {
                result.AddMessage(QuizValidationMessages.NAME);
            }

            if (!command.Answers.Any())
            {
                result.AddMessage(QuizValidationMessages.NO_ANSWERS);
            }
            if (command.Answers.Any(answer => answer.AnswerId == null || answer.AnswerId.Equals(Guid.Empty)))
            {
                result.AddMessage(QuizValidationMessages.ANSWER);
            }

            return(result);
        }
Example #28
0
        public ValidationResult Validate(Brand brand)
        {
            var result = new ValidationResult();

            if (string.IsNullOrWhiteSpace(brand.Name))
            {
                result.AddMessage(nameof(brand.Name), $"{nameof(brand.Name)} is Required");
            }

            return(result);
        }
Example #29
0
        protected override void Context()
        {
            base.Context();
            _validationResult    = new ValidationResult();
            _sensitivityAnalysis = new SensitivityAnalysis();
            _oldSimulation       = A.Fake <ISimulation>();
            _newSimulation       = A.Fake <ISimulation>();
            _validationResult.AddMessage(NotificationType.Warning, _sensitivityAnalysis, "this is text");

            A.CallTo(() => _sensitivityAnalysisSwapValidator.ValidateSwap(_sensitivityAnalysis, _oldSimulation, _newSimulation)).Returns(_validationResult);
        }
Example #30
0
 private void validateBuildingBlockWithFormulaCache(IBuildingBlock buildingBlockWithFormulaCache, ValidationResult validationResult)
 {
     foreach (var formula in buildingBlockWithFormulaCache.FormulaCache.Where(f => f.IsExplicit()).Cast <ExplicitFormula>())
     {
         var(valid, message) = formula.IsValid();
         if (!valid)
         {
             validationResult.AddMessage(NotificationType.Error, formula, Validation.FormulaIsNotValid(formula.Name, buildingBlockWithFormulaCache.Name, message), buildingBlockWithFormulaCache);
         }
     }
 }
        static void Main(string[] args)
        {
            ValidationResult result = new ValidationResult();
            result.AddMessage(
                new ValidationMessage
                {
                    Severity = SeverityType.Error,
                    Message = "Sample error message 1."
                }).AddMessage(
                new ValidationMessage
                {
                    Severity = SeverityType.Error,
                    Message = "Sample error message 2."
                });

            ValidationResult deepClone = result.DeepClone();
            ValidationResult shallowClone = result.ShallowClone();;
        }
        /// <summary>
        /// Converts an flow document to html string.
        /// </summary>
        /// <param name="flowDocument">Flow document.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <returns>
        /// Well-formed xml string representing html equivalent for the input flow document.
        /// </returns>
        public static string ConvertXamlToHtml(FlowDocument flowDocument, ValidationResult conversionResult)
        {
            StringBuilder htmlStringBuilder = new StringBuilder();
            System.IO.StringWriter stringWriter = null;
            try
            {
                stringWriter = new System.IO.StringWriter(htmlStringBuilder);
                using (XmlTextWriter htmlWriter = new XmlTextWriter(stringWriter))
                {
                    try
                    {
                        foreach (Block block in flowDocument.Blocks)
                        {
                            AddBlock(block, htmlWriter, conversionResult);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (conversionResult != null)
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Error, "Conversion failed: " + ex.Message));
                    }
                    finally
                    {
                        stringWriter = null;
                    }
                }
            }
            finally
            {
                if (stringWriter != null)
                    stringWriter.Dispose();
            }

            string htmlString = htmlStringBuilder.ToString();
            return htmlString;
        }
        /// <summary>
        /// Parses the html margin attribute given as a string.
        /// </summary>
        /// <param name="margin">Html margin attribute value.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <returns>
        /// Returns the corresponding xaml margin value as a string. 
        /// Should the given value not be recognized, the default value ('0') is returned.</returns>
        private static string ParseMarginValue(string margin, ValidationResult conversionResult)
        {
            string marginValue = margin.ToLower();
            if (String.IsNullOrEmpty(marginValue))
            {
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                        "ParseMargin: Unknown value: " + margin));
                }
            }
            else
            {
                int result;
                if (Int32.TryParse(marginValue, out result))
                {
                    return result.ToString();
                }
                else
                {
                    if (conversionResult != null)
                    {
                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                            "ParseMargin: Value is not a number: " + margin));
                    }
                }
            }

            return "0";
        }
        /// <summary>
        /// Adds an image.
        /// </summary>
        /// <param name="xamlParentElement">XmlElement representing Xaml parent to which the converted element should be added</param>
        /// <param name="htmlElement">Source html element subject to convert to xaml.</param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddImage(XmlElement xamlParentElement, HtmlNode htmlElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            // Very simple processing for now
            bool bFoundImage = false;

            XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Image, HtmlToXamlConverter.Xaml_Namespace_Tum_VMX_Types);
            string src = GetAttribute(htmlElement, "src");
            if (src != null)
            {
                string filePath = vModellDirectory + "\\" + src;
                if (System.IO.File.Exists(filePath))
                {
                    try
                    {
                        // try to load image
                        System.Windows.Controls.Image image = new System.Windows.Controls.Image();
                        BitmapImage bimg = new BitmapImage();
                        bimg.BeginInit();
                        bimg.UriSource = new Uri(filePath, UriKind.Absolute);
                        bimg.EndInit();
                        image.Source = bimg;

                        string width = GetAttribute(htmlElement, "width");
                        string height = GetAttribute(htmlElement, "height");

                        if (width != null && height != null)
                        {
                            xamlElement.SetAttribute("MaxWidth", width);
                            xamlElement.SetAttribute("MaxHeight", height);
                        }
                        xamlElement.SetAttribute("Stretch", "Uniform");

                        XmlElement source = xamlElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Image_Source, HtmlToXamlConverter.Xaml_Namespace_Tum_VMX_Types);
                        XmlElement bmp = source.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Image_BitmapImage, HtmlToXamlConverter.Xaml_Namespace);
                        bmp.SetAttribute(HtmlToXamlConverter.Xaml_UriSource, filePath);
                        source.AppendChild(bmp);
                        xamlElement.AppendChild(source);

                        bFoundImage = true;
                    }
                    catch { }
                }
            }

            if (!bFoundImage)
            {
                xamlElement.SetAttribute("Source", "pack://application:,,,/Tum.PDE.ToolFramework.Images;component/Ribbon/Save-32.png");
                xamlElement.SetAttribute("Width", "32");
                xamlElement.SetAttribute("Height", "32");
            }

            foreach (HtmlAttribute attribute in htmlElement.Attributes)
            {
                string name = attribute.Name.ToLower();
                switch (name)
                {
                    case "align":
                        xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_HorizontalAlignment, attribute.Value);
                        break;

                    case "alt":
                        xamlElement.SetAttribute("AlternativeText", attribute.Value);
                        break;

                    case "id":
                        xamlElement.SetAttribute("Id", attribute.Value);
                        break;

                    case "src":
                        xamlElement.SetAttribute("RelativeSource", attribute.Value);
                        break;

                    case "width":
                        xamlElement.SetAttribute("ExportWidth", attribute.Value);
                        break;

                    case "height":
                        xamlElement.SetAttribute("ExportHeight", attribute.Value);
                        break;

                    default:
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddImage: Unknown attribute on img: " + name));
                        }
                        break;
                }
            }

            // Add the new element to the parent.
            xamlParentElement.AppendChild(xamlElement);
        }
        /// <summary>
        /// Parses the html align attribute given as a string.
        /// </summary>
        /// <param name="alignment">Html align attribute value.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <returns>
        /// Returns the corresponding xaml alignment value as a string. 
        /// Should the given value not be recognized, the default value ('Left') is returned.</returns>
        public static string ParseTextAlignment(string alignment, ValidationResult conversionResult)
        {
            string alignmentValue = alignment.ToLower();
            switch (alignmentValue)
            {
                case "left":
                    return "Left";

                case "right":
                    return "Right";

                case "center":
                    return "Center";

                case "justify":
                    return "Justify";

                default:
                    if (conversionResult != null)
                    {
                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                            "ParseTextAlignment: Unknown value: " + alignment));
                    }
                    return "Left";
            }
        }
        /// <summary>
        /// Adds TableCell elements to xamlTableRowElement.
        /// </summary>
        /// <param name="xamlTableRowElement">XmlElement representing Xaml TableRow element to which the converted cells should be added.</param>
        /// <param name="htmlTDStartNode">XmlElement representing the child of tr element from which we should start adding td elements. </param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        /// <param name="inheritedProperties">Inherited properties.</param>
        /// <returns>
        /// XmlElement representing the current position of the iterator among the children of the parent Html tbody/tr element
        /// </returns>
        private static HtmlNode AddTableCellsToTableRow(XmlElement xamlTableRowElement, HtmlNode htmlTDStartNode, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory, Hashtable inheritedProperties)
        {
            System.Diagnostics.Debug.Assert(xamlTableRowElement.LocalName == Xaml_TableRow);
            HtmlNode htmlChildNode = htmlTDStartNode;

            while (htmlChildNode != null && htmlChildNode.Name.ToLower() != "tr")
            {
                if (htmlChildNode.Name.ToLower() == "td")
                {
                    XmlElement xamlTableCellElement = xamlTableRowElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_TableCell, HtmlToXamlConverter.Xaml_Namespace);
                    sourceContext.Add(htmlChildNode);

                    // We do not support any attributes on td items
                    foreach (HtmlAttribute attribute in htmlChildNode.Attributes)
                    {
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTableCellsToTableRow: Unknown attribute " + attribute.Name + ":" + attribute.Value + " on td: " + htmlChildNode.Name));
                        }
                    }
                    foreach (object key in inheritedProperties.Keys)
                        if (key.ToString() == "border")
                        {
                            xamlTableCellElement.SetAttribute(Xaml_BorderThickness, ParseBorderThickness(inheritedProperties[key].ToString(), conversionResult));
                            xamlTableCellElement.SetAttribute(Xaml_BorderBrush, "Black");
                        }

                    AddDataToTableCell(xamlTableCellElement, htmlChildNode.FirstChild, sourceContext, conversionResult, vModellDirectory);


                    //if (xamlTableCellElement.HasChildNodes)
                    //{
                    xamlTableRowElement.AppendChild(xamlTableCellElement);
                    //}                   

                    System.Diagnostics.Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode);
                    sourceContext.RemoveAt(sourceContext.Count - 1);

                    htmlChildNode = htmlChildNode.NextSibling;
                }
                else
                {
                    if (conversionResult != null)
                    {
                        if (String.IsNullOrWhiteSpace(htmlChildNode.InnerText) && htmlChildNode.NodeType == HtmlNodeType.Text)
                        {
                            // for some reason, there is always a white space behind the table/tr/td elements.. so dont react on that
                            // do we need a warning?
                        }
                        else
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTableCellsToTableRow: Unknown child: " + htmlChildNode.Name + ":" + htmlChildNode.OuterHtml));
                    }

                    htmlChildNode = htmlChildNode.NextSibling;
                }
            }
            return htmlChildNode;
        }
        /// <summary>
        /// Convert an flow document table into its html representation.
        /// </summary>
        /// <param name="table">Flow document table.</param>
        /// <param name="htmlWriter">XmlTextWriter producing resulting html.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        private static void AddTable(Table table, XmlTextWriter htmlWriter, ValidationResult conversionResult)
        {
            htmlWriter.WriteStartElement("table");

            /*
            if (table.BorderThickness.Left == table.BorderThickness.Right &&
                table.BorderThickness.Right == table.BorderThickness.Top &&
                table.BorderThickness.Top == table.BorderThickness.Bottom)
            {
                if (table.BorderThickness.Left != 0)
                    htmlWriter.WriteAttributeString("border", table.BorderThickness.Left.ToString());
            }
            */

            double border = 0.0;
            foreach (TableRowGroup group in table.RowGroups)
            {
                foreach (TableRow row in group.Rows)
                {
                    foreach (TableCell cell in row.Cells)
                    {
                        if (cell.BorderThickness.Left == cell.BorderThickness.Right &&
                           cell.BorderThickness.Right == cell.BorderThickness.Top &&
                           cell.BorderThickness.Top == cell.BorderThickness.Bottom)
                        {
                            border = cell.BorderThickness.Left;
                            break;
                        }
                    }

                    if (border > 0)
                        break;
                }
                if (border > 0)
                    break;
            }

            if (border > 0)
                // set border attribute
                htmlWriter.WriteAttributeString("border", border.ToString());

            foreach (TableRowGroup group in table.RowGroups)
            {
                foreach (TableRow row in group.Rows)
                {
                    // add tr
                    htmlWriter.WriteStartElement("tr");

                    foreach (TableCell cell in row.Cells)
                    {
                        if (cell.BorderThickness.Left == cell.BorderThickness.Right &&
                            cell.BorderThickness.Right == cell.BorderThickness.Top &&
                            cell.BorderThickness.Top == cell.BorderThickness.Bottom)
                        {
                            if (cell.BorderThickness.Left != 0)
                                if (border != cell.BorderThickness.Left)
                                {
                                    // error
                                    if (conversionResult != null)
                                    {
                                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                            "AddInline: All border values on table cells within one table need to be equal, ignoring newly found border value."));
                                    }
                                }
                        }

                        // add td
                        htmlWriter.WriteStartElement("td");

                        // process blocks
                        foreach (Block block in cell.Blocks)
                            AddBlock(block, htmlWriter, conversionResult);

                        htmlWriter.WriteEndElement();
                    }

                    htmlWriter.WriteEndElement();
                }
            }


            htmlWriter.WriteEndElement();
        }
        /// <summary>
        /// Convert an flow document inlines into their (combined!) html representation.
        /// </summary>
        /// <param name="inlines">Flow document inlines collection.</param>
        /// <param name="htmlWriter">XmlTextWriter producing resulting html.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="inheritedStyle">Inherited inline styles.</param>
        /// <remarks>
        /// Supported: Hyperlink, Bold, Underline, Italic as well as Run and InlineUIContainer for Image.
        /// </remarks>
        private static void AddInlines(InlineCollection inlines, XmlTextWriter htmlWriter, ValidationResult conversionResult, List<InlineStyles> inheritedStyle)
        {
            for (int i = 0; i < inlines.Count; ++i)
            {
                Inline inline = inlines.ElementAt(i);

                #region InheritedStyle + B,I,U processing
                bool bAddBold = false;
                bool bAddItalic = false;
                bool bAddUnderlined = false;

                // Bold
                if (inline.FontWeight != System.Windows.FontWeights.Bold && inheritedStyle.Contains(InlineStyles.Bold))
                {
                    // close last element tag
                    htmlWriter.WriteEndElement();
                    inheritedStyle.Remove(InlineStyles.Bold);
                }
                else if (!inheritedStyle.Contains(InlineStyles.Bold) && inline.FontWeight == System.Windows.FontWeights.Bold)
                    bAddBold = true;

                // Italic
                if (inline.FontStyle != System.Windows.FontStyles.Italic && inheritedStyle.Contains(InlineStyles.Italic))
                {
                    // close last element tag
                    htmlWriter.WriteEndElement();
                    inheritedStyle.Remove(InlineStyles.Italic);
                }
                else if (!inheritedStyle.Contains(InlineStyles.Italic) && inline.FontStyle == System.Windows.FontStyles.Italic)
                    bAddItalic = true;

                // Underline
                bool bHasUnderline = false;
                if (inline is Run && inline.Parent is Span)
                {
                    if ((inline.Parent as Span).TextDecorations.Contains(System.Windows.TextDecorations.Underline[0]))
                        bHasUnderline = true;
                }

                if (!inline.TextDecorations.Contains(System.Windows.TextDecorations.Underline[0]) && inheritedStyle.Contains(InlineStyles.Underlined))
                {
                    if (!bHasUnderline)
                    {
                        // close last element tag
                        htmlWriter.WriteEndElement();
                        inheritedStyle.Remove(InlineStyles.Underlined);
                    }
                }
                else if (!inheritedStyle.Contains(InlineStyles.Underlined) && inline.TextDecorations.Contains(System.Windows.TextDecorations.Underline[0]))
                    if (!bHasUnderline)
                        bAddUnderlined = true;

                if (inline is HtmlHyperlink)
                    bAddUnderlined = false;

                // see what needs to be added.. if multiple elements need to be added, than we have to iterate through
                // siblings to see what tag to set first (depending on what to close first).
                if (bAddUnderlined || bAddBold || bAddItalic)
                {
                    if (bAddBold && bAddItalic || bAddBold && bAddUnderlined || bAddItalic && bAddUnderlined)
                    {
                        InlineStylesCount stylesCount = InlineStylesCounter.Count(inlines, i + 1);

                        // see what has to be added first
                        // add tags
                        for (int z = 0; z < 3; ++z)
                        {
                            if (stylesCount.Order[z] == InlineStyles.Bold && bAddBold)
                            {
                                htmlWriter.WriteStartElement("b");
                                inheritedStyle.Add(InlineStyles.Bold);
                            }
                            else if (stylesCount.Order[z] == InlineStyles.Italic && bAddItalic)
                            {
                                htmlWriter.WriteStartElement("i");
                                inheritedStyle.Add(InlineStyles.Italic);
                            }
                            else if (stylesCount.Order[z] == InlineStyles.Underlined && bAddUnderlined)
                            {
                                htmlWriter.WriteStartElement("u");
                                inheritedStyle.Add(InlineStyles.Underlined);
                            }
                        }
                    }
                    else
                    {
                        // just add the tag of the needed style
                        if (bAddBold)
                        {
                            htmlWriter.WriteStartElement("b");
                            inheritedStyle.Add(InlineStyles.Bold);
                        }
                        else if (bAddItalic)
                        {
                            htmlWriter.WriteStartElement("i");
                            inheritedStyle.Add(InlineStyles.Italic);
                        }
                        else if (bAddUnderlined)
                        {
                            htmlWriter.WriteStartElement("u");
                            inheritedStyle.Add(InlineStyles.Underlined);
                        }
                    }
                }
                #endregion

                // continue with text or inlines
                if (inline is InlineUIContainer)
                {
                    InlineUIContainer container = inline as InlineUIContainer;
                    if (container.Child is HtmlImage)
                    {
                        // Add image
                        AddImage(container.Child as HtmlImage, htmlWriter, conversionResult);
                    }
                    else if (container.Child is System.Windows.Controls.TextBlock)
                    {
                        // Comment, just add text as is
                        string text = ExtendedHtmlUtility.HtmlEntityEncode((container.Child as System.Windows.Controls.TextBlock).Text);
                        htmlWriter.WriteRaw(text);
                    }
                    else
                    {
                        // not supported
                        if (conversionResult != null)
                        {
                            if (container.Child != null)
                                conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                    "AddInline: Unknown inline ui container child: " + container.Child.ToString()));
                            //else
                            //    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                            //        "AddInline: Inline ui container child is null: " + container.ToString()));
                        }
                    }
                }
                else if (inline is HtmlHyperlink)
                {
                    // Add hyperlink
                    AddHyperlink(inline as HtmlHyperlink, htmlWriter, conversionResult, inheritedStyle);
                }
                else if (inline is Span)
                {
                    Span span = inline as Span;
                    AddInlines(span.Inlines, htmlWriter, conversionResult, inheritedStyle);
                }
                else if (inline is Run)
                {
                    string text = ExtendedHtmlUtility.HtmlEntityEncode((inline as Run).Text);
                    //string text = HtmlEncode((inline as Run).Text); ;
                    htmlWriter.WriteRaw(text);
                }
                else
                {
                    // not supported
                    if (conversionResult != null)
                    {
                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                            "AddInline: Unknown inline element: " + inline.ToString()));
                    }

                }
            }
        }
        /// <summary>
        /// Converts Html ul or ol element into Xaml list element. During conversion if the ul/ol element has any children 
        /// that are not li elements, they are ignored and not added to the list element
        /// </summary>
        /// <param name="xamlParentElement">XmlElement representing Xaml parent to which the converted element should be added</param>
        /// <param name="htmlListElement">XmlElement representing Html ul/ol element to be converted</param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddList(XmlElement xamlParentElement, HtmlNode htmlListElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            string htmlListElementName = htmlListElement.Name.ToLower();

            // Create Xaml List element
            XmlElement xamlListElement = xamlParentElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_List, HtmlToXamlConverter.Xaml_Namespace);

            // We do not support any attributes on lists
            foreach (HtmlAttribute attribute in htmlListElement.Attributes)
            {
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                        "AddList: Unknown attribute " + attribute.Name + ":" + attribute.Value + " on list: " + htmlListElement.Name));
                }
            }

            // Set default list markers
            if (htmlListElementName == "ol")
            {
                // Ordered list
                xamlListElement.SetAttribute(HtmlToXamlConverter.Xaml_List_MarkerStyle, Xaml_List_MarkerStyle_Decimal);
            }
            else
            {
                // Unordered list - all elements other than OL treated as unordered lists
                xamlListElement.SetAttribute(HtmlToXamlConverter.Xaml_List_MarkerStyle, Xaml_List_MarkerStyle_Disc);
            }

            // Recurse into list subtree
            for (HtmlNode htmlChildNode = htmlListElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling)
            {
                if (htmlChildNode.NodeType == HtmlNodeType.Element && htmlChildNode.Name.ToLower() == "li")
                {
                    sourceContext.Add(htmlChildNode);
                    AddListItem(xamlListElement, htmlChildNode, sourceContext, conversionResult, vModellDirectory);

                    System.Diagnostics.Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode);
                    sourceContext.RemoveAt(sourceContext.Count - 1);
                }
                else
                {
                    // Not an li element. Add it to previous ListBoxItem
                    //  We need to append the content to the end
                    // of a previous list item.
                }
            }

            // Add the List element to xaml tree - if it is not empty
            if (xamlListElement.HasChildNodes)
            {
                xamlParentElement.AppendChild(xamlListElement);
            }
        }
        /// <summary>
        /// Convert an flow document list into its html representation.
        /// </summary>
        /// <param name="list">Flow document list.</param>
        /// <param name="htmlWriter">XmlTextWriter producing resulting html.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        private static void AddList(List list, XmlTextWriter htmlWriter, ValidationResult conversionResult)
        {
            if (list.MarkerStyle == System.Windows.TextMarkerStyle.Disc)
                htmlWriter.WriteStartElement("ul");
            else if (list.MarkerStyle == System.Windows.TextMarkerStyle.Decimal)
                htmlWriter.WriteStartElement("ol");
            else
            {
                if (conversionResult != null)
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Error, "Unknown list marker style: " + list.MarkerStyle.ToString()));
                return;
            }

            // process list items
            foreach (ListItem item in list.ListItems)
            {
                htmlWriter.WriteStartElement("li");

                // process blocks
                foreach (Block block in item.Blocks)
                    AddBlock(block, htmlWriter, conversionResult);

                htmlWriter.WriteEndElement();
            }

            htmlWriter.WriteEndElement();
        }
        /// <summary>
        /// Converts htmlLIElement into Xaml ListItem element, and appends it to the parent xamlListElement
        /// </summary>
        /// <param name="xamlListElement">XmlElement representing Xaml List element to which the converted td/th should be added</param>
        /// <param name="htmlLIElement">XmlElement representing Html li element to be converted</param>
        /// <param name="sourceContext">Source context.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddListItem(XmlElement xamlListElement, HtmlNode htmlLIElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            // Parameter validation
            System.Diagnostics.Debug.Assert(xamlListElement != null);
            System.Diagnostics.Debug.Assert(xamlListElement.LocalName == Xaml_List);
            System.Diagnostics.Debug.Assert(htmlLIElement != null);
            System.Diagnostics.Debug.Assert(htmlLIElement.Name.ToLower() == "li");

            XmlElement xamlListItemElement = xamlListElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_ListItem, HtmlToXamlConverter.Xaml_Namespace);

            // We do not support any attributes on list items
            foreach (HtmlAttribute attribute in htmlLIElement.Attributes)
            {
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                        "AddList: Unknown attribute " + attribute.Name + ":" + attribute.Value + " on list: " + htmlLIElement.Name));
                }
            }

            // Process children of the ListItem
            for (HtmlNode htmlChildNode = htmlLIElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode != null ? htmlChildNode.NextSibling : null)
            {
                htmlChildNode = AddBlock(xamlListItemElement, htmlChildNode, sourceContext, conversionResult, vModellDirectory);
            }

            // Add resulting ListBoxItem to a xaml parent
            xamlListElement.AppendChild(xamlListItemElement);
        }
        /// <summary>
        /// Adds a hyperlink.
        /// </summary>
        /// <param name="xamlParentElement">XmlElement representing Xaml parent to which the converted element should be added</param>
        /// <param name="htmlElement">Source html element subject to convert to xaml.</param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddHyperlink(XmlElement xamlParentElement, HtmlNode htmlElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            // Convert href attribute into NavigateUri and TargetName
            string href = GetAttribute(htmlElement, "href");
            if (href == null)
            {
                // When href attribute is missing - ignore the hyperlink
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                        "AddHyperlink: Href is missing: " + htmlElement.InnerHtml));
                }
            }
            else
            {
                // Create a XAML element corresponding to this html element
                XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Hyperlink, HtmlToXamlConverter.Xaml_Namespace_Tum_VMX_Types);

                //string[] hrefParts = href.Split(new char[] { '#' });
                //if (hrefParts.Length > 0 && hrefParts[0].Trim().Length > 0)
                //{
                //xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_NavigateUri, hrefParts[0].Trim());
                //    xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_TargetName, hrefParts[0].Trim());
                //}
                //if (hrefParts.Length == 2 && hrefParts[1].Trim().Length > 0)
                //{
                //     xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_TargetName, hrefParts[1].Trim());
                //}
                xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_TargetName, href.Trim());

                // Recurse into element subtree
                for (HtmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling)
                {
                    AddInline(xamlElement, htmlChildNode, sourceContext, conversionResult, vModellDirectory);
                }

                // Add the new element to the parent.
                xamlParentElement.AppendChild(xamlElement);
            }
        }
        /// <summary>
        /// Converts an html string into xaml string.
        /// </summary>
        /// <param name="htmlDocument">Html document.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        /// <returns>
        /// Well-formed xml string representing XAML equivalent for the input html.
        /// </returns>
        public static string ConvertHtmlToXaml(HtmlDocument htmlDocument, ValidationResult conversionResult, string vModellDirectory)
        {
            // Decide what name to use as a root
            string rootElementName = HtmlToXamlConverter.Xaml_FlowDocument;

            // Create an XmlDocument for generated xaml
            XmlDocument xamlTree = new XmlDocument();
            XmlElement xamlFlowDocumentElement = xamlTree.CreateElement(null, rootElementName, HtmlToXamlConverter.Xaml_Namespace_Tum_VMX_Types);
            //xamlFlowDocumentElement.SetAttribute("TextOptions.TextFormattingMode", "Display");

            try
            {
                // Source context is a stack of all elements - ancestors of a parentElement
                List<HtmlNode> sourceContext = new List<HtmlNode>(10);

                // convert root html element
                AddBlock(xamlFlowDocumentElement, htmlDocument.DocumentNode, sourceContext, conversionResult, vModellDirectory);

                // Return a string representing resulting Xaml
                xamlFlowDocumentElement.SetAttribute("xml:space", "preserve");

            }
            catch (Exception ex)
            {
                if (conversionResult != null)
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Error, "Conversion failed: " + ex.Message));
            }

            return xamlFlowDocumentElement.OuterXml;
        }
        /// <summary>
        /// Generates Paragraph element from P.
        /// </summary>
        /// <param name="xamlParentElement">XmlElement representing Xaml parent to which the converted element should be added</param>
        /// <param name="htmlElement">XmlElement representing Html element to be converted</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        /// <param name="sourceContext"></param>
        private static void AddParagraph(XmlElement xamlParentElement, HtmlNode htmlElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            // Create a XAML element corresponding to this html element
            XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Paragraph, HtmlToXamlConverter.Xaml_Namespace);

            // apply local paragraph properties
            bool bAlignmentSet = false;
            foreach (HtmlAttribute attribute in htmlElement.Attributes)
            {
                string name = attribute.Name.ToLower();
                switch (name)
                {
                    case "align":
                        xamlElement.SetAttribute(Xaml_TextAlignment, ParseTextAlignment(attribute.Value, conversionResult));
                        bAlignmentSet = true;
                        break;

                    case "style":
                        Hashtable cssAttributes = GetCssAttributes(attribute.Value);

                        // only margins are supported in inline style attribute
                        bool marginSet = false;
                        string marginTop = "0";
                        string marginBottom = "0";
                        string marginLeft = "0";
                        string marginRight = "0";
                        foreach (string cssName in cssAttributes.Keys)
                        {
                            string attributeValue = cssAttributes[cssName].ToString();
                            switch (cssName)
                            {
                                case "margin-top":
                                    marginSet = true;
                                    marginTop = attributeValue;
                                    break;
                                case "margin-right":
                                    marginSet = true;
                                    marginRight = attributeValue;
                                    break;
                                case "margin-bottom":
                                    marginSet = true;
                                    marginBottom = attributeValue;
                                    break;
                                case "margin-left":
                                    marginSet = true;
                                    marginLeft = attributeValue;
                                    break;

                                case "margin":
                                    marginSet = true;
                                    marginLeft = marginRight = marginTop = marginBottom = attributeValue;
                                    break;

                                default:
                                    if (conversionResult != null)
                                    {
                                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                            "AddParagraph: Unknown style attribute on paragraph: " + attribute.Value));
                                    }
                                    break;
                            }
                        }

                        if (marginSet)
                        {
                            xamlElement.SetAttribute(Xaml_Margin, ParseMargin(marginLeft, marginRight, marginTop, marginBottom, conversionResult));
                        }
                        break;

                    default:
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddParagraph: Unknown attribute on paragraph: " + name));
                        }
                        break;
                }
            }
            if (!bAlignmentSet)
                xamlElement.SetAttribute(Xaml_TextAlignment, "Left");

            // Recurse into element subtree
            for (HtmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling)
            {
                AddInline(xamlElement, htmlChildNode, sourceContext, conversionResult, vModellDirectory);
            }

            // Add the new element to the parent.
            xamlParentElement.AppendChild(xamlElement);
        }
        /// <summary>
        /// Adds inline elements.
        /// </summary>
        /// <param name="xamlParentElement">Parent xaml element, to which new converted element will be added </param>
        /// <param name="htmlNode"> Source html element subject to convert to xaml.</param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddInline(XmlElement xamlParentElement, HtmlNode htmlNode, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            if (htmlNode.NodeType == HtmlNodeType.Comment)
            {
                AddCommentText(xamlParentElement, htmlNode, conversionResult, vModellDirectory);
            }
            else if (htmlNode.NodeType == HtmlNodeType.Text)
            {
                AddTextRun(xamlParentElement, htmlNode, conversionResult, vModellDirectory);
            }
            else if (htmlNode.NodeType == HtmlNodeType.Element)
            {
                // Identify element name
                string htmlElementName = htmlNode.Name.ToLower();

                // Put source element to the stack
                sourceContext.Add(htmlNode);

                switch (htmlElementName)
                {
                    case "a":
                        AddHyperlink(xamlParentElement, htmlNode, sourceContext, conversionResult, vModellDirectory);
                        break;

                    case "img":
                        AddImage(xamlParentElement, htmlNode, sourceContext, conversionResult, vModellDirectory);
                        break;

                    case "b":
                    case "u":
                    case "i":
                        AddSpanOrRun(xamlParentElement, htmlNode, sourceContext, conversionResult, vModellDirectory);
                        break;

                    default:
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddInline: Unknown inline element: " + htmlElementName));
                        }
                        break;
                }
                // Ignore all other elements non-(block/inline/image)

                // Remove the element from the stack
                System.Diagnostics.Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlNode);
                sourceContext.RemoveAt(sourceContext.Count - 1);
            }
        }
        /// <summary>
        /// Parses the html border attribute given as a string.
        /// </summary>
        /// <param name="border">Html border attribute value.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <returns>
        /// Returns the corresponding xaml border thickness value as a string. 
        /// Should the given value not be recognized, the default value ('0') is returned.</returns>
        public static string ParseBorderThickness(string border, ValidationResult conversionResult)
        {
            string bordernValue = border.ToLower();
            if (String.IsNullOrEmpty(bordernValue))
            {
                if (conversionResult != null)
                {
                    conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                        "ParseBorderThickness: Unknown value: " + border));
                }
            }
            else
            {
                int result;
                if (Int32.TryParse(bordernValue, out result))
                {
                    return result.ToString();
                }
                else
                {
                    if (conversionResult != null)
                    {
                        conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                            "ParseBorderThickness: Value is not a number: " + border));
                    }
                }
            }

            return "0";
        }
 /// <summary>
 /// Convert an flow document paragraph into its html representation.
 /// </summary>
 /// <param name="block">Flow document block.</param>
 /// <param name="htmlWriter">XmlTextWriter producing resulting html.</param>
 /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
 /// <remarks>
 /// List, Paragraph, Table are supported Block elements. Section is not supported.
 /// </remarks>
 private static void AddBlock(Block block, XmlTextWriter htmlWriter, ValidationResult conversionResult)
 {
     if (block is List)
     {
         AddList(block as List, htmlWriter, conversionResult);
     }
     else if (block is Paragraph)
     {
         AddParagraph(block as Paragraph, htmlWriter, conversionResult);
     }
     else if (block is Table)
     {
         AddTable(block as Table, htmlWriter, conversionResult);
     }
     else
     {
         // not supported: Section
         if (conversionResult != null)
         {
             conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                 "AddBlock: Unknown block element: " + block.ToString()));
         }
     }
 }
        /// <summary>
        /// Adds TableRow elements . The rows are converted from Html tr elements.
        /// </summary>
        /// <param name="xamlTableRowGroup">XmlElement representing Xaml TableRowGroup element to which the converted rows should be added.</param>
        /// <param name="htmlTRStartNode">XmlElement representing the first tr child.</param>
        /// <param name="sourceContext"></param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        /// <param name="inheritedProperties">Inherited properties.</param>
        /// <returns>
        /// XmlNode representing the current position of the iterator among tr elements.
        /// </returns>
        private static HtmlNode AddTableRows(XmlElement xamlTableRowGroup, HtmlNode htmlTRStartNode, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory, Hashtable inheritedProperties)
        {
            // Parameter validation
            System.Diagnostics.Debug.Assert(xamlTableRowGroup.LocalName == Xaml_TableRowGroup);

            // Initialize child node for iteratimg through children to the first tr element
            HtmlNode htmlChildNode = htmlTRStartNode;
            while (htmlChildNode != null)
            {
                if (htmlChildNode.Name.ToLower() == "tr")
                {
                    XmlElement xamlTableRowElement = xamlTableRowGroup.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_TableRow, HtmlToXamlConverter.Xaml_Namespace);
                    sourceContext.Add(htmlChildNode);

                    // We do not support any attributes on tr items
                    foreach (HtmlAttribute attribute in htmlChildNode.Attributes)
                    {
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTableRows: Unknown attribute " + attribute.Name + ":" + attribute.Value + " on tr: " + htmlChildNode.Name));
                        }
                    }

                    AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode.FirstChild, sourceContext, conversionResult, vModellDirectory, inheritedProperties);
                    //if (xamlTableRowElement.HasChildNodes)
                    //{
                    xamlTableRowGroup.AppendChild(xamlTableRowElement);
                    //}

                    System.Diagnostics.Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode);
                    sourceContext.RemoveAt(sourceContext.Count - 1);

                    // Advance
                    htmlChildNode = htmlChildNode.NextSibling;
                }
                else if (htmlChildNode.Name.ToLower() == "td")
                {
                    // Tr element is not present. We create one and add td elements to it
                    XmlElement xamlTableRowElement = xamlTableRowGroup.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_TableRow, HtmlToXamlConverter.Xaml_Namespace);

                    htmlChildNode = AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode, sourceContext, conversionResult, vModellDirectory, inheritedProperties);
                    //if (xamlTableRowElement.HasChildNodes)
                    //{
                    xamlTableRowGroup.AppendChild(xamlTableRowElement);
                    //}
                }
                else
                {
                    if (conversionResult != null)
                    {
                        if (String.IsNullOrWhiteSpace(htmlChildNode.InnerText) && htmlChildNode.NodeType == HtmlNodeType.Text)
                        {
                            // for some reason, there is always a white space behind the table/tr/td elements.. so dont react on that
                            // do we need a warning?
                        }
                        else
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTableRows: Unknown child: " + htmlChildNode.Name + ":" + htmlChildNode.OuterHtml));
                    }

                    htmlChildNode = htmlChildNode.NextSibling;
                }
            }
            return htmlChildNode;
        }
        /// <summary>
        /// Converts htmlTableElement to a Xaml Table element. Adds tbody elements if they are missing so
        /// that a resulting Xaml Table element is properly formed.
        /// </summary>
        /// <param name="xamlParentElement">Parent xaml element to which a converted table must be added.</param>
        /// <param name="htmlTableElement">XmlElement reprsenting the Html table element to be converted</param>
        /// <param name="sourceContext">Source context.</param>
        /// <param name="conversionResult">Conversion result to store error and warning messages. Can be null.</param>
        /// <param name="vModellDirectory">Directory of the VModell instance containing the element that has a html property.</param>
        private static void AddTable(XmlElement xamlParentElement, HtmlNode htmlTableElement, List<HtmlNode> sourceContext, ValidationResult conversionResult, string vModellDirectory)
        {
            // Parameter validation
            System.Diagnostics.Debug.Assert(htmlTableElement.Name.ToLower() == "table");
            System.Diagnostics.Debug.Assert(xamlParentElement != null);

            // Create xamlTableElement
            XmlElement xamlTableElement = xamlParentElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_Table, HtmlToXamlConverter.Xaml_Namespace);

            Hashtable inheritedProperties = new Hashtable();

            // apply local table properties, only border is supported
            foreach (HtmlAttribute attribute in htmlTableElement.Attributes)
            {
                string name = attribute.Name.ToLower();
                switch (name)
                {
                    case "border":
                        inheritedProperties.Add("border", attribute.Value);
                        //xamlTableElement.SetAttribute(Xaml_BorderThickness, ParseBorderThickness(attribute.Value, conversionResult));
                        //xamlTableElement.SetAttribute(Xaml_BorderBrush, "Black");
                        break;

                    default:
                        if (conversionResult != null)
                        {
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTable: Unknown attribute on table: " + name));
                        }
                        break;
                }
            }



            // Process table body - TR elements
            HtmlNode htmlChildNode = htmlTableElement.FirstChild;
            while (htmlChildNode != null)
            {
                string htmlChildName = htmlChildNode.Name.ToLower();
                if (htmlChildName == "tr")
                {
                    XmlElement xamlTableRowGroup = xamlTableElement.OwnerDocument.CreateElement(null, HtmlToXamlConverter.Xaml_TableRowGroup, HtmlToXamlConverter.Xaml_Namespace);
                    htmlChildNode = AddTableRows(xamlTableRowGroup, htmlChildNode, sourceContext, conversionResult, vModellDirectory, inheritedProperties);

                    //if (xamlTableRowGroup.HasChildNodes)
                    //{
                    xamlTableElement.AppendChild(xamlTableRowGroup);
                    //}
                }
                else
                {
                    if (conversionResult != null)
                    {

                        if (String.IsNullOrWhiteSpace(htmlChildNode.InnerText) && htmlChildNode.NodeType == HtmlNodeType.Text)
                        {
                            // for some reason, there is always a white space behind the table/tr/td elements.. so dont react on that
                            // do we need a warning?
                        }
                        else
                            conversionResult.AddMessage(new ConversionMessage(ModelValidationViolationType.Warning,
                                "AddTable: Unknown child: " + htmlChildName + ":" + htmlChildNode.OuterHtml));
                    }
                    htmlChildNode = htmlChildNode.NextSibling;
                }
            }

            //if (xamlTableElement.HasChildNodes)
            //{
            xamlParentElement.AppendChild(xamlTableElement);
            //}
        }