private void PreprocessElement(XmlDocument document, XmlElement element, ref List<PreprocessorAreaData> datas, PreprocessorAreaData parentArea = null)
		{
			List<XmlElement> nodes = element.ChildNodes.OfType<XmlElement>().ToList();

			foreach (XmlElement subElement in nodes)
			{
				if (subElement == null)
				{
					continue;
				}

				switch (subElement.Name.ToLower())
				{
					case "mssqlauditorpreprocessor":
						{
							string className           = subElement.Attributes["preprocessor"].Value;

							XmlAttribute idAttr        = subElement.Attributes["id"];
							XmlAttribute nameAttr      = subElement.Attributes["name"];
							XmlAttribute columnAttr    = subElement.Attributes["column"];
							XmlAttribute rowAttr       = subElement.Attributes["row"];
							XmlAttribute colSpanAttr   = subElement.Attributes["colspan"];
							XmlAttribute rowSpanAttr   = subElement.Attributes["rowspan"];
							XmlAttribute vertTestAlign = subElement.Attributes["text-vertical-align"];
							XmlAttribute textAlign     = subElement.Attributes["text-align"];

							string id                  = "";
							string preprocName         = "unnamed";

							if (nameAttr != null)
							{
								preprocName = nameAttr.Value;
							}

							if (idAttr != null)
							{
								id = idAttr.Value;
							}

							int col     = ParseIntAttribute(columnAttr,  1);
							int row     = ParseIntAttribute(rowAttr,     1);
							int colSpan = ParseIntAttribute(colSpanAttr, 1);
							int rowSpan = ParseIntAttribute(rowSpanAttr, 1);

							VerticalTextAlign? preprocVertTestAlign = null;

							if (vertTestAlign != null)
							{
								VerticalTextAlign tempVertTestAlign;

								if (Enum.TryParse(vertTestAlign.Value, out tempVertTestAlign))
								{
									preprocVertTestAlign = tempVertTestAlign;
								}
							}

							TextAlign preprocTestAlign = TextAlign.Left;

							if (textAlign != null)
							{
								if (!Enum.TryParse(textAlign.Value, out preprocTestAlign))
								{
									preprocTestAlign = TextAlign.Left;
								}
							}

							IPreprocessor preprocessor =
								(from proc in this._availablePreprocessors where proc.GetType().Name == className select proc)
									.FirstOrDefault();

							if (preprocessor != null)
							{
								string          configuration = subElement.InnerXml;
								IContentFactory factory       = preprocessor.CreateContentFactory(id, configuration);

								PreprocessorData data = new PreprocessorData
								{
									ContentFactory    = factory,
									Name              = preprocName,
									Column            = col,
									Row               = row,
									ColSpan           = colSpan,
									RowSpan           = rowSpan,
									VerticalTextAlign = preprocVertTestAlign,
									TextAlign         = preprocTestAlign
								};

								XmlElement newSubElement = document.CreateElement("div");

								newSubElement.SetAttribute("style", "margin:0; padding:0;");
								newSubElement.InnerXml = string.Empty;

								element.ReplaceChild(newSubElement, subElement);

								if (parentArea != null)
								{
									parentArea.Preprocessors.Add(data);
								}
								else
								{
									log.ErrorFormat(
										"Invalid configuration: <mssqlauditorpreprocessor> is not embedded in <mssqlauditorpreprocessors>. " +
										"Are you using old style configuration file?" + Environment.NewLine +
										"Silently ignoring '{0}' with id='{1}' and name='{2}'",
										className,
										id,
										preprocName
									);

									throw new ArgumentOutOfRangeException(
										"document",
										"Invalid configuration: <mssqlauditorpreprocessor> is not embedded in <mssqlauditorpreprocessors>!"
									);
								}
								continue;
							}
							break;
						}
					case "mssqlauditorpreprocessors":
						{
							XmlAttribute idAttr       = subElement.Attributes["id"];
							XmlAttribute nameAttr     = subElement.Attributes["name"];
							XmlAttribute rowsAttr     = subElement.Attributes["rows"];
							XmlAttribute columnsAttr  = subElement.Attributes["columns"];
							XmlAttribute splitterAttr = subElement.Attributes["splitter"];

							string id       = "";
							string name     = "unnamed";
							string rows     = "";
							string columns  = "";
							string splitter = "";

							if (nameAttr != null)
							{
								name = nameAttr.Value;
							}
							if (idAttr != null)
							{
								id = idAttr.Value;
							}
							if (columnsAttr != null)
							{
								columns = columnsAttr.Value;
							}
							if (rowsAttr != null)
							{
								rows = rowsAttr.Value;
							}
							if (splitterAttr != null)
							{
								splitter = splitterAttr.Value;
							}

							PreprocessorAreaData container = new PreprocessorAreaData(id, name, columns, rows);

							if (string.Equals(splitter, "no", StringComparison.InvariantCultureIgnoreCase))
							{
								container.NoSplitter = true;
							}

							datas.Add(container);

							PreprocessElement(document, subElement, ref datas, container);

							container.CheckPreprocessors();

							continue;
						}
				}

				PreprocessElement(document, subElement, ref datas);
			}
		}
        private void PreprocessElement(XmlDocument document, XmlElement element, ref List <PreprocessorAreaData> datas, PreprocessorAreaData parentArea = null)
        {
            List <XmlElement> nodes = element.ChildNodes.OfType <XmlElement>().ToList();

            foreach (XmlElement subElement in nodes)
            {
                if (subElement == null)
                {
                    continue;
                }

                switch (subElement.Name.ToLower())
                {
                case "mssqlauditorpreprocessor":
                {
                    string className = subElement.Attributes["preprocessor"].Value;

                    XmlAttribute idAttr        = subElement.Attributes["id"];
                    XmlAttribute nameAttr      = subElement.Attributes["name"];
                    XmlAttribute columnAttr    = subElement.Attributes["column"];
                    XmlAttribute rowAttr       = subElement.Attributes["row"];
                    XmlAttribute colSpanAttr   = subElement.Attributes["colspan"];
                    XmlAttribute rowSpanAttr   = subElement.Attributes["rowspan"];
                    XmlAttribute vertTestAlign = subElement.Attributes["text-vertical-align"];
                    XmlAttribute textAlign     = subElement.Attributes["text-align"];

                    string id          = "";
                    string preprocName = "unnamed";

                    if (nameAttr != null)
                    {
                        preprocName = nameAttr.Value;
                    }

                    if (idAttr != null)
                    {
                        id = idAttr.Value;
                    }

                    int col     = ParseIntAttribute(columnAttr, 1);
                    int row     = ParseIntAttribute(rowAttr, 1);
                    int colSpan = ParseIntAttribute(colSpanAttr, 1);
                    int rowSpan = ParseIntAttribute(rowSpanAttr, 1);

                    VerticalTextAlign?preprocVertTestAlign = null;

                    if (vertTestAlign != null)
                    {
                        VerticalTextAlign tempVertTestAlign;

                        if (Enum.TryParse(vertTestAlign.Value, out tempVertTestAlign))
                        {
                            preprocVertTestAlign = tempVertTestAlign;
                        }
                    }

                    TextAlign preprocTestAlign = TextAlign.Left;

                    if (textAlign != null)
                    {
                        if (!Enum.TryParse(textAlign.Value, out preprocTestAlign))
                        {
                            preprocTestAlign = TextAlign.Left;
                        }
                    }

                    IPreprocessor preprocessor =
                        (from proc in this._availablePreprocessors where proc.GetType().Name == className select proc)
                        .FirstOrDefault();

                    if (preprocessor != null)
                    {
                        string          configuration = subElement.InnerXml;
                        IContentFactory factory       = preprocessor.CreateContentFactory(id, configuration);

                        PreprocessorData data = new PreprocessorData
                        {
                            ContentFactory    = factory,
                            Name              = preprocName,
                            Column            = col,
                            Row               = row,
                            ColSpan           = colSpan,
                            RowSpan           = rowSpan,
                            VerticalTextAlign = preprocVertTestAlign,
                            TextAlign         = preprocTestAlign
                        };

                        XmlElement newSubElement = document.CreateElement("div");

                        newSubElement.SetAttribute("style", "margin:0; padding:0;");
                        newSubElement.InnerXml = string.Empty;

                        element.ReplaceChild(newSubElement, subElement);

                        if (parentArea != null)
                        {
                            parentArea.Preprocessors.Add(data);
                        }
                        else
                        {
                            log.ErrorFormat(
                                "Invalid configuration: <mssqlauditorpreprocessor> is not embedded in <mssqlauditorpreprocessors>. " +
                                "Are you using old style configuration file?" + Environment.NewLine +
                                "Silently ignoring '{0}' with id='{1}' and name='{2}'",
                                className,
                                id,
                                preprocName
                                );

                            throw new ArgumentOutOfRangeException(
                                      "document",
                                      "Invalid configuration: <mssqlauditorpreprocessor> is not embedded in <mssqlauditorpreprocessors>!"
                                      );
                        }
                        continue;
                    }
                    break;
                }

                case "mssqlauditorpreprocessors":
                {
                    XmlAttribute idAttr       = subElement.Attributes["id"];
                    XmlAttribute nameAttr     = subElement.Attributes["name"];
                    XmlAttribute rowsAttr     = subElement.Attributes["rows"];
                    XmlAttribute columnsAttr  = subElement.Attributes["columns"];
                    XmlAttribute splitterAttr = subElement.Attributes["splitter"];

                    string id       = "";
                    string name     = "unnamed";
                    string rows     = "";
                    string columns  = "";
                    string splitter = "";

                    if (nameAttr != null)
                    {
                        name = nameAttr.Value;
                    }
                    if (idAttr != null)
                    {
                        id = idAttr.Value;
                    }
                    if (columnsAttr != null)
                    {
                        columns = columnsAttr.Value;
                    }
                    if (rowsAttr != null)
                    {
                        rows = rowsAttr.Value;
                    }
                    if (splitterAttr != null)
                    {
                        splitter = splitterAttr.Value;
                    }

                    PreprocessorAreaData container = new PreprocessorAreaData(id, name, columns, rows);

                    if (string.Equals(splitter, "no", StringComparison.InvariantCultureIgnoreCase))
                    {
                        container.NoSplitter = true;
                    }

                    datas.Add(container);

                    PreprocessElement(document, subElement, ref datas, container);

                    container.CheckPreprocessors();

                    continue;
                }
                }

                PreprocessElement(document, subElement, ref datas);
            }
        }