/// <summary>
        /// Writes the value of the geolocation to the table as an image.
        /// </summary>
        /// <param name="table">The <see cref="MigraDoc.DocumentObjectModel.Tables.Table"/> to write to.</param>
        /// <param name="control">The control.</param>
        /// <param name="container">The application data container.</param>
        /// <param name="level">The depth down the control tree being rendered (affects indenting).</param>
        private void WriteValueGeolocation(Table table, GeolocationControl control, Dictionary<string, object> container, int level)
        {
            if (control.DisplayStyle == GeolocationDisplayStyle.None)
            {
                return;
            }

            Row row = table.AppendRow(this.DefaultStyle.Font.Size, control.Label, string.Empty);
            row.Cells[0].Format.LeftIndent = new Unit(PdfConstants.IndentMultiplier * level, UnitType.Millimeter);

            string coords = container[control.Name].ToString();

            if (control.DisplayStyle == GeolocationDisplayStyle.Both || control.DisplayStyle == GeolocationDisplayStyle.Coordinates)
            {
                row.Cells[1].AddParagraph(coords);
            }

            if (control.DisplayStyle != GeolocationDisplayStyle.Both && control.DisplayStyle != GeolocationDisplayStyle.Map)
            {
                return;
            }

            string path = this.GetTemporaryFileName("png");
            Coordinate coordinate = Coordinate.Parse(coords);
            GoogleMapProvider provider = new GoogleMapProvider();

            using (FileStream fileStream = new FileStream(path, FileMode.Create))
            {
                provider.Write(coordinate, new Size(225, 225), fileStream);
            }

            row.Cells[1].AddParagraph().AddImage(path);
        }
        /// <summary>
        /// Writes the value of the signature to the table as an image.
        /// </summary>
        /// <param name="table">The <see cref="MigraDoc.DocumentObjectModel.Tables.Table"/> to write to.</param>
        /// <param name="control">The control.</param>
        /// <param name="container">The application data container.</param>
        /// <param name="level">The depth down the control tree being rendered (affects indenting).</param>
        private void WriteValueSignature(Table table, SignaturePadControl control, Dictionary<string, object> container, int level)
        {
            Row row = table.AppendRow(this.DefaultStyle.Font.Size, control.Label, string.Empty);
            row.Cells[0].Format.LeftIndent = new Unit(PdfConstants.IndentMultiplier * level, UnitType.Millimeter);

            string controlValue = container[control.Name].ToString();
            if (string.IsNullOrEmpty(controlValue))
            {
                return;
            }

            byte[] encodedBytes = Convert.FromBase64String(controlValue.Split(',')[1]);
            string path = this.GetTemporaryFileName("png");

            using (FileStream stream = new FileStream(path, FileMode.CreateNew))
            {
                SvgToImageConverter converter = new SvgToImageConverter();
                converter.ConvertToImage(encodedBytes, stream, ImageFormat.Png);
            }

            Unit size = this.DefaultStyle.Font.Size * 2;
            Image addedImage = row.Cells[1].AddParagraph().AddImage(path);
            addedImage.LockAspectRatio = true;
            addedImage.Height = size;
            row.Height = size;
        }
        /// <summary>
        /// Writes the application value from <paramref name="container"/>
        /// that corresponds to <paramref name="control"/> to the <paramref name="table"/>.
        /// </summary>
        /// <param name="table">The <see cref="MigraDoc.DocumentObjectModel.Tables.Table"/> to write to.</param>
        /// <param name="control">The control.</param>
        /// <param name="container">The application data container.</param>
        /// <param name="level">The depth down the control tree being rendered (affects indenting).</param>
        private void WriteValue(Table table, Control control, Dictionary<string, object> container, int level)
        {
            if (control.Type == ControlType.Group)
            {
                this.WriteValueGroup(table, (GroupControl)control, container, level);
                return;
            }

            if (!container.ContainsKey(control.Name))
            {
                return;
            }

            switch (control.Type)
            {
                case ControlType.Group:
                    break;

                case ControlType.Repeater:
                    this.WriteValueRepeater(table, (RepeaterControl)control, container, level);
                    break;

                case ControlType.Calculation:
                    Row calcRow = table.AppendRow(this.DefaultStyle.Font.Size, ((CalculationControl)control).Label, container[control.Name].ToString());
                    calcRow.Cells[0].Format.LeftIndent = new Unit(PdfConstants.IndentMultiplier * level, UnitType.Millimeter);
                    break;

                case ControlType.Checkbox:
                case ControlType.CheckboxGroup:
                case ControlType.Combo:
                case ControlType.Date:
                case ControlType.FileBrowser:
                case ControlType.Hidden:
                case ControlType.Radio:
                case ControlType.Text:
                case ControlType.Time:
                    string formattedValue = this.formatter.FormatApplicationValue(container[control.Name], control);
                    Row row = table.AppendRow(this.DefaultStyle.Font.Size, ((ValueControl)control).Label, formattedValue);
                    row.Cells[0].Format.LeftIndent = new Unit(PdfConstants.IndentMultiplier * level, UnitType.Millimeter);
                    break;

                case ControlType.Geolocation:
                    this.WriteValueGeolocation(table, (GeolocationControl)control, container, level);
                    break;

                case ControlType.SignaturePad:
                    this.WriteValueSignature(table, (SignaturePadControl)control, container, level);
                    break;

                case ControlType.Likert:
                    this.WriteValueLikert(table, (LikertControl)control, container, level);
                    break;

                default:
                    throw new InvalidOperationException(string.Format(ExceptionMessages.UnknownControlType, control.Type));
            }
        }