/// <summary>
        /// Writes a text to the console with word wrap.
        /// </summary>
        /// <param name="message">the message to write</param>
        /// <param name="maxLineWidth">the maximum length of a line before line break.</param>
        /// <param name="writeToNewLine">write the message to a separated line (otherwise continue to output on the same line)</param>
        /// <param name="indentation">Apply indentation when writing on a new line.</param>
        /// <param name="prefixForNewLines">The text to put at the beginning of each new line that need to be created because of word wrap.</param>
        public void Write(string message, int maxLineWidth, bool writeToNewLine, int indentation = 0, string prefixForNewLines = null)
        {
            // handle null message
            if (message == null)
            {
                // write a new line
                if (writeToNewLine && HasWroteToOuput)
                {
                    WriteLine();
                }
                HasWroteToOuput = true;
                return;
            }

            // check indentation
            if (maxLineWidth > 0 && indentation >= maxLineWidth - 10)
            {
                indentation = maxLineWidth - 10;
            }
            indentation = Math.Max(indentation, 0);

            // write without word wrap
            if (maxLineWidth <= 0)
            {
                // write a new line
                if (writeToNewLine && HasWroteToOuput)
                {
                    WriteLine();
                    _currentLineSpaceTaken = 0;
                }
                message = _currentLineSpaceTaken == 0 && indentation > 0 ? message.PadLeft(message.Length + indentation) : message;
                UnderLyingWriter.Write(message);
                _currentLineSpaceTaken += message.Length;
                HasWroteToOuput         = true;
                return;
            }

            // for each line of text
            int lineStartPos, nextLineStartPos;

            for (lineStartPos = 0; lineStartPos < message.Length; lineStartPos = nextLineStartPos)
            {
                int eolPosition = message.IndexOf('\n', lineStartPos);
                if (eolPosition == -1)
                {
                    nextLineStartPos = eolPosition = message.Length;
                }
                else
                {
                    nextLineStartPos = eolPosition + 1;
                    if (eolPosition == lineStartPos)
                    {
                        // found a new line
                        WriteLine();
                        continue;
                    }
                }

                // an input line can have indentation; if we split this input line into several lines (because it is too long),
                // we need to keep the same indentation for each new line
                bool newInputLineStarting = true;
                int  paragraphIndent      = 0;

                if (eolPosition > lineStartPos)
                {
                    do
                    {
                        // write a new line
                        if (writeToNewLine && HasWroteToOuput || _currentLineSpaceTaken >= maxLineWidth)
                        {
                            if (newInputLineStarting || string.IsNullOrEmpty(prefixForNewLines))
                            {
                                WriteLine();
                            }
                            else
                            {
                                var newLinePrefix = prefixForNewLines.PadRight(Math.Max(0, indentation + paragraphIndent));
                                WriteLine($"{UnderLyingWriter.NewLine}{newLinePrefix}");
                                _currentLineSpaceTaken += newLinePrefix.Length;
                            }
                        }

                        int lineLength  = eolPosition - lineStartPos;
                        int totalIndent = _currentLineSpaceTaken > 0 ? 0 : indentation + paragraphIndent;
                        int currentConsoleLineSpaceLeft = maxLineWidth - _currentLineSpaceTaken - totalIndent;

                        if (lineLength > currentConsoleLineSpaceLeft)
                        {
                            lineLength = GetLineLengthToKeep(message, lineStartPos, currentConsoleLineSpaceLeft, !writeToNewLine && message.Length <= maxLineWidth - totalIndent);
                        }

                        if (lineLength > 0)
                        {
                            var line = message.Substring(lineStartPos, lineLength);
                            line = _currentLineSpaceTaken > 0 ? line : line.PadLeft(lineLength + indentation + paragraphIndent, ' ');
                            UnderLyingWriter.Write(line);
                            _currentLineSpaceTaken += line.Length;
                            HasWroteToOuput         = true;
                        }

                        if (newInputLineStarting && writeToNewLine)
                        {
                            while (lineStartPos + paragraphIndent < message.Length && char.IsWhiteSpace(message[lineStartPos + paragraphIndent]))
                            {
                                paragraphIndent++;
                            }
                            if (indentation + paragraphIndent >= maxLineWidth)
                            {
                                paragraphIndent = maxLineWidth - indentation - 10;
                            }
                        }
                        newInputLineStarting = false;
                        writeToNewLine       = true;

                        // trim the whitespaces following a word break
                        lineStartPos += lineLength;
                        while (lineStartPos < eolPosition && message[lineStartPos] != '\n' && char.IsWhiteSpace(message[lineStartPos]))
                        {
                            lineStartPos++;
                        }
                    } while (eolPosition > lineStartPos);
                }
            }
        }
 /// <summary>
 /// Write a new line char into the text writer
 /// </summary>
 /// <param name="newLine"></param>
 public void WriteLine(string newLine = null)
 {
     UnderLyingWriter.Write(newLine ?? UnderLyingWriter.NewLine);
     _currentLineSpaceTaken = 0;
     HasWroteToOuput        = true;
 }