void
CBCompileDocument::AppendText
	(
	const JString& origText
	)
{
	const JString* text = &origText;
	JBoolean deleteText = kJFalse;
	if (strchr(*text, kMultibyteMarker) != NULL)
		{
		JString* s = jnew JString(origText);
		assert( s != NULL );
		text       = s;
		deleteText = kJTrue;

		JSize length = s->GetLength();
		for (JIndex i=1; i<=length; i++)
			{
			if (s->GetCharacter(i) == kMultibyteMarker && i <= length-2)
				{
				const unsigned char c1 = s->GetCharacter(i+1);
				const unsigned char c2 = s->GetCharacter(i+2);
				const JIndex u = (((unsigned int) (unsigned char) c1) << 8) |
								 ((unsigned int) (unsigned char) c2);

				if (u == 32920 || u == 32921)
					{
					s->ReplaceSubstring(i, i+2, "'");
					}
				else
					{
					std::cout << "jcc: AppendText: unicode: " << u << std::endl;
					s->ReplaceSubstring(i, i+2, "\x80");
					}

				length -= 2;
				}
			}
		}

	const JBoolean isJavacError = javacOutputRegex.Match(*text);

	JIndexRange gccPrevLineRange, gccRange;
	const JBoolean isGCCError = JI2B(!isJavacError && gccErrorRegex.Match(*text, &gccRange));

	JIndexRange flexRange;
	const JBoolean isFlexError = flexErrorRegex.Match(*text, &flexRange);

	JIndexRange bisonRange;
	const JBoolean isBisonError = bisonErrorRegex.Match(*text, &bisonRange);

	JIndexRange makeRange;
	const JBoolean isMakeError = JI2B(
		makeErrorRegex.Match(*text, &makeRange) && !text->EndsWith(makeIgnoreErrorStr) );

	JArray<JIndexRange> absoftRangeList;
	const JBoolean isAbsoftError = absoftErrorRegex.Match(*text, &absoftRangeList);

	JArray<JIndexRange> maven2RangeList;
	const JBoolean isMaven2Error = maven2ErrorRegex.Match(*text, &maven2RangeList);

	JArray<JIndexRange> maven3RangeList;
	const JBoolean isMaven3Error = maven3ErrorRegex.Match(*text, &maven3RangeList);

	if (isGCCError &&
		gccErrorRegex.Match(itsPrevLine, &gccPrevLineRange) &&
		gccPrevLineRange == gccRange &&
		JCompareMaxN(itsPrevLine, *text, gccRange.last, kJTrue))
		{
		JString s = *text;
		s.RemoveSubstring(1, gccRange.last - 1);
		s.Prepend(" /");

		// in front of 1 or 2 trailing newlines

		CBTextEditor* te = GetTextEditor();
		te->SetCaretLocation(te->GetTextLength() - (theDoubleSpaceFlag ? 1 : 0));
		te->Paste(s);
		}
	else if (!isJavacError && !isGCCError &&
			 gccErrorRegex.Match(itsPrevLine, &gccPrevLineRange) &&
			 text->BeginsWith(gccMultilinePrefix) &&
			 text->GetLength() > kGCCMultilinePrefixLength &&
			 !isspace(text->GetCharacter(kGCCMultilinePrefixLength+1)))
		{
		JString s = *text;
		s.RemoveSubstring(1, strlen(gccMultilinePrefix));

		CBTextEditor* te = GetTextEditor();
		te->SetCaretLocation(te->GetTextLength() - (theDoubleSpaceFlag ? 1 : 0));
		te->Paste(s);
		}
	else
		{
		CBTextEditor* te        = GetTextEditor();
		const JIndex startIndex = te->GetTextLength() + 1;

		CBExecOutputDocument::AppendText(*text);
		if (theDoubleSpaceFlag)
			{
			te->Paste("\n");
			}

		itsPrevLine = *text;

		// display file name in bold and activate Errors menu

		JIndexRange boldRange;
		if (isJavacError)
			{
			JArray<JIndexRange> javacMatchList;
			if (javacErrorRegex.Match(*text, &javacMatchList))
				{
				const JIndexRange r = javacMatchList.GetElement(2);
				boldRange.Set(startIndex + r.first-1, startIndex + r.last-1);
				}
			}
		else if (isGCCError)
			{
			boldRange.Set(startIndex, startIndex + gccRange.first - 1);
			}
		else if (isFlexError)
			{
			boldRange.Set(startIndex+1, startIndex + flexRange.first);
			}
		else if (isBisonError)
			{
			boldRange.Set(startIndex+2, startIndex + bisonRange.first + 1);
			}
		else if (isMakeError)
			{
			boldRange.SetFirstAndLength(startIndex, text->GetLength());
			}
		else if (isAbsoftError)
			{
			boldRange  = absoftRangeList.GetElement(2);
			boldRange += startIndex-1;
			}
		else if (isMaven2Error)
			{
			boldRange  = maven2RangeList.GetElement(2);
			boldRange += startIndex-1;
			}
		else if (isMaven3Error)
			{
			boldRange  = maven3RangeList.GetElement(2);
			boldRange += startIndex-1;
			}

		if (!boldRange.IsEmpty())
			{
			te->JTextEditor::SetFont(boldRange.first, boldRange.last, GetErrorFont(), kJTrue);

			if (!itsHasErrorsFlag)
				{
				itsHasErrorsFlag = kJTrue;
				itsErrorMenu->Activate();

				JXWindow* window    = GetWindow();
				JString windowTitle = window->GetTitle();
				windowTitle.SetCharacter(1, '!');
				windowTitle.SetCharacter(2, '!');
				windowTitle.SetCharacter(3, '!');
				window->SetTitle(windowTitle);
				}
			}
		}

	if (deleteText)
		{
		jdelete text;
		}
}