diff --git a/exec/SlyEdit.js b/exec/SlyEdit.js
index 126b2fe3803bada0854a2f813d4c334ca1704a47..18cbea3cba4c49a6ab9e810fc6cdb9dffd7e61a7 100644
--- a/exec/SlyEdit.js
+++ b/exec/SlyEdit.js
@@ -53,6 +53,20 @@
  *                              the sbbs/ctrl directory, and if they're not
  *                              found there, assume they're in the same
  *                              directory as the .js files.
+ * 2012-12-23 Eric Oulashin     Version 1.17 BETA
+ *                              Started working on updating the quoting style,
+ *                              to add the "To" user's initials or first 2
+ *                              letters of their username to the quote prefix.
+ * 2012-12-25 Eric Oulashin     When reading quote lines, if a quote line
+ *                              contains only whitespace characters and/or >
+ *                              characters, it will make the line blank before
+ *                              adding it to gQuoteLines, to avoid weird
+ *                              issues when prefixing the quote lines.
+ * 2012-12-26 Eric Oulashin     Updated printEditLine() to return the length of
+ *                              text actually written.  Fixed a bug in
+ *                              displayMessageRectangle() that was causing some
+ *                              text lines not to be updated properly due to
+ *                              incorrectly calculating text lengths, etc.
  */
 
 /* Command-line arguments:
@@ -110,8 +124,8 @@ if (!console.term_supports(USER_ANSI))
 }
 
 // Constants
-const EDITOR_VERSION = "1.16";
-const EDITOR_VER_DATE = "2012-12-21";
+const EDITOR_VERSION = "1.17";
+const EDITOR_VER_DATE = "2012-12-26";
 
 
 // Program variables
@@ -131,7 +145,6 @@ if (console.screen_columns < 80)
 	gEditLeft = 1;
 	gEditRight = console.screen_columns;
 }
-// Note: gQuotePrefix is declared in SlyEdit_Misc.js.
 
 // Colors
 var gQuoteWinTextColor = "n7k";   // Normal text color for the quote window (DCT default)
@@ -139,6 +152,10 @@ var gQuoteLineHighlightColor = "nw"; // Highlighted text color for the quote w
 var gTextAttrs = "nw";               // The text color for edit mode
 var gQuoteLineColor = "nc";          // The text color for quote lines
 var gUseTextAttribs = false;              // Will be set to true if text colors start to be used
+// gQuotePrefix contains the text to prepend to quote lines.
+// gQuotePrefix will later be updated to include the "To" user's
+// initials or first 2 letters of their username.
+var gQuotePrefix = " > ";
 
 // EDITOR_STYLE: Can be changed to mimic the look of DCT Edit or IceEdit.
 // The following are supported:
@@ -270,6 +287,56 @@ console.ctrlkey_passthru = "+ACGKLOPQRTUVWXYZ_";
 // Enable delete line in SyncTERM (Disabling ANSI Music in the process)
 console.write("\033[=1M");
 console.clear();
+
+// Read the message from name, to name, and subject from the drop file
+// (msginf in the node directory).
+var gMsgSubj = "";
+var gFromName = user.alias;
+var gToName = gInputFilename;
+var gMsgArea = "";
+var dropFileTime = -Infinity;
+var dropFileName = file_getcase(system.node_dir + "msginf");
+if (dropFileName != undefined)
+{
+	if (file_date(dropFileName) >= dropFileTime)
+	{
+		var dropFile = new File(dropFileName);
+		if (dropFile.exists && dropFile.open("r"))
+		{
+			dropFileTime = dropFile.date;
+			info = dropFile.readAll();
+			dropFile.close();
+
+			gFromName = info[0];
+			gToName = info[1];
+			gMsgSubj = info[2];
+			gMsgArea = info[4];
+
+			// If specified in the configuration to use author's initials in
+			// the quote line prefix, then update gQuotePrefix to contain the
+			// initials or first 2 letters from gToName.
+			if (gConfigSettings.useQuoteLineInitials && (gToName.length > 0))
+			{
+				// Make a copy of gToName and remove any leading, multiple, or
+				// trailing spaces that it might have.  Then, use the initials
+				// or first 2 characters from it for gQuotePrefix.
+				var toName = trimSpaces(gToName, true, true, true);
+				var spaceIndex = toName.indexOf(" ");
+				if (spaceIndex > -1) // If a space exists, use the initials
+				{
+					gQuotePrefix = toName.charAt(0).toUpperCase();
+					if (toName.length > spaceIndex+1)
+						gQuotePrefix += toName.charAt(spaceIndex+1).toUpperCase();
+					gQuotePrefix += "> ";
+				}
+				else // A space doesn't exist; use the first 2 letters
+					gQuotePrefix = toName.substr(0, 2) + "> ";
+			}
+		}
+	}
+	file_remove(dropFileName);
+}
+
 // Open the quote file / message file
 var inputFile = new File(gInputFilename);
 if (inputFile.open("r", false))
@@ -286,12 +353,17 @@ if (inputFile.open("r", false))
         if (typeof(textLine) == "string")
         {
            textLine = strip_ctrl(textLine);
+           // If the line has only whitespace and/or > characters,
+           // then make the line blank before putting it into
+           // gQuoteLines.
+           if (/^[\s>]+$/.test(textLine))
+              textLine = "";
            gQuoteLines.push(textLine);
         }
      }
      // If the setting to re-wrap quote lines is enabled, then do it.
      if (gConfigSettings.reWrapQuoteLines && (gQuoteLines.length > 0))
-       wrapQuoteLines();
+       wrapQuoteLines(gConfigSettings.useQuoteLineInitials);
 	}
 	else
 	{
@@ -328,34 +400,6 @@ if (inputFile.open("r", false))
 	inputFile.close();
 }
 
-// Read the message from name, to name, and subject from the drop file
-// (msginf in the node directory).
-var gMsgSubj = "";
-var gFromName = user.alias;
-var gToName = gInputFilename;
-var gMsgArea = "";
-var dropFileTime = -Infinity;
-var dropFileName = file_getcase(system.node_dir + "msginf");
-if (dropFileName != undefined)
-{
-   if (file_date(dropFileName) >= dropFileTime)
-	{
-		var dropFile = new File(dropFileName);
-		if (dropFile.exists && dropFile.open("r"))
-		{
-         dropFileTime = dropFile.date;
-			info = dropFile.readAll();
-			dropFile.close();
-
-         gFromName = info[0];
-         gToName = info[1];
-			gMsgSubj = info[2];
-			gMsgArea = info[4];
-		}
-	}
-	file_remove(dropFileName);
-}
-
 // If the subject is blank, set it to something.
 if (gMsgSubj == "")
 	gMsgSubj = gToName.replace(/^.*[\\\/]/,'');
@@ -2213,8 +2257,16 @@ function getQuoteTextLine(pIndex, pMaxWidth)
    var textLine = "";
    if ((pIndex >= 0) && (pIndex < gQuoteLines.length))
    {
-      if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0))
-         textLine = quote_msg(gQuoteLines[pIndex], pMaxWidth-1, gQuotePrefix);
+      if (gConfigSettings.useQuoteLineInitials)
+      {
+         if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0))
+          textLine = gQuoteLines[pIndex].substr(0, pMaxWidth-1);
+      }
+      else
+      {
+         if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0))
+            textLine = quote_msg(gQuoteLines[pIndex], pMaxWidth-1, gQuotePrefix);
+      }
    }
    return textLine;
 }
@@ -2456,6 +2508,7 @@ function displayMessageRectangle(pX, pY, pWidth, pHeight, pEditLinesIndex, pClea
    var screenY = pY;
    var editLinesIndex = pEditLinesIndex;
    var formatStr = "%-" + pWidth + "s";
+   var actualLenWritten = 0; // Actual length of text written for each line
    for (var rectangleLine = 0; rectangleLine < pHeight; ++rectangleLine)
    {
       // Output the correct color for the line
@@ -2467,19 +2520,14 @@ function displayMessageRectangle(pX, pY, pWidth, pHeight, pEditLinesIndex, pClea
       // then print it; otherwise, just print spaces to blank out the line.
       if (typeof(gEditLines[editLinesIndex]) != "undefined")
       {
-         //printf(formatStr, gEditLines[editLinesIndex].text.substr(editLineIndex, pWidth));
-         //printEditLine(pIndex, pUseColors, pStart, pLength)
-         // TODO: Change the false to the parameter for whether or not to allow
-         // message colors
-         printEditLine(editLinesIndex, false, editLineIndex, pWidth);
+         actualLenWritten = printEditLine(editLinesIndex, false, editLineIndex, pWidth);
          // If pClearExtraWidth is true, then if the box width is longer than
          // the text that was written, then output spaces to clear the rest
          // of the line to erase the rest of the box line.
          if (pClearExtraWidth)
          {
-            var displayedTextLen = gEditLines[editLinesIndex].text.length - editLineIndex;
-            if (pWidth > displayedTextLen)
-               printf("%" + (pWidth-displayedTextLen) + "s", "");
+            if (pWidth > actualLenWritten)
+               printf("%" + +(pWidth-actualLenWritten) + "s", "");
          }
       }
       else
@@ -3496,10 +3544,12 @@ function doColorSelection(pCurpos, pCurrentWordLength)
 //  pLength: Integer - The length to write.  Optional.  If
 //           omitted, the entire line will be written.  <= 0 can be
 //           passed to write the entire string.
+//
+// Return value: The actual length of text written
 function printEditLine(pIndex, pUseColors, pStart, pLength)
 {
    if (typeof(pIndex) != "number")
-      return;
+      return 0;
    var useColors = true;
    var start = 0;
    var length = -1;
@@ -3518,7 +3568,7 @@ function printEditLine(pIndex, pUseColors, pStart, pLength)
       // that the screen is updated correctly
       for (var i = 0; i < length; ++i)
          console.print(" ");
-      return;
+      return length;
    }
    if (start < 0)
       start = 0;
@@ -3528,11 +3578,12 @@ function printEditLine(pIndex, pUseColors, pStart, pLength)
       // that the screen is updated correctly
       for (var i = 0; i < length; ++i)
          console.print(" ");
-      return;
+      return length;
    }
    //if (length > (gEditLines[pIndex].text.length - start))
    //   length = gEditLines[pIndex].text.length - start;
 
+   var lengthWritten = 0;
    if (useColors)
    {
    }
@@ -3544,18 +3595,27 @@ function printEditLine(pIndex, pUseColors, pStart, pLength)
       {
          // Simplest case: start is 0 and length is negative -
          // Just print the entire line.
+         lengthWritten = gEditLines[pIndex].text.length;
          if (length <= 0)
             console.print(gEditLines[pIndex].text);
          else
-            console.print(gEditLines[pIndex].text.substr(start, length));
+         {
+            var textToWrite = gEditLines[pIndex].text.substr(start, length);
+            console.print(textToWrite);
+            lengthWritten = textToWrite.length;
+         }
       }
       else
       {
          // Start is > 0
+         var textToWrite = "";
          if (length <= 0)
-            console.print(gEditLines[pIndex].text.substr(start));
+            textToWrite = gEditLines[pIndex].text.substr(start);
          else
-            console.print(gEditLines[pIndex].text.substr(start, length));
+            textToWrite = gEditLines[pIndex].text.substr(start, length);
+         console.print(textToWrite);
+         lengthWritten = textToWrite.length;
       }
    }
+   return lengthWritten;
 }
\ No newline at end of file
diff --git a/exec/SlyEdit_DCTStuff.js b/exec/SlyEdit_DCTStuff.js
index f6cce88a99abbea393b15b65391329881bc5910a..76376cbd0b19ac42c673afe9ea3abd9034e3a916 100644
--- a/exec/SlyEdit_DCTStuff.js
+++ b/exec/SlyEdit_DCTStuff.js
@@ -1,5 +1,4 @@
-/* This contains some DCTEdit-specific functions for the Digital Distortion
- * Editor which don't rely on any global variables.
+/* This file contains DCTEdit-specific functions for SlyEdit.
  *
  * Author: Eric Oulashin (AKA Nightfox)
  * BBS: Digital Distortion
@@ -880,7 +879,6 @@ function doDCTMenu(pEditLeft, pEditRight, pEditTop, pDisplayMessageRectangle,
          case KEY_DOWN:
             break;
          case KEY_ENTER: // Selected an item from the menu
-            //displayDebugText(1, 1, "Pressed Enter", null, false); // Temporary
             // Set userInput to the return code from the menu so that it will
             // be returned from this function.
             userInput = menuRetObj.returnVal;
@@ -903,7 +901,6 @@ function doDCTMenu(pEditLeft, pEditRight, pEditTop, pDisplayMessageRectangle,
             continueOn = false;
             break;
          default:
-            //displayDebugText(1, 1, "Last key:" + userInput + ":", null, true); // Temporary
             break;
 		}
    }
diff --git a/exec/SlyEdit_IceStuff.js b/exec/SlyEdit_IceStuff.js
index 7e193e987f29e47e6ec8c9496be243b71bb4b9ac..8d13550cee803f64b52a61f0b68f7470cee0a0cb 100644
--- a/exec/SlyEdit_IceStuff.js
+++ b/exec/SlyEdit_IceStuff.js
@@ -1,5 +1,4 @@
-/* This contains some IceEdit-specific functions for the Digital Distortion
- * Editor which don't rely on any global variables.
+/* This contains IceEdit-specific functions for SlyEdit.
  *
  * Author: Eric Oulashin (AKA Nightfox)
  * BBS: Digital Distortion
diff --git a/exec/SlyEdit_Misc.js b/exec/SlyEdit_Misc.js
index 0b832c524cc5bdc526a16df6939c862fa8fd89d9..c4e9d3dbe40847197c774c2ba9cbbf184981110b 100644
--- a/exec/SlyEdit_Misc.js
+++ b/exec/SlyEdit_Misc.js
@@ -1,5 +1,5 @@
-/* This file declares functions and variables that are used by Digital
- * Distortion Editor for both DCTEdit and IceEdit modes.
+/* This file declares some general helper functions and variables
+ * that are used by SlyEdit.
  *
  * Author: Eric Oulashin (AKA Nightfox)
  * BBS: Digital Distortion
@@ -39,9 +39,16 @@
  *                              was incorrectly dealing with quote lines that
  *                              were blank after the quote text.
  * 2012-12-21 Eric Oulashin     Updated to check for the .cfg files in the
- *                              /sbbs/ctrl directory first, and if they aren't
+ *                              sbbs/ctrl directory first, and if they aren't
  *                              there, assume they're in the same directory as
  *                              the .js file.
+ * 2012-12-23 Eric Oulashin     Worked on updating wrapQuoteLines() and
+ *                              firstNonQuoteTxtIndex() to support putting the
+ *                              "To" user's initials before the > in quote lines.
+ * 2012-12-25 Eric Oulashin     Updated wrapQuoteLines() to insert a > in quote
+ *                              lines right after the leading quote characters
+ *                              (if any), without a space afteward, to indicate
+ *                              an additional level of quoting.
  */
 
 // Note: These variables are declared with "var" instead of "const" to avoid
@@ -135,9 +142,6 @@ var CTRL_Y = "\x19";
 var CTRL_Z = "\x1a";
 var KEY_ESC = "\x1b";
 
-// gQuotePrefix contains the text to prepend to quote lines.
-var gQuotePrefix = " > ";
-
 ///////////////////////////////////////////////////////////////////////////////////
 // Object/class stuff
 
@@ -309,6 +313,8 @@ function isPrintableChar(pText)
 //  pLeading: Whether or not to trim leading spaces (optional, defaults to true)
 //  pMultiple: Whether or not to trim multiple spaces (optional, defaults to true)
 //  pTrailing: Whether or not to trim trailing spaces (optional, defaults to true)
+//
+// Return value: The trimmed string
 function trimSpaces(pString, pLeading, pMultiple, pTrailing)
 {
    // Make sure pString is a string.
@@ -457,7 +463,7 @@ function displayGeneralHelp(pDisplayHeader, pClear, pPause)
    if (pDisplayHeader)
       displayHelpHeader();
 
-   console.print("ncThis is a full-screen message editor that mimics the look & feel of\r\n");
+   console.print("ncSlyEdit is a full-screen message editor that mimics the look & feel of\r\n");
    console.print("IceEdit or DCT Edit, two popular editors.  The editor is currently in " +
                  (EDITOR_STYLE == "DCT" ? "DCT" : "Ice") + "\r\nmode.\r\n");
    console.print("At the top of the screen, information about the message being written (or\r\n");
@@ -522,7 +528,7 @@ function displayProgramInfo(pDisplayHeader, pClear, pPause)
                   EDITOR_VER_DATE + "w)");
    console.center("ncby Eric Oulashin");
    console.crlf();
-   console.print("ncThis is a full-screen message editor written for Synchronet that mimics\r\n");
+   console.print("ncSlyEdit is a full-screen message editor written for Synchronet that mimics\r\n");
    console.print("the look & feel of IceEdit or DCT Edit.");
    console.crlf();
    if (pPause)
@@ -632,8 +638,9 @@ function promptYesNo(pQuestion, pDefaultYes, pBoxTitle)
 // Return value: An object containing the settings as properties.
 function ReadSlyEditConfigFile()
 {
-   // Create the configuration object
-   var cfgObj = new Object();
+   var cfgObj = new Object(); // Configuration object
+
+   // Default settings
    cfgObj.thirdPartyLoadOnStart = new Array();
    cfgObj.runJSOnStart = new Array();
    cfgObj.thirdPartyLoadOnExit = new Array();
@@ -643,7 +650,9 @@ function ReadSlyEditConfigFile()
    cfgObj.inputTimeoutMS = 300000;
    cfgObj.reWrapQuoteLines = true;
    cfgObj.allowColorSelection = true;
-   // Ice-style colors
+   cfgObj.useQuoteLineInitials = true;
+
+   // Default Ice-style colors
    cfgObj.iceColors = new Object();
    // Ice color theme file
    cfgObj.iceColors.ThemeFilename = system.ctrl_dir + "SlyIceColors_BlueIce.cfg";
@@ -676,7 +685,7 @@ function ReadSlyEditConfigFile()
    cfgObj.iceColors.EditMode = "ch";
    cfgObj.iceColors.KeyInfoLabelColor = "ch";
 
-   // DCT-style colors
+   // Default DCT-style colors
    cfgObj.DCTColors = new Object();
    // DCT color theme file
    cfgObj.DCTColors.ThemeFilename = system.ctrl_dir + "SlyDCTColors_Default.cfg";
@@ -815,6 +824,8 @@ function ReadSlyEditConfigFile()
                   cfgObj.reWrapQuoteLines = (valueUpper == "TRUE");
                else if (settingUpper == "ALLOWCOLORSELECTION")
                   cfgObj.allowColorSelection = (valueUpper == "TRUE");
+               else if (settingUpper == "USEQUOTELINEINITIALS")
+                  cfgObj.useQuoteLineInitials = (valueUpper == "TRUE");
                else if (settingUpper == "ADD3RDPARTYSTARTUPSCRIPT")
                   cfgObj.thirdPartyLoadOnStart.push(value);
                else if (settingUpper == "ADD3RDPARTYEXITSCRIPT")
@@ -1455,6 +1466,7 @@ function firstNonQuoteTxtIndex(pStr)
   var retObj = new Object();
   retObj.startIndex = -1;
   retObj.quoteLevel = 0;
+  retObj.begOfLine = ""; // Will store the beginning of the line, before the >
 
   // If pStr is not a valid positive-length string, then just return.
   if ((pStr == null) || (typeof(pStr) != "string") || (pStr.length == 0))
@@ -1465,7 +1477,7 @@ function firstNonQuoteTxtIndex(pStr)
   // & count the > characters from the >.
   var searchStartIndex = 0;
   // Regex notes:
-  //  \w: Matches any alphanumerical character (word characters) including underscore (short for [a-zA-Z0-9_])
+  //  \w: Matches any alphanumeric character (word characters) including underscore (short for [a-zA-Z0-9_])
   //  ?: Supposed to match 0 or 1 occurance, but seems to match 1 or 2
   var lineStartsWithQuoteText = /^ *\w?[^ ]>/.test(pStr);
   if (lineStartsWithQuoteText)
@@ -1477,6 +1489,7 @@ function firstNonQuoteTxtIndex(pStr)
   // Look for the first non-quote text and quote level in the string.
   var strChar = "";
   var j = 0;
+  var GTIndex = -1; // Index of a > character in the string
   for (var i = searchStartIndex; i < pStr.length; ++i)
   {
     strChar = pStr.charAt(i);
@@ -1494,6 +1507,8 @@ function firstNonQuoteTxtIndex(pStr)
             ++retObj.quoteLevel;
         }
       }
+      // Store the beginning of the line in retObj.begOfLine
+      retObj.begOfLine = pStr.substr(0, retObj.startIndex);
       break;
     }
   }
@@ -1510,15 +1525,19 @@ function firstNonQuoteTxtIndex(pStr)
   return retObj;
 }
 
-function wrapQuoteLines()
+function wrapQuoteLines(pUseAuthorInitials)
 {
   if (gQuoteLines.length == 0)
     return;
 
+  var useAuthorInitials = true;
+  if (typeof(pUseAuthorInitials) != "undefined")
+    useAuthorInitials = pUseAuthorInitials;
+
   // This function checks if a string has only > characters separated by
   // whitespace and returns a version where the > characters are only separated
-  // by one space each, and if the line starts with " >", the leading space
-  // will be removed.
+  // by one space each.  If the line starts with " >", the leading space will
+  // be removed.
   function normalizeGTChars(pStr)
   {
     if (/^\s*>\s*$/.test(pStr))
@@ -1532,6 +1551,8 @@ function wrapQuoteLines()
     return pStr;
   }
 
+  // Note: gQuotePrefix is declared in SlyEdit.js.
+
   // Create an array for line information objects, and append the
   // first line's info to it.  Also, store the first line's quote
   // level in the lastQuoteLevel variable.
@@ -1543,23 +1564,25 @@ function wrapQuoteLines()
   // Loop through the array starting at the 2nd line and wrap the lines
   var startArrIndex = 0;
   var endArrIndex = 0;
-  var quoteStr = "";
+  var quotePrefix = "";
   var quoteLevel = 0;
   var retObj = null;
   var i = 0; // Index variable
+  var maxBegOfLineLen = 0; // For storing the length of the longest beginning of line that was removed
   for (var quoteLineIndex = 1; quoteLineIndex < gQuoteLines.length; ++quoteLineIndex)
   {
     retObj = firstNonQuoteTxtIndex(gQuoteLines[quoteLineIndex]);
     lineInfos.push(retObj);
     if (retObj.quoteLevel != lastQuoteLevel)
     {
+      maxBegOfLineLen = 0;
       endArrIndex = quoteLineIndex;
       // Remove the quote strings from the lines we're about to wrap
       for (i = startArrIndex; i < endArrIndex; ++i)
       {
-        // TODO
-        // Error on next line: !JavaScript  TypeError: lineInfos[i] is undefined
-        // Fixed by checking that lineInfos[i] is not null..  but why would it be?
+        // lineInfos[i] is checked for null to avoid the error "!JavaScript
+        // TypeError: lineInfos[i] is undefined".  But I'm not sure why it
+        // would be null..
         if (lineInfos[i] != null)
         {
           if (lineInfos[i].startIndex > -1)
@@ -1568,18 +1591,42 @@ function wrapQuoteLines()
             gQuoteLines[i] = normalizeGTChars(gQuoteLines[i]);
           // If the quote line now only consists of spaces after removing the quote
           // characters, then make it blank.
-          if (/^ +$/.test(gQuoteLines[i])) gQuoteLines[i] = "";
+          if (/^ +$/.test(gQuoteLines[i]))
+            gQuoteLines[i] = "";
+          // Remove leading spaces and change multiple spaces to single
+          // spaces in the beginning-of-line string.
+          lineInfos[i].begOfLine = trimSpaces(lineInfos[i].begOfLine, true, true, false);
+          // See if we need to update maxBegOfLineLen, and if so, do it.
+          if (lineInfos[i].begOfLine.length > maxBegOfLineLen)
+            maxBegOfLineLen = lineInfos[i].begOfLine.length;
         }
       }
+      // If maxBegOfLineLen is non-zero, then add 1 more to it because
+      // we'll be adding a > character to the quote lines to signify one
+      // more level of quoting.
+      if (maxBegOfLineLen > 0)
+        ++maxBegOfLineLen;
+      // Add gQuotePrefix's length to maxBegOfLineLen to account for that
+      // for wrapping the text. Note: In future versions, if we don't want
+      // to add the previous author's initials to all lines, then we might
+      // not automatically want to add this to every line.
+      maxBegOfLineLen += gQuotePrefix.length;
       // Wrap the text lines in the range we've seen
       // Note: 79 is assumed as the maximum line length because
       // that seems to be a commonly-accepted message width for
-      // BBSs.  Also, the following length is subtracted from it:
-      // (2*(lastQuoteLevel+1) + gQuotePrefix.length)
-      // That is because we'll be prepending "> " to the quote lines,
-      // and then SlyEdit will prepend gQuotePrefix to them during quoting.
+      // BBSs.  So, we need to subtract the maximum "beginning
+      // of line" length from 79 and use that as the wrapping
+      // length.
       var numLinesBefore = gQuoteLines.length;
-      wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length));
+
+      // Wrap the text lines.  If using new-style quote lines preservation,
+      // use maxBegOfLineLen as the basis of where to wrap.  Otherwise (for
+      // older style without author initials), calculate the width based on
+      // the quote level and number of " > " strings we'll insert.
+      if (useAuthorInitials)
+        wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - maxBegOfLineLen);
+      else
+        wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length));
       // If quote lines were added as a result of wrapping, then
       // determine the number of lines added, and update endArrIndex
       // and quoteLineIndex accordingly.
@@ -1589,27 +1636,104 @@ function wrapQuoteLines()
         endArrIndex += numLinesAdded;
         quoteLineIndex += (numLinesAdded-1); // - 1 because quoteLineIndex will be incremented by the for loop
       }
-      // Put quote strings ("> ") back into the lines we just wrapped
+      // Put the beginnings of the wrapped lines back on them.
       if ((quoteLineIndex > 0) && (lastQuoteLevel > 0))
       {
-        quoteStr = "";
-        for (i = 0; i < lastQuoteLevel; ++i)
-          quoteStr += "> ";
-        for (i = startArrIndex; i < endArrIndex; ++i)
-          gQuoteLines[i] = quoteStr + gQuoteLines[i].replace(/^\s*>/, ">");
+        // If using the author's initials in the quote lines, then
+        // do it the new way.  Otherwise, do it the old way where
+        // we just insert "> " back in the beginning of the quote
+        // lines.
+        if (useAuthorInitials)
+        {
+          for (i = startArrIndex; i < endArrIndex; ++i)
+          {
+            if (lineInfos[i] != null)
+            {
+              // If the beginning of the line has a non-zero length,
+              // then add a > at the end to signify that this line is
+              // being quoted again.
+              var begOfLineLen = lineInfos[i].begOfLine.length;
+              if (begOfLineLen > 0)
+              {
+                if (lineInfos[i].begOfLine.charAt(begOfLineLen-1) == " ")
+                  lineInfos[i].begOfLine = lineInfos[i].begOfLine.substr(0, begOfLineLen-1) + "> ";
+                else
+                  lineInfos[i].begOfLine += ">";
+              }
+              // Re-assemble the quote line
+              gQuoteLines[i] = lineInfos[i].begOfLine + gQuoteLines[i];
+            }
+            else
+            {
+              // Old style: Put quote strings ("> ") back into the lines
+              // we just wrapped.
+              quotePrefix = "";
+              for (i = 0; i < lastQuoteLevel; ++i)
+                quotePrefix += "> ";
+              gQuoteLines[i] = quotePrefix + gQuoteLines[i].replace(/^\s*>/, ">");
+            }
+          }
+        }
+        else
+        {
+          // Not using author initials in the quote lines.
+          // Old style: Put quote strings ("> ") back into the lines
+          // we just wrapped.
+          quotePrefix = "";
+          for (i = 0; i < lastQuoteLevel; ++i)
+            quotePrefix += "> ";
+          for (i = startArrIndex; i < endArrIndex; ++i)
+            gQuoteLines[i] = quotePrefix + gQuoteLines[i].replace(/^\s*>/, ">");
+        }
       }
+
       lastQuoteLevel = retObj.quoteLevel;
       startArrIndex = quoteLineIndex;
+
+      if (useAuthorInitials)
+      {
+        // For quoting only the last author's lines: Insert gQuotePrefix
+        // to the front of the quote lines.  gQuotePrefix contains the
+        // last message author's initials.
+        if (retObj.quoteLevel == 0)
+        {
+          if ((gQuoteLines[i].length > 0) && (gQuoteLines[i].indexOf(gQuotePrefix) != 0))
+            gQuoteLines[i] = gQuotePrefix + gQuoteLines[i];
+        }
+      }
+    }
+  }
+
+  // Wrap the last block of lines: This is the block that contains
+  // (some of) the last message's author's reply to the quoted lines
+  // above it.
+  // Then, go through the quote lines again, and for ones that start with " >",
+  // remove the leading whitespace.  This is because the quote string is " > ",
+  // so it would insert an extra space before the first > in the quote line.
+  // Also, if using author initials, quote the last author's lines by inserting
+  // gQuotePrefix to the front of the quote lines.  gQuotePrefix contains the
+  // last message author's initials.
+  if (useAuthorInitials)
+  {
+    wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - gQuotePrefix.length);
+    for (i = 0; i < gQuoteLines.length; ++i)
+    {
+      // Remove leading whitespace from > characters
+      gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">");
+      // Quote the last author's lines with gQuotePrefix
+      if ((lineInfos[i] != null) && (lineInfos[i].quoteLevel == 0))
+      {
+        if ((gQuoteLines[i].length > 0) && (gQuoteLines[i].indexOf(gQuotePrefix) != 0))
+          gQuoteLines[i] = gQuotePrefix + gQuoteLines[i];
+      }
     }
   }
-  // Wrap the last block of lines
-  wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length));
-
-  // Go through the quote lines again, and for ones that start with " >", remove
-  // the leading whitespace.  This is because the quote string is " > ", so it
-  // would insert an extra space before the first > in the quote line.
-  for (i = 0; i < gQuoteLines.length; ++i)
-    gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">");
+  else
+  {
+    wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length));
+    for (i = 0; i < gQuoteLines.length; ++i)
+      gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">");
+  }
 }
 
 // This function displays debug text at a given location on the screen, then