//
//  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 "XTOutputTextParserHtml.h"


@interface XTOutputFormatterTests : XCTestCase

@property XTOutputFormatter *formatter;

@end


@implementation XTOutputFormatterTests

- (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];
		[res addObjectsFromArray:fea];
	}
	return res;
}

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

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––");
	
	outElt = outputElements[2];
	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(7, outputElements.count);

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

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

	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[6];
	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(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"McGee");

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

	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[8];
	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 makeTagTab],
		[self makeTagBr],
		@"Desc",
	];

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

	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Outside cave");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" \t");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Desc");
}

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

- (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(7, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"1.\t");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item1");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[6];
	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(11, outputElements.count);

	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"1.\t");
	
	outElt = outputElements[4];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item1");

	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"2.\t");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"item2");

	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	//TODO should be another nl here...
	outElt = outputElements[10];
	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(2, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	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(3, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[2];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
}

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

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

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

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

	outElt = outputElements[2];
	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(4, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[3];
	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(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;

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

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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, @"After");
}

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

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

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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, @"pg1");

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

	outElt = outputElements[7];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"pg2");
	
	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[10];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[11];
	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(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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, @"pg1");

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

	outElt = outputElements[7];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[8];
	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(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Before");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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, @"pg1");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[8];
	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(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[4];
	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(7, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"text1");
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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, @"bq1");
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[6];
	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(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"bq1");
	
	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, @"text2");
}

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

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

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


//------- Quoted spaces ------

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

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

- (void)test_quotedSpaces_qq
{
	/*
	 "\ \ "
	 */
	NSArray *parsedElements =
	@[
	  [self makeQuotedSpace],
	  [self makeQuotedSpace]
	  ];
	
	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, @" ");
}

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

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

- (void)test_quotedSpaces_sqq
{
	/*
	 " \ \ "
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace]
	  ];
	
	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, @" ");
}

- (void)test_quotedSpaces_sqqs
{
	/*
	 " \ \  "
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeQuotedSpace],
	  [self makeWhitespace]
	  ];
	
	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, @" ");
}

- (void)test_quotedSpaces_sqsqs
{
	/*
	 " \  \  "
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [self makeWhitespace]
	  ];
	
	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, @" ");
}

- (void)test_quotedSpaces_sqss
{
	/*
	 " \ \  "
	 */
	NSArray *parsedElements =
	@[
	  [self makeWhitespace],
	  [self makeQuotedSpace],
	  [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, @" ");
}

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

- (void)test_quotedSpaces_tq
{
	/*
	 "a\ "
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace]
	  ];
	
	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, @" ");
}

- (void)test_quotedSpaces_tqq
{
	/*
	 "a\ \ "
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeQuotedSpace],
	  [self makeQuotedSpace]
	  ];
	
	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, @" ");
}

- (void)test_quotedSpaces_tsq
{
	/*
	 "a \ "
	 */
	NSArray *parsedElements =
	@[
	  @"a",
	  [self makeWhitespace],
	  [self makeQuotedSpace]
	  ];
	
	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, @" ");
}

- (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(6, 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, @" ");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);

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

- (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(11, 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 isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"fg");
	
	outElt = outputElements[8];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[9];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	outElt = outputElements[10];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"hi");
}

//------- 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, @"\u00A0");

	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, @" ");
	
	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, @" ");
	
	outElt = outputElements[3];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @" ");
	
	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, @" ");

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

//------- 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(7, outputElements.count);

	XCTAssertTrue([outputElements[0] isRegularOutputElementWithString:@"Text before"]);
	XCTAssertTrue([outputElements[1] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[2] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[3] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[4] isRegularOutputElementWithString:@"[Image \"Img Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[5] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[6] isRegularOutputElementWithString:@"after"]);
}

- (void) test_img_betweenOtherBlockLevelTags
{
	/*
	 "Meh
	 <p>Text before</p>
	 <img src=unknown.gif alt='Img 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(14, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Meh"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	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:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"after"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	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(11, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"7 Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"Text"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"8 Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
}

- (void) test_img_severalInARow
{
	/*
	 "<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 =
	@[
	  [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(11, outputElements.count);
	
	NSUInteger i = 0;
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"Other Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"4 Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	XCTAssertTrue([outputElements[i++] isRemoveTabsToStartOfLineElement]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"[Image \"5 Alt Text\" not shown]\n"]);
	XCTAssertTrue([outputElements[i++] isRegularOutputElementWithString:@"\n"]);
	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(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;
	
	outElt = outputElements[0];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"breed:");

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	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 isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[5];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[6];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Mutt");
	
	outElt = outputElements[7];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");

	outElt = outputElements[8];
	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 makeTagTab],
	  [self makeTagLiOpen],
	  @"realtime",
	  [self makeTagLiClose]
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(6, outputElements.count);
	
	XTFormattedOutputElement *outElt;

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

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

	outElt = outputElements[5];
	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 makeTagTab],
	  [self makeTagLiOpen],
	  @"wallow",
	  [self makeTagLiClose],
	  [self makeTagBr0],
	  [self makeTagUlClose],
	  [self makeWhitespace],
	  @"Also",
	  ];
	
	NSArray *outputElements = [self formatParsedElements:parsedElements];
	
	XCTAssertEqual(5, outputElements.count);
	
	XTFormattedOutputElement *outElt;

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

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

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

	outElt = outputElements[3];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);
	
	outElt = outputElements[4];
	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(9, outputElements.count);
	
	XTFormattedOutputElement *outElt;

	outElt = outputElements[0];
	XCTAssertTrue([outElt isRemoveTabsToStartOfLineElement]);

	outElt = outputElements[1];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"\n");
	
	outElt = outputElements[2];
	XCTAssertTrue([outElt isRegularOutputElement]);
	XCTAssertEqualObjects(outElt.attributedString.string, @"Bedroom");
	
	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 isRemoveTabsToStartOfLineElement]);

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


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

- (XTHtmlWhitespace *)makeWhitespace
{
	XTHtmlWhitespace *ws = [XTHtmlWhitespace new];
	return ws;
}

- (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;
}

- (XTHtmlTagTab *)makeTagTab
{
	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];
}

- (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
