//
//  XTOutputFormatterTests.m
//  TadsTerp
//
//  Created by Rune Berg on 15/07/14.
//  Copyright (c) 2014 Rune Berg. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "XTOutputFormatter.h"
#import "XTFormattedOutputElement.h"
#import "XTHtmlTagHr.h"
#import "XTHtmlTagB.h"
#import "XTHtmlTagI.h"
#import "XTHtmlTagU.h"
#import "XTHtmlTagQ.h"
#import "XTHtmlTagAboutBox.h"
#import "XTHtmlTagBanner.h"
#import "XTHtmlTagCenter.h"
#import "XTHtmlTagH1.h"
#import "XTHtmlTagH2.h"
#import "XTHtmlTagH3.h"
#import "XTHtmlTagH4.h"
#import "XTHtmlTagOl.h"
#import "XTHtmlTagUl.h"
#import "XTHtmlTagLi.h"
#import "XTHtmlTagNoop.h"
#import "XTHtmlTagQuestionMarkT2.h"
#import "XTHtmlTagQuestionMarkT3.h"
#import "XTHtmlTagTt.h"
#import "XTHtmlTagTab.h"
#import "XTHtmlTagDiv.h"
#import "XTHtmlTagBr.h"
#import "XTHtmlTagP.h"
#import "XTHtmlTagImg.h"
#import "XTHtmlTagTitle.h"
#import "XTHtmlTagBlockQuote.h"
#import "XTHtmlTagPre.h"
#import "XTHtmlWhitespace.h"
#import "XTHtmlQuotedSpace.h"
#import "XTHtmlNonbreakingSpace.h"
#import "XTHtmlSpecialSpace.h"
#import "XTOutputTextParserHtml.h"
#import "XTStringUtils.h"


@interface XTOutputFormatterTests : XCTestCase

@property XTOutputFormatter *formatter;

@end


@implementation XTOutputFormatterTests

#define ENSP_DEC 8194
#define ENSP_FMTD @"  "
#define EMSP_DEC 8195
#define EMSP_FMTD @"    "
#define FIGSP_DEC 8199
#define FIGSP_FMTD @"  "
#define NBSP_FMTD @" "

#define TAB_FMTD @" \t"
	//TODO use consistently

#define HR_MINIMAL @"–"

- (void)setUp
{
    [super setUp];
	self.formatter = [XTOutputFormatter new];
	self.formatter.htmlMode = YES;
	[self.formatter resetFlags];
}

- (void)tearDown
{
    [super tearDown];
}

//TODO refactor typical result checks in to funcs / macros

- (NSArray *)formatParsedElements:(NSArray *)parsedElements
{
	NSMutableArray *res = [NSMutableArray new];
	for (id pe in parsedElements) {
		NSArray *fea = [self.formatter formatElement:pe];
		if (fea != nil) {
			[res addObjectsFromArray:fea];
		}
	}
	return res;
}

//------- Pending whitespace ------------

//TODO section in progress...

- (void)testBasic_text
{
	NSArray *parsedElements = @[
		@"a"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)testBasic_textText
{
	NSArray *parsedElements = @[
		@"a",
		@"b"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)testBasic_ws
{
	NSArray *parsedElements = @[
		[self makeWhitespace]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)testBasic_wsWs
{
	NSArray *parsedElements = @[
		[self makeWhitespace],
		[self makeWhitespace]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)testBasic_textWs
{
	NSArray *parsedElements = @[
		@"a",
		[self makeWhitespace]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(1, outputElements.count);

	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)testBasic_textWsWs
{
	NSArray *parsedElements = @[
		@"a",
		[self makeWhitespace],
		[self makeWhitespace]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)testBasic_textWsText
{
	NSArray *parsedElements = @[
		@"a",
		[self makeWhitespace],
		@"b",
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)testBasic_textWsText_2
{
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespaceWithText:@"\n"],
	  @"b",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)testBasic_textWsText_2b
{
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespaceWithText:@"\n \n"],
	  @"b",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)testBasic_textWsTextWsText
{
	NSArray *parsedElements = @[
		@"a",
		[self makeWhitespace],
		@"b",
		[self makeWhitespace],
		@"c",
		];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"c");
}

- (void)testBasic_textWsWsText
{
	NSArray *parsedElements = @[
		@"a",
		[self makeWhitespace],
		[self makeWhitespace],
		@"b",
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)testBasic_wsText
{
	NSArray *parsedElements = @[
		[self makeWhitespace],
		@"a"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)testBasic_wsWsText
{
	NSArray *parsedElements = @[
		[self makeWhitespace],
		[self makeWhitespace],
		@"a"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)testBasic_wsTextWs
{
	NSArray *parsedElements = @[
		[self makeWhitespace],
		@"a",
		[self makeWhitespace],
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

//----

- (void)test_pendingWs_wsTextBopenTextBcloseText
{
	// " (<b>b</b>)n"
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  @"(",
	  [self makeTagBOpen],
	  @"b",
	  [self makeTagBClose],
	  @")n"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"(");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @")n");
}

- (void)test_pendingWs_wsTextBopenTextWsBcloseText
{
	// " (<b>b </b>)n"
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  @"(",
	  [self makeTagBOpen],
	  @"b",
	  [self makeWhitespace],
	  [self makeTagBClose],
	  @")n"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"(");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @")n");
}

//TODO variations?

//----

- (void)test_pendingWs_textWsBrText
{
	/*
	 "ab <br>cd";
	 */
	
	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeWhitespace],
	  [self makeTagBr],
	  @"cd",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_pendingWs_textWsPopenText
{
	/*
	 "ab <p>cd";
	 */
	
	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeWhitespace],
	  [self makeTagPOpen],
	  @"cd",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_pendingWs_popenTextPcloseWsText
{
	/*
	 "<p>para</p> after";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  @"para",
	  [self makeTagPClose],
	  [self makeWhitespace],
	  @"after",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"para");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"after");
}

- (void)test_pendingWs_textBrWsText
{
	/*
	 "ab<br> cd";
	 */
	
	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeTagBr],
	  [self makeWhitespace],
	  @"cd",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_pendingWs_textWsBrWsText
{
	/*
	 "ab <br> cd";
	 */
	
	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace],
	  @"cd",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_pendingWs_wsBrWsText
{
	/*
	 " <br> cd";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace],
	  @"cd",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_pendingWs_wsBrWs
{
	/*
	 " <br> ";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_pendingWs_wsBrWsBrWs
{
	/*
	 " <br>  <br> ";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_pendingWs_wsBrWsTextWsBrWs
{
	/*
	 " <br> a <br> ";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace],
	  @"a",
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeWhitespace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_pendingWs_wsPopenWsTextWsPopenWs
{
	/*
	 " <p> a <p> ";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagPOpen],
	  [self makeWhitespace],
	  @"a",
	  [self makeWhitespace],
	  [self makeTagPOpen],
	  [self makeWhitespace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_pendingWs_wsPopenWsTextWsPopenWsText
{
	/*
	 " <p> a <p> b";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagPOpen],
	  [self makeWhitespace],
	  @"a",
	  [self makeWhitespace],
	  [self makeTagPOpen],
	  [self makeWhitespace],
	  @"b",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

//------ Pending ws misc. ----------

- (void)test_pendingWs_tagQ_1
{
	/*
	 "a <Q>b</Q> c";
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeTagQOpen],
	  @"b",
	  [self makeTagQClose],
	  [self makeWhitespace],
	  @"c"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(7, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\"");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\"");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"c");
}

- (void)test_pendingWs_tagQ_2
{
	/*
	 "a <Q> b </Q> c";
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeTagQOpen],
	  [self makeWhitespace],
	  @"b",
	  [self makeWhitespace],
	  [self makeTagQClose],
	  [self makeWhitespace],
	  @"c"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\"");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\"");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"c");
}

//------- TODO label -------------

- (void)testHr //TODO rename
{
	NSArray *parsedElements = @[
		[XTHtmlTagHr new]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertTrue([XTStringUtils string:outElt.attributedString.string startsWith:HR_MINIMAL]);

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)testBeetmongerBannerMissingNewlineBugSimplified
{
	/* BUG was: qtads / zoom / frob print 2 newlines before "[For ..." - xtads only prints one for:
	 
	 "Foo<hr>
	 <BR HEIGHT=0>
	 Bar";
 
	 TODO test w/o ws elements too
	 */

	NSArray *parsedElements = @[
		@"Foo",
		[XTHtmlTagHr new],
		[XTHtmlWhitespace new],
		[self makeTagBr0],
		@"Bar",
	];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);

	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Foo");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertTrue([XTStringUtils string:outElt.attributedString.string startsWith:HR_MINIMAL]);

	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Bar");
	
}

- (void)testBeetmongerBannerMissingNewlineBug
{
    /* BUG was: qtads / zoom / frob print 2 newlines before "[For ..." - xtads only prints one for:
	 
    "McGee<hr>
    <BR HEIGHT=0>
    <BR>[For information";
     */

	NSArray *parsedElements = @[
		@"McGee",
		[XTHtmlTagHr new],
		[XTHtmlWhitespace new],
		[self makeTagBr0],
		[XTHtmlWhitespace new],
		[XTHtmlTagBr new],
		@"[For information"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"McGee");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertTrue([XTStringUtils string:outElt.attributedString.string startsWith:HR_MINIMAL]);

	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"[For information");
}

//--------------------------------------------------------

- (void)test_gold_tabsBefore1stLocDescBug_simplified
{
	/* Bug was: 2 unwanted tabs before "Desc" for:
	 
	 "<P>Outside cave";
	 "<BR HEIGHT=0>";
	 "<TAB MULTIPLE=4>";
	 "<BR HEIGHT=0>";
	 "<TAB MULTIPLE=4><BR>Desc";
	 */
	
	NSArray *parsedElements = @[
		@"Outside cave",
		[self makeTagBr0],
		[self makeTagTabWithMultiple:4],
		[self makeTagBr],
		@"Desc",
	];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);

	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Outside cave");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt.htmlTag);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Desc");
}

//TODO test with *actual* elts from comment in test above

//----- Basic <tab> handling ---------------------------------------------------

- (void)test_basicTab_1
{
	// "<tab multiple=4>abc"

	NSArray *parsedElements =
	@[
	  [self makeTagTabWithMultiple:4],
	  @"abc"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt.htmlTag);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"abc");
}

- (void)test_basicTab_2
{
	// " <tab multiple=4>abc"
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagTabWithMultiple:4],
	  @"abc"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt.htmlTag);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"abc");
}

- (void)test_basicTab_3
{
	// "<tab multiple=4> abc"
	
	NSArray *parsedElements =
	@[
	  [self makeTagTabWithMultiple:4],
	  [self makeWhitespace],
	  @"abc"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt.htmlTag);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"abc");
}

- (void)test_basicTab_4
{
	// " <tab multiple=4> abc"
	
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeTagTabWithMultiple:4],
	  [self makeWhitespace],
	  @"abc"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt.htmlTag);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"abc");
}

- (void)test_basicTab_10
{
	// "<tab>a";

	NSArray *parsedElements =
	@[
	  [self makeTagTabWithoutMultiple],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_basicTab_11
{
	// "<tab><tab>a";
	
	NSArray *parsedElements =
	@[
	  [self makeTagTabWithoutMultiple],
	  [self makeTagTabWithoutMultiple],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_basicTab_12
{
	// "a <tab> b";
	
	//...
	
	//TODO qtads -> "a 	b" i.e. "a", space, tab, "b" - but visually it's "a b"
}


//TODO more...

//--------------------------------------------------------

- (void)test_Ol_1li
{
	//"<ol><li>item1</li></ol>";
	
	NSArray *parsedElements = @[
		[self makeTagOlOpen],
		[self makeTagLiOpen],
		@"item1",
		[self makeTagLiClose],
		[self makeTagOlClose]
		];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"1.");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\t");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item1");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_Ol_2li
{
	//"<ol><li>item1</li><li>item2</li></ol>";

	NSArray *parsedElements = @[
	  [self makeTagOlOpen],
	  [self makeTagLiOpen],
	  @"item1",
	  [self makeTagLiClose],
	  [self makeTagLiOpen],
	  @"item2",
	  [self makeTagLiClose],
	  [self makeTagOlClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(10, outputElements.count);

	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"1.");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\t");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item1");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"2.");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\t");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item2");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	//TODO should be another nl here...
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

//TODO make ditto test for </ol>
- (void)test_ulClose_outsideListModes
{
	//"<li>item1</li>";
	
	NSArray *parsedElements =
	@[
	  [self makeTagUlClose],
	  @"item1"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item1");
}

//TODO more tests on this theme...

- (void)test_P_oneEmptyPg
{
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  [self makeTagPClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_P_twoEmptyPgs
{
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  [self makeTagPOpen],
	  [self makeTagPClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_P_threeEmptyPgs
{
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  [self makeTagPOpen],
	  [self makeTagPClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_P_br0BetweenTwoEmptyPgs
{
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  [self makeTagBr0],
	  [self makeTagPOpen],
	  [self makeTagPClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_P_oneEmptyPgBeforeText
{
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  @"After"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"After");
}

- (void)test_P_oneEmptyPgAfterText
{
	NSArray *parsedElements =
	@[
	  @"Before",
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_P_oneEmptyPgBetweenTexts
{
	NSArray *parsedElements =
	@[
	  @"Before",
	  [self makeTagPOpen],
	  [self makeTagPClose],
	  @"After",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"After");
}

- (void)test_P_twoPgsBetweenText
{
	/* Before<p>pg1</p><p>og2</p>After */
	
	NSArray *parsedElements =
	@[
	  @"Before",
	  [self makeTagPOpen],
	  @"pg1",
	  [self makeTagPClose],
	  [self makeTagPOpen],
	  @"pg2",
	  [self makeTagPClose],
	  @"After",
	  ];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"pg1");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"pg2");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"After");
	
	/*TODO
	 and more variants...
	 and variants with <br ...>
		esp mismatched / repeated opens / closes
	 */
}

- (void)test_br0AfterP
{
	// "Before<p>pg1</p><br height=0>After";

	NSArray *parsedElements =
	@[
	  @"Before",
	  [self makeTagPOpen],
	  @"pg1",
	  [self makeTagPClose],
	  [self makeTagBr0],
	  @"After"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"pg1");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"After");
}

- (void)test_br0AfterP_2
{
	// "Before<p>pg1</p><br height=0>After";
	
	NSArray *parsedElements =
	@[
	  @"Before",
	  [self makeTagPOpen],
	  @"pg1",
	  [self makeTagPClose],
	  [self makeTagBr0],
	  @"After"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	NSUInteger i = 0;
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"pg1");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"After");
}

//------- blockquote ------

- (void)test_blockquoteAlone
{
	/*
	 <blockquote>bq1</blockquote>
	*/

	NSArray *parsedElements =
	@[
	  [self makeTagBlockquoteOpen],
	  @"bq1",
	  [self makeTagBlockquoteClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_blockquoteAfterText
{
	/*
	 "text1
	 <blockquote>bq1</blockquote>
	 */
	
	NSArray *parsedElements =
	@[
	  @"text1",
	  [self makeTagBlockquoteOpen],
	  @"bq1",
	  [self makeTagBlockquoteClose],
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text1");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_blockquoteBeforeText
{
	/*
	 <blockquote>bq1</blockquote>
	 text2
	 */

	NSArray *parsedElements =
	@[
	  [self makeTagBlockquoteOpen],
	  @"bq1",
	  [self makeTagBlockquoteClose],
	  @"text2",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text2");
}

- (void)test_blockquoteBetweenTexts
{
	/*
	 "text1
	 <blockquote>bq1</blockquote>
	 text2
	 */
	
	NSArray *parsedElements =
	@[
	  @"text1",
	  [self makeTagBlockquoteOpen],
	  @"bq1",
	  [self makeTagBlockquoteClose],
	  @"text2",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(7, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text1");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text2");
}

//TODO nested bq's
//TODO more blockquote tests?

//------- Misc. special spaces -------

- (void)test_specialSpaces_ensp_tSt // text - Special space - test
{
	// "m&#8194;r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:ENSP_DEC],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tSst // text - Special space - (regular) space - test
{
	// "m&#8194; r"   -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tSsst // text - Special space - (regular) space - (regular) space - test
{
	// "m&#8194;  r"   -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tsSt
{
	// "m &#8194;r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tsSst
{
	// "m &#8194; r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tssSt
{
	// "m  &#8194;r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tssSsst
{
	// "m  &#8194;  r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tSSt
{
	// "m&#8194;&#8194;r" -> "m    r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeSpecialSpace:ENSP_DEC],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tsSSst
{
	// "m &#8194;&#8194; r" -> "m    r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_ensp_tsSsSst
{
	// "m &#8194; &#8194; r" -> "m    r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  [self makeSpecialSpace:ENSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, ENSP_FMTD);
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_emsp_tSt
{
	// "m&#8195;r" -> "m    r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:EMSP_DEC],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, EMSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_emsp_tSst
{
	// "m&#8195; r" -> "m    r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:EMSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, EMSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_emsp_tsSsSst
{
	// "m &#8195; &#8195; r" -> "m        r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeSpecialSpace:EMSP_DEC],
	  [self makeWhitespace],
	  [self makeSpecialSpace:EMSP_DEC],
	  [self makeWhitespace],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, EMSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, EMSP_FMTD);
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

- (void)test_specialSpaces_figsp_tSt // text - Special space - test
{
	// "m&#8199;r" -> "m  r"
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeSpecialSpace:FIGSP_DEC],
	  @"r"
	  ];
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, FIGSP_FMTD);
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}


//TODO "mud. \  \  Rain" -> "mud.  Rain"

//------- Special (typographical) spaces when monosize font -------

- (void)test_specialSpaces_monofont_ensp
{
	// "<pre>a&ensp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2002],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"  "); // 2 spaces
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_emsp
{
	// "<pre>a&emsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2003],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"   "); // 3 spaces
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_tpmsp
{
	// "<pre>a&tpmsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2004],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"  "); // 2 spaces
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_fpmsp
{
	// "<pre>a&fpmsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2005],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_spmsp
{
	// "<pre>a&spmsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2006],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_figsp
{
	// "<pre>a&figsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2007],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_puncsp
{
	// "<pre>a&puncsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2008],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_thinsp
{
	// "<pre>a&thinsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x2009],
	  @"b",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_specialSpaces_monofont_hairsp
{
	// "<pre>a&hairsp;b</pre>"
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"a",
	  [self makeSpecialSpace:0x200A],
	  @"b",
	  [self makeTagPreClose]
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

//------- Quoted spaces ------
/*
 standard TADS quoted space behavior: a quoted space doesn't combine with adjacent quoted spaces, but does allow a line break. Any regular space characters adjacent to the quoted space in the source string are removed.
 */

- (void)test_quotedSpaces_tsqst
{
	/*
	 "a \  b"
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_quotedSpaces_q
{
	/*
	 "\ "
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace]
	];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)test_quotedSpaces_qt
{
	/*
	 "\ a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_qq
{
	/*
	 "\ \ "
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  [self makeQuotedSpace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)test_quotedSpaces_qqt
{
	/*
	 "\ \ a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_sq
{
	/*
	 " \ "
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)test_quotedSpaces_sqt
{
	/*
	 " \ a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_qs
{
	/*
	 "\  "
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  [self makeWhitespace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(0, outputElements.count);
}

- (void)test_quotedSpaces_qst
{
	/*
	 "\  a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_sqqt
{
	/*
	 " \ \ a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_sqqst
{
	/*
	 " \ \  a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_sqsqst
{
	/*
	 " \  \  a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_sqsst
{
	/*
	 " \   a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_ssqst
{
	/*
	 "  \  a"
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"a"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_tq
{
	/*
	 "a\ "
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(1, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
}

- (void)test_quotedSpaces_tqt
{
	/*
	 "a\ b"
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_quotedSpaces_tqqt
{
	/*
	 "a\ \ bb"
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  @"bb"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bb");
}

- (void)test_quotedSpaces_tsqt
{
	/*
	 "a \ b"
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_quotedSpaces_tqst
{
	/*
	 "a\  "
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_quotedSpaces_tqsqqstqtsqst
{
	/*
	 "ax\  \ \  b\ c \  e"
	 */
	NSArray *parsedElements =
	@[
	  @"ax",
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"b",
	  [self makeQuotedSpace],
	  @"c",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"e"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ax");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");

	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"c");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_quotedSpaces_tqsssqt
{
	/*
	 "A\    \ B"
	 */
	NSArray *parsedElements =
	@[
	  @"A",
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  @"B"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"A");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"B");
}

- (void)test_quotedSpaces_spec2text_1
{
	/*
	 "We have some \ \ quoted spaces \ \ in this one."
	 */

	NSArray *parsedElements =
	@[
	  @"We",
	  [self makeWhitespaceWithText:@" "],
	  @"have",
	  [self makeWhitespaceWithText:@" "],
	  @"some",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  @"quoted",
	  [self makeWhitespace],
	  @"spaces",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  @"in",
	  [self makeWhitespace],
	  @"this",
	  [self makeWhitespace],
	  @"one."
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(17, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"We");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"have");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"some");

	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"quoted");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"spaces");
	
	outElt = outputElements[10];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[11];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[12];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"in");
	
	outElt = outputElements[13];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[14];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"this");
	
	outElt = outputElements[15];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[16];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"one.");
}

- (void)test_quotedSpaces_spec2text_2
{
	/*
	 "Mixing \  \  quoted and \ \   \   unquoted spaces."
	 */
	NSArray *parsedElements =
	@[
	  @"Mixing",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  @"quoted",
	  [self makeWhitespace],
	  @"and",
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"unquoted",
	  [self makeWhitespace],
	  @"spaces."
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(12, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Mixing");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"quoted");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"and");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"unquoted");
	
	outElt = outputElements[10];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[11];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"spaces.");
}

//-----

- (void)test_quotedSpaces_after_tag_start
{
	/*
	 "ab <br>\ cd";
	 */

	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeWhitespace],
	  [self makeTagBr],
	  [self makeQuotedSpace],
	  @"cd",
	];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
}

- (void)test_quotedSpaces_after_tag_end_simplified
{
	/*
	 "<b>cd </b>\ e";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeTagBOpen],
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBClose],
	  [self makeQuotedSpace],
	  @"e",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_quotedSpaces_after_tag_end
{
	/*
	 "ab<b>cd </b>\ e<br>
	 fg <b>\ hi"
	 */
	
	NSArray *parsedElements =
	@[
	  @"ab",
	  [self makeTagBOpen],
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBClose],
	  [self makeQuotedSpace],
	  @"e",
	  [self makeTagBr],
	  @"fg",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeQuotedSpace],
	  @"hi"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(10, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"ab");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");

	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"fg");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"hi");
}

//-----------

- (void)test_spaceAndInlineTag1
{
	// "cd <b> e</b>" -> "cd e"

	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  @"e",
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag1b
{
	// "cd<b> e</b>" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  @"e",
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag1c
{
	// "cd <b>e </b>" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  @"e",
	  [self makeWhitespace],
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag1d
{
	// "cd  <b>  e</b>" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"e",
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag2
{
	// "cd <b></b> e" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeTagBClose],
	  [self makeWhitespace],
	  @"e",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag2b
{
	// "cd <b> </b> e" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  [self makeTagBClose],
	  [self makeWhitespace],
	  @"e",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag2c
{
	// "cd  <b>  </b>  e" -> "cd e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  [self makeTagBClose],
	  [self makeWhitespace],
	  [self makeWhitespace],
	  @"e",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3a
{
	// "cd <b>\ e</b>" -> "cd  e"
 
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeQuotedSpace],
	  @"e",
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3b
{
	// "cd\ <b> e</b>" -> "cd e"
 
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeQuotedSpace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  @"e",
	  [self makeTagBClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3c
{
	// "cd <u> \ e</u>" -> "cd  e"

	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeWhitespace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  @"e",
	  [self makeTagBClose],
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3c2
{
	// "cd\ <u> \ e</u>" -> "cd  e"
	
	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeQuotedSpace],
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  @"e",
	  [self makeTagBClose],
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3d
{
	// "cd<u> e</u>" -> "cd e"

	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  @"e",
	  [self makeTagBClose],
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
}

- (void)test_spaceAndInlineTag3e
{
	// "cd<u>e </u>f" -> "cde f"

	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeTagBOpen],
	  @"e",
	  [self makeWhitespace],
	  [self makeTagBClose],
	  @"f"
	];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"f");
}

- (void)test_spaceAndInlineTag3f
{
	// "cd<u> e </u>f" -> "cd e f"

	NSArray *parsedElements =
	@[
	  @"cd",
	  [self makeTagBOpen],
	  [self makeWhitespace],
	  @"e",
	  [self makeWhitespace],
	  [self makeTagBClose],
	  @"f"
	  ];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"cd");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"e");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"f");
}

//------- non-breaking space -------

// The focus here is on nbsp's being folded into a immediately preceding whitespace,
// to avoid the dread "unwanted indent bug".

- (void)test_nonbreakingSpace_basic {
	
	/*
	 "a&nbsp;b"
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeNonbreakingSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
	
}

- (void)test_nonbreakingSpace_spaceNbsp {
	
	/*
	 "a &nbsp;b"
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeNonbreakingSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];

	XCTAssertEqual(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_nonbreakingSpace_spaceNbspNbsp {
	
	/*
	 "a &nbsp;&nbsp;b"
	 */
	
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeNonbreakingSpace],
	  [self makeNonbreakingSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];

	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_nonbreakingSpace_regTextEndingInSpaceNbsp {
	
	/*
	 "a&8194;&nbsp;b"
	 */
	
	NSArray *parsedElements =
	@[
	  @"a  ",  // "  " being what &#8194; gets expanded to
	  [self makeNonbreakingSpace],
	  @"b"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"a  ");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"b");
}

- (void)test_nbsp_tsnsnst {
	
	/*
	 "m &nbsp; &nbsp; r"
	 */
	
	NSArray *parsedElements =
	@[
	  @"m",
	  [self makeWhitespace],
	  [self makeNonbreakingSpace],
	  [self makeWhitespace],
	  [self makeNonbreakingSpace],
	  [self makeWhitespace],
	  @"r"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(7, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"m");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, NBSP_FMTD);
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"r");
}

//------- TODO ------

- (void) test_img_betweenText
{
	/*
	 "Text before<img src=unknown.gif alt='Img Alt Text'>after"
	 */
	
	NSArray *parsedElements =
	@[
	  @"Text before",
	  [self makeTagImgWithSrc:@"unknown.gif" alt:@"Img Alt Text"],
	  @"after"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);

	XCTAssertTrue([outputElements[0] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[1] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[2] isRegularOutputElementWithString:@"Img Alt Text"]);
	XCTAssertTrue([outputElements[3] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[4] isRegularOutputElementWithString:@"after"]);
}

- (void) test_img_betweenWhitespaceAndText
{
	/*
	 "Text before <img src=unknown.gif alt='Img Alt Text'>after"
	 */
	
	NSArray *parsedElements =
	@[
	  @"Text before",
	  [self makeWhitespace],
	  [self makeTagImgWithSrc:@"unknown.gif" alt:@"Img Alt Text"],
	  @"after"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XCTAssertTrue([outputElements[0] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[1] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[2] isRegularOutputElementWithString:@"Img Alt Text"]);
	XCTAssertTrue([outputElements[3] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[4] isRegularOutputElementWithString:@"after"]);
}

- (void) test_img_betweenTextAndWhitespace
{
	/*
	 "Text before<img src=unknown.gif alt='Img Alt Text'> after"
	 */
	
	NSArray *parsedElements =
	@[
	  @"Text before",
	  [self makeTagImgWithSrc:@"unknown.gif" alt:@"Img Alt Text"],
	  [self makeWhitespace],
	  @"after"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XCTAssertTrue([outputElements[0] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[1] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[2] isRegularOutputElementWithString:@"Img Alt Text"]);
	XCTAssertTrue([outputElements[3] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[4] isRegularOutputElementWithString:@"after"]);
}

- (void) test_img_betweenWhitespaceAndWhitespace
{
	/*
	 "Text before <img src=unknown.gif alt='Img Alt Text'> after"
	 */
	
	NSArray *parsedElements =
	@[
	  @"Text before",
	  [self makeWhitespace],
	  [self makeTagImgWithSrc:@"unknown.gif" alt:@"Img Alt Text"],
	  [self makeWhitespace],
	  @"after"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XCTAssertTrue([outputElements[0] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[1] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[2] isRegularOutputElementWithString:@"Img Alt Text"]);
	XCTAssertTrue([outputElements[3] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[4] isRegularOutputElementWithString:@"after"]);
}

- (void) test_img_betweenOtherBlockLevelTags
{
	/*
	 "Meh
	 <p>Text before</p>
	 <img src=unknown.gif alt='Alt Text'>
	 <p>after</p>"
	 */
	
	NSArray *parsedElements =
	@[
	  @"Meh",
	  [self makeTagPOpen],
	  @"Text before",
	  [self makeTagPClose],
	  [self makeTagImgWithSrc:@"unknown2.gif" alt:@"Alt Text"],
	  [self makeTagPOpen],
	  @"after",
	  [self makeTagPClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(10, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Meh"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Alt Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"after"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
}

- (void) test_img_aroundOtherBlockLevelTag
{
	/*
	 "<img src=unknown7.gif alt='7 Alt Text'>
	 <p>Text</p>
	 <img src=unknown8.gif alt='8 Alt Text'>";
	 */

	NSArray *parsedElements =
	@[
	  [self makeTagImgWithSrc:@"unknown7.gif" alt:@"7 Alt Text"],
	  [self makeTagPOpen],
	  @"Text",
	  [self makeTagPClose],
	  [self makeTagImgWithSrc:@"unknown8.gif" alt:@"8 Alt Text"],
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"7 Alt Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"8 Alt Text"]);
}

- (void) test_img_severalInARow
{
	/*
	 "before
	 <img src=unknown3.gif alt='Other Alt Text'>
	 <img src=unknown4.gif alt='4 Alt Text'>
	 <img src=unknown5.gif alt='5 Alt Text'>
	 after"
	 */

	NSArray *parsedElements =
	@[
	  @"before",
	  [self makeTagImgWithSrc:@"unknown3.gif" alt:@"Other Alt Text"],
	  [self makeTagImgWithSrc:@"unknown4.gif" alt:@"4 Alt Text"],
	  [self makeTagImgWithSrc:@"unknown5.gif" alt:@"5 Alt Text"],
	  @"after"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(9, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"before"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Other Alt Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"4 Alt Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"5 Alt Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@" "]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"after"]);
}

//-----  xtads bugs wrt. specific games  -----

- (void)test_drool_extraNewLineAfterEnterYourBreed_bug_simplified
{
	/*
	 "breed:";
	 "<BR HEIGHT=0>";
	 "</p>";
	 "<BR HEIGHT=0>";
	 "<ol>";
	 "Mutt";
	 "</ol>";
	 */
	
	NSArray *parsedElements =
	@[
	  @"breed:",
	  [self makeTagBr0],
	  [self makeTagPClose],
	  [self makeTagBr0],
	  [self makeTagOlOpen],
	  @"Mutt",
	  [self makeTagOlClose]
	  ];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"breed:");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Mutt");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

- (void)test_drool_gameverbs_missingIndentationBug_simplified
{
	/*
	 "preferences:<BR HEIGHT=0><TAB MULTIPLE=4><li>realtime</li>";
	 */
	
	NSArray *parsedElements =
	@[
	  @"preferences:",
	  [self makeTagBr0],
	  [self makeTagTabWithMultiple:4],
	  [self makeTagLiOpen],
	  @"realtime",
	  [self makeTagLiClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"preferences:");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"realtime");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
}

//TODO test "<li>a</li><li>b</li><li>c</li>"

- (void)test_drool_miscverbs_extraNewlineBug
{
	/*
	 "<TAB MULTIPLE=4><li>wallow</li>";
	 "<BR HEIGHT=0>";
	 "</ul> Also";
	 */

	NSArray *parsedElements =
	@[
	  [self makeTagTabWithMultiple:4],
	  [self makeTagLiOpen],
	  @"wallow",
	  [self makeTagLiClose],
	  [self makeTagBr0],
	  [self makeTagUlClose],
	  [self makeWhitespace],
	  @"Also",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger idx = 0;

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt);
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"wallow");
	
	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[idx++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Also");
}

- (void)test_preTag_newlineBug
{
	/*
	 "pre?
	 <pre>is      this
	   pre?</pre>
	 after pre";
	 */

	NSArray *parsedElements =
	@[
	  @"pre?",
	  [self makeWhitespaceWithText:@"\n"],
	  [self makeTagPreOpen],
	  @"is",
	  [self makeWhitespaceWithText:@"      "],
	  @"this",
	  [self makeWhitespaceWithText:@"\n  "],
	  @"pre?",
	  [self makeTagPreClose],
	  [self makeWhitespaceWithText:@"\n"],
	  @"after",
	  @"pre",
	  ];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	//XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	//TODO finish
}

- (void)test_preTag_newlineBug_simplified
{
	/*
	 <pre>line1
	   line2</pre>
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeTagPreOpen],
	  @"line1",
	  [self makeWhitespaceWithText:@"\n  "],
	  @"line2",
	  [self makeTagPreClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	//XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	//TODO finish
}

- (void)test_darkAngel_locNameNoneBug
{
	/*
	 "<p>Bedroom</p><BR HEIGHT=0>The bedroom...";
	 */

	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  @"Bedroom",
	  [self makeTagPClose],
	  [self makeTagBr0],
	  @"The",
	  [self makeWhitespaceWithText:@" "],
	  @"bedroom...",
	];

	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Bedroom");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"The");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bedroom...");
}

- (void)test_magicSpacesAroundLinkBug
{
	/*
	 "<BR HEIGHT=0> ";
	 "(<A HREF="http://g42.org/xwiki/bin/view/Main/IFComp2008">website</A>)";
	 "<BR HEIGHT=0> ";
	*/

	//TODO
}

- (void)test_adhoc_t2_extraNlAfterParaBug
{
	NSArray *parsedElements =
	@[
	  @"sdesc",
	  [self makeWhitespaceWithText:@"\n"],
	  [self makeTagTabWithMultiple:4],
	  [self makeTagPOpen],
	  @"Text",
	  [self makeTagPClose],
	  [self makeWhitespaceWithText:@"\n"],
	  [self makeTagBr0],
	  [self makeTagTabWithMultiple:4],
	  [self makeWhitespaceWithText:@"\n"],
	  [self makeTagBr0],
	  [self makeTagBr0],
	  [self makeTagBr0],
	  [self makeTagBr0],
	  [self makeWhitespaceWithText:@"\n"],
	  [self makeTagBr],
	  @">"
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(10, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"sdesc");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt);
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Text");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isTabElement]);
	XCTAssertNotNil(outElt);
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @">");
}

- (void)test_adhoc_t3_extraNlAfterParaBug
{
	//TODO impl
	/*
	 "<p>text1</p><br>text2";
	 */
	
	NSArray *parsedElements =
	@[
	  [self makeTagPOpen],
	  @"text1",
	  [self makeTagPClose],
	  [self makeTagBr],
	  @"text2",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	NSUInteger i = 0;

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text1");

	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[i++];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text2");
}

//---------------  Support  -----------------------------------------

- (XTHtmlWhitespace *)makeWhitespace
{
	return [self makeWhitespaceWithText:@" "];
}

- (XTHtmlWhitespace *)makeWhitespaceWithText:(NSString *)text
{
	XTHtmlWhitespace *ws = [XTHtmlWhitespace whitespaceWithText:text];
	return ws;
}

- (XTHtmlQuotedSpace *)makeQuotedSpace
{
	XTHtmlQuotedSpace *qs = [XTHtmlQuotedSpace quotedSpace];
	return qs;
}

- (XTHtmlNonbreakingSpace *)makeNonbreakingSpace
{
	XTHtmlNonbreakingSpace *nbs = [XTHtmlNonbreakingSpace new];
	return nbs;
}

- (XTHtmlSpecialSpace *)makeSpecialSpace:(unichar)ch
{
	XTHtmlSpecialSpace *ss = [XTHtmlSpecialSpace specialSpaceWithChar:ch];
	return ss;
}

- (XTHtmlTagTab *)makeTagTabWithMultiple:(NSUInteger)multiple
{
	XTHtmlTagTab *tag = [XTHtmlTagTab new];
	tag.attributes[@"multiple"] = @"4";
	return tag;
}

- (XTHtmlTagTab *)makeTagTabWithoutMultiple
{
	XTHtmlTagTab *tag = [XTHtmlTagTab new];
	return tag;
}

- (XTHtmlTagBlockQuote *)makeTagBlockquoteOpen
{
	return (XTHtmlTagBlockQuote *) [self makeTagOfClass:[XTHtmlTagBlockQuote class] closing:NO];
}

- (XTHtmlTagBlockQuote *)makeTagBlockquoteClose
{
	return (XTHtmlTagBlockQuote *) [self makeTagOfClass:[XTHtmlTagBlockQuote class] closing:YES];
}

- (XTHtmlTagP *)makeTagPOpen
{
	return (XTHtmlTagP *) [self makeTagOfClass:[XTHtmlTagP class] closing:NO];
}

- (XTHtmlTagP *)makeTagPClose
{
	return (XTHtmlTagP *) [self makeTagOfClass:[XTHtmlTagP class] closing:YES];
}

- (XTHtmlTagQ *)makeTagQOpen
{
	return (XTHtmlTagQ *) [self makeTagOfClass:[XTHtmlTagQ class] closing:NO];
}

- (XTHtmlTagQ *)makeTagQClose
{
	return (XTHtmlTagQ *) [self makeTagOfClass:[XTHtmlTagQ class] closing:YES];
}

- (XTHtmlTagBr *)makeTagBr
{
	XTHtmlTagBr *tagBr0 = [XTHtmlTagBr new];
	return tagBr0;
}

- (XTHtmlTagBr *)makeTagBr0
{
	XTHtmlTagBr *tagBr0 = [XTHtmlTagBr new];
	tagBr0.attributes[@"height"] = @"0";
	return tagBr0;
}

- (XTHtmlTagOl *)makeTagOlOpen
{
	return (XTHtmlTagOl *) [self makeTagOfClass:[XTHtmlTagOl class] closing:NO];
}

- (XTHtmlTagOl *)makeTagOlClose
{
	return (XTHtmlTagOl *) [self makeTagOfClass:[XTHtmlTagOl class] closing:YES];
}

- (XTHtmlTagUl *)makeTagUlOpen
{
	return (XTHtmlTagUl *) [self makeTagOfClass:[XTHtmlTagUl class] closing:NO];
}

- (XTHtmlTagUl *)makeTagUlClose
{
	return (XTHtmlTagUl *) [self makeTagOfClass:[XTHtmlTagUl class] closing:YES];
}

- (XTHtmlTagLi *)makeTagLiOpen
{
	return (XTHtmlTagLi *) [self makeTagOfClass:[XTHtmlTagLi class] closing:NO];
}

- (XTHtmlTagLi *)makeTagLiClose
{
	return (XTHtmlTagLi *) [self makeTagOfClass:[XTHtmlTagLi class] closing:YES];
}

- (XTHtmlTagPre *)makeTagPreOpen
{
	return (XTHtmlTagPre *) [self makeTagOfClass:[XTHtmlTagPre class] closing:NO];
}

- (XTHtmlTagPre *)makeTagPreClose
{
	return (XTHtmlTagPre *) [self makeTagOfClass:[XTHtmlTagPre class] closing:YES];
}

- (XTHtmlTagB *)makeTagBOpen
{
	return (XTHtmlTagB *) [self makeTagOfClass:[XTHtmlTagB class] closing:NO];
}

- (XTHtmlTagB *)makeTagBClose
{
	return (XTHtmlTagB *) [self makeTagOfClass:[XTHtmlTagB class] closing:YES];
}

- (XTHtmlTagImg *)makeTagImgWithSrc:(NSString *)src alt:(NSString *)alt
{
	XTHtmlTagImg *tag = (XTHtmlTagImg *)[self makeTagOfClass:[XTHtmlTagImg class] closing:NO];
	if (src.length >= 1) {
		tag.attributes[@"src"] = src;
	}
	if (alt.length >= 1) {
		tag.attributes[@"alt"] = alt;
	}
	return tag;
}

- (XTHtmlTag *)makeTagOfClass:(Class)tagClass closing:(BOOL)closing
{
	XTHtmlTag *tag = [[tagClass alloc] init];
	tag.closing = closing;
	return tag;
}

@end
