<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[166147] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/166147">166147</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2014-03-23 15:14:20 -0700 (Sun, 23 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move HTMLConverter from platform/mac to editing/cocoa.

Rubber-stamped by Darin Adler.

* WebCore.xcodeproj/project.pbxproj:
* editing/cocoa: Added.
* editing/cocoa/HTMLConverter.h: Copied from platform/mac/HTMLConverter.h.
* editing/cocoa/HTMLConverter.mm: Copied from platform/mac/HTMLConverter.mm.
* platform/mac/HTMLConverter.h: Removed.
* platform/mac/HTMLConverter.mm: Removed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/WebCore/editing/cocoa/</li>
<li><a href="#trunkSourceWebCoreeditingcocoaHTMLConverterh">trunk/Source/WebCore/editing/cocoa/HTMLConverter.h</a></li>
<li><a href="#trunkSourceWebCoreeditingcocoaHTMLConvertermm">trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformmacHTMLConverterh">trunk/Source/WebCore/platform/mac/HTMLConverter.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacHTMLConvertermm">trunk/Source/WebCore/platform/mac/HTMLConverter.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166146 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-23 21:47:52 UTC (rev 166146)
+++ trunk/Source/WebCore/ChangeLog        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -1,5 +1,18 @@
</span><span class="cx"> 2014-03-23  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><ins>+        Move HTMLConverter from platform/mac to editing/cocoa.
+
+        Rubber-stamped by Darin Adler.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/cocoa: Added.
+        * editing/cocoa/HTMLConverter.h: Copied from platform/mac/HTMLConverter.h.
+        * editing/cocoa/HTMLConverter.mm: Copied from platform/mac/HTMLConverter.mm.
+        * platform/mac/HTMLConverter.h: Removed.
+        * platform/mac/HTMLConverter.mm: Removed.
+
+2014-03-23  Sam Weinig  &lt;sam@webkit.org&gt;
+
</ins><span class="cx">         Simplify the HTMLConverter interface (Part 2)
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=130654
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (166146 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-23 21:47:52 UTC (rev 166146)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -2034,7 +2034,6 @@
</span><span class="cx">                 5B7A208D2E12979B4AE19DE6 /* RenderMathMLSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DBFCB0EBFF5CD77EBEB35395 /* RenderMathMLSpace.cpp */; };
</span><span class="cx">                 5D21A80213ECE5DF00BB7064 /* WebVTTParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D21A80013ECE5DF00BB7064 /* WebVTTParser.cpp */; };
</span><span class="cx">                 5D21A80313ECE5DF00BB7064 /* WebVTTParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D21A80113ECE5DF00BB7064 /* WebVTTParser.h */; };
</span><del>-                5D4F51DF132725480016F541 /* HTMLConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = C5392D341326AD0100043D35 /* HTMLConverter.mm */; };
</del><span class="cx">                 5D874F130D161D3200796C3B /* NetscapePlugInStreamLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E227DD0AF589AD00D48324 /* NetscapePlugInStreamLoader.cpp */; };
</span><span class="cx">                 5D87BB8311E3ED8600702B6F /* ExportFileGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D87BB8211E3ED8600702B6F /* ExportFileGenerator.cpp */; };
</span><span class="cx">                 5D8C4DBF1428222C0026CE72 /* DisplaySleepDisabler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D8C4DBD1428222C0026CE72 /* DisplaySleepDisabler.cpp */; };
</span><span class="lines">@@ -2320,6 +2319,8 @@
</span><span class="cx">                 7BE7427381FA906FBB4F0F2C /* JSSVGGraphicsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */; };
</span><span class="cx">                 7C2BDD3D17C7F98C0038FF15 /* JSDOMGlobalObjectTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */; };
</span><span class="cx">                 7C2BDD3E17C7F98C0038FF15 /* JSDOMGlobalObjectTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */; };
</span><ins>+                7C3E510A18DF8F3500C112F7 /* HTMLConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3E510818DF8F3500C112F7 /* HTMLConverter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                7C3E510B18DF8F3500C112F7 /* HTMLConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C3E510918DF8F3500C112F7 /* HTMLConverter.mm */; };
</ins><span class="cx">                 7C4902A218B825F8007D9298 /* DOMWheelEventInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85989DCA0ACC8BBD00A0BC51 /* DOMWheelEventInternal.h */; };
</span><span class="cx">                 7C522D4B15B477E8009B7C95 /* InspectorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C522D4915B477E8009B7C95 /* InspectorOverlay.cpp */; };
</span><span class="cx">                 7C5343FC17B74B63004232F0 /* JSMediaQueryListListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5343FA17B74B63004232F0 /* JSMediaQueryListListener.cpp */; };
</span><span class="lines">@@ -5865,7 +5866,6 @@
</span><span class="cx">                 E1A1470811102B1500EEC0F3 /* ContainerNodeAlgorithms.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A1470711102B1500EEC0F3 /* ContainerNodeAlgorithms.h */; };
</span><span class="cx">                 E1A3162D134BC32D007C9A4F /* WebNSAttributedStringExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A3162B134BC32D007C9A4F /* WebNSAttributedStringExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E1A3162E134BC32D007C9A4F /* WebNSAttributedStringExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1A3162C134BC32D007C9A4F /* WebNSAttributedStringExtras.mm */; };
</span><del>-                E1A31663134BCAE8007C9A4F /* HTMLConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = C5392D331326AD0100043D35 /* HTMLConverter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 E1A5F99B0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */; };
</span><span class="cx">                 E1A643F20EC0972500779668 /* WorkerScriptController.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A643F10EC0972500779668 /* WorkerScriptController.h */; };
</span><span class="cx">                 E1A643FD0EC097A000779668 /* WorkerScriptController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A643FC0EC097A000779668 /* WorkerScriptController.cpp */; };
</span><span class="lines">@@ -9335,6 +9335,8 @@
</span><span class="cx">                 7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVTTRegionList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMGlobalObjectTask.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMGlobalObjectTask.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7C3E510818DF8F3500C112F7 /* HTMLConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLConverter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7C3E510918DF8F3500C112F7 /* HTMLConverter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLConverter.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7C522D4915B477E8009B7C95 /* InspectorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorOverlay.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C522D4A15B478B2009B7C95 /* InspectorOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorOverlay.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C5343FA17B74B63004232F0 /* JSMediaQueryListListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaQueryListListener.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -12731,8 +12733,6 @@
</span><span class="cx">                 C5160EE81004543A00A7CEE2 /* StorageAreaImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageAreaImpl.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C5160EE91004543A00A7CEE2 /* StorageAreaImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageAreaImpl.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C5278B0B17F212EA003A2998 /* PlatformPasteboardIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlatformPasteboardIOS.mm; path = ios/PlatformPasteboardIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                C5392D331326AD0100043D35 /* HTMLConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLConverter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                C5392D341326AD0100043D35 /* HTMLConverter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLConverter.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 C544274911A57E7A0063A749 /* DOMStringList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMStringList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C544274A11A57E7A0063A749 /* DOMStringList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMStringList.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C55610F011A704EB00B82D27 /* DOMStringList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMStringList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -16074,8 +16074,6 @@
</span><span class="cx">                                 E1BA66F01742BD8600C20251 /* DynamicLinkerInterposing.h */,
</span><span class="cx">                                 1CA19E030DC255950065A994 /* EventLoopMac.mm */,
</span><span class="cx">                                 514B3F750C722055000530DF /* FileSystemMac.mm */,
</span><del>-                                C5392D331326AD0100043D35 /* HTMLConverter.h */,
-                                C5392D341326AD0100043D35 /* HTMLConverter.mm */,
</del><span class="cx">                                 935C476E09AC4D7300A6AAB4 /* KeyEventMac.mm */,
</span><span class="cx">                                 521D46F511AEC98100514613 /* KillRingMac.mm */,
</span><span class="cx">                                 9352084409BD43B900F2038D /* Language.mm */,
</span><span class="lines">@@ -16364,6 +16362,15 @@
</span><span class="cx">                         tabWidth = 4;
</span><span class="cx">                         usesTabs = 0;
</span><span class="cx">                 };
</span><ins>+                7C3E510718DF8F1200C112F7 /* cocoa */ = {
+                        isa = PBXGroup;
+                        children = (
+                                7C3E510818DF8F3500C112F7 /* HTMLConverter.h */,
+                                7C3E510918DF8F3500C112F7 /* HTMLConverter.mm */,
+                        );
+                        path = cocoa;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 7C74D43018823A4200E5ED57 /* icu */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="lines">@@ -17005,6 +17012,7 @@
</span><span class="cx">                 93309D86099E64910056E581 /* editing */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                7C3E510718DF8F1200C112F7 /* cocoa */,
</ins><span class="cx">                                 443292C10EBA6D7300E62016 /* ios */,
</span><span class="cx">                                 ED501DC90B249F3900AE18D9 /* mac */,
</span><span class="cx">                                 CE08C3CF152B599A0021B8C2 /* AlternativeTextController.cpp */,
</span><span class="lines">@@ -23266,6 +23274,7 @@
</span><span class="cx">                                 FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */,
</span><span class="cx">                                 4167EBF6102962BA003D252A /* DefaultSharedWorkerRepository.h in Headers */,
</span><span class="cx">                                 1AF4CEEA18BC350100BC2D34 /* DefaultVisitedLinkStore.h in Headers */,
</span><ins>+                                7C3E510A18DF8F3500C112F7 /* HTMLConverter.h in Headers */,
</ins><span class="cx">                                 FD31602C12B0267600C1A359 /* DelayDSPKernel.h in Headers */,
</span><span class="cx">                                 FD31602E12B0267600C1A359 /* DelayNode.h in Headers */,
</span><span class="cx">                                 FD31603112B0267600C1A359 /* DelayProcessor.h in Headers */,
</span><span class="lines">@@ -23911,7 +23920,6 @@
</span><span class="cx">                                 996231F318D18AC300C03FDA /* InspectorWebBackendCommands.js in Headers */,
</span><span class="cx">                                 A8DF3FD0097FA0FC0052981B /* HTMLCollection.h in Headers */,
</span><span class="cx">                                 977B3865122883E900B81FF8 /* HTMLConstructionSite.h in Headers */,
</span><del>-                                E1A31663134BCAE8007C9A4F /* HTMLConverter.h in Headers */,
</del><span class="cx">                                 F5C041DB0FFCA7CE00839D4A /* HTMLDataListElement.h in Headers */,
</span><span class="cx">                                 D359D78A129CA2710006E5D2 /* HTMLDetailsElement.h in Headers */,
</span><span class="cx">                                 A8EA79FA0A1916DF00A8EF5F /* HTMLDirectoryElement.h in Headers */,
</span><span class="lines">@@ -27321,7 +27329,6 @@
</span><span class="cx">                                 93F19AFD08245E59001E9ABC /* HTMLCanvasElement.cpp in Sources */,
</span><span class="cx">                                 A8DF3FD1097FA0FC0052981B /* HTMLCollection.cpp in Sources */,
</span><span class="cx">                                 977B3864122883E900B81FF8 /* HTMLConstructionSite.cpp in Sources */,
</span><del>-                                5D4F51DF132725480016F541 /* HTMLConverter.mm in Sources */,
</del><span class="cx">                                 F5C041DA0FFCA7CE00839D4A /* HTMLDataListElement.cpp in Sources */,
</span><span class="cx">                                 D359D789129CA2710006E5D2 /* HTMLDetailsElement.cpp in Sources */,
</span><span class="cx">                                 A8EA79F90A1916DF00A8EF5F /* HTMLDirectoryElement.cpp in Sources */,
</span><span class="lines">@@ -28425,6 +28432,7 @@
</span><span class="cx">                                 31078CC71880AAB5008099DC /* OESTextureHalfFloatLinear.cpp in Sources */,
</span><span class="cx">                                 77A17A7112F28182004E02F6 /* OESVertexArrayObject.cpp in Sources */,
</span><span class="cx">                                 FDA3E959134A49EF008D4B5A /* OfflineAudioCompletionEvent.cpp in Sources */,
</span><ins>+                                7C3E510B18DF8F3500C112F7 /* HTMLConverter.mm in Sources */,
</ins><span class="cx">                                 FDA9325D16703B2A008982DC /* OfflineAudioContext.cpp in Sources */,
</span><span class="cx">                                 FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */,
</span><span class="cx">                                 CDE7FC44181904B1002BBB77 /* OrderIterator.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingcocoaHTMLConverterhfromrev166145trunkSourceWebCoreplatformmacHTMLConverterh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/editing/cocoa/HTMLConverter.h (from rev 166145, trunk/Source/WebCore/platform/mac/HTMLConverter.h) (0 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/cocoa/HTMLConverter.h                                (rev 0)
+++ trunk/Source/WebCore/editing/cocoa/HTMLConverter.h        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2010-2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLConverter_h
+#define HTMLConverter_h
+
+OBJC_CLASS NSAttributedString;
+
+namespace WebCore {
+    
+class Range;
+    
+NSAttributedString *attributedStringFromRange(Range&amp;);
+#if !PLATFORM(IOS)
+NSAttributedString *editingAttributedStringFromRange(Range&amp;);
+#endif
+
+}
+
+#endif // HTMLConverter_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreeditingcocoaHTMLConvertermmfromrev166145trunkSourceWebCoreplatformmacHTMLConvertermm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm (from rev 166145, trunk/Source/WebCore/platform/mac/HTMLConverter.mm) (0 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm                                (rev 0)
+++ trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -0,0 +1,2648 @@
</span><ins>+/*
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import &quot;config.h&quot;
+#import &quot;HTMLConverter.h&quot;
+
+#import &quot;ArchiveResource.h&quot;
+#import &quot;CachedImage.h&quot;
+#import &quot;ColorMac.h&quot;
+#import &quot;CSSComputedStyleDeclaration.h&quot;
+#import &quot;CSSParser.h&quot;
+#import &quot;CSSPrimitiveValue.h&quot;
+#import &quot;Document.h&quot;
+#import &quot;DocumentLoader.h&quot;
+#import &quot;DOMCSSPrimitiveValueInternal.h&quot;
+#import &quot;DOMDocumentInternal.h&quot;
+#import &quot;DOMElementInternal.h&quot;
+#import &quot;DOMHTMLTableCellElement.h&quot;
+#import &quot;DOMNodeInternal.h&quot;
+#import &quot;DOMPrivate.h&quot;
+#import &quot;DOMRGBColorInternal.h&quot;
+#import &quot;DOMRangeInternal.h&quot;
+#import &quot;Element.h&quot;
+#import &quot;Font.h&quot;
+#import &quot;Frame.h&quot;
+#import &quot;FrameLoader.h&quot;
+#import &quot;HTMLElement.h&quot;
+#import &quot;HTMLNames.h&quot;
+#import &quot;HTMLParserIdioms.h&quot;
+#import &quot;LoaderNSURLExtras.h&quot;
+#import &quot;RGBColor.h&quot;
+#import &quot;RenderImage.h&quot;
+#import &quot;SoftLinking.h&quot;
+#import &quot;StyleProperties.h&quot;
+#import &quot;StyledElement.h&quot;
+#import &quot;TextIterator.h&quot;
+#import &lt;objc/runtime.h&gt;
+#import &lt;wtf/ASCIICType.h&gt;
+
+#if PLATFORM(IOS)
+
+SOFT_LINK_FRAMEWORK(UIKit)
+SOFT_LINK_CLASS(UIKit, UIColor)
+
+SOFT_LINK_PRIVATE_FRAMEWORK(UIFoundation)
+SOFT_LINK_CLASS(UIFoundation, UIFont)
+SOFT_LINK_CLASS(UIFoundation, NSColor)
+SOFT_LINK_CLASS(UIFoundation, NSShadow)
+SOFT_LINK_CLASS(UIFoundation, NSTextAttachment)
+SOFT_LINK_CLASS(UIFoundation, NSMutableParagraphStyle)
+SOFT_LINK_CLASS(UIFoundation, NSParagraphStyle)
+SOFT_LINK_CLASS(UIFoundation, NSTextList)
+SOFT_LINK_CLASS(UIFoundation, NSTextBlock)
+SOFT_LINK_CLASS(UIFoundation, NSTextTableBlock)
+SOFT_LINK_CLASS(UIFoundation, NSTextTable)
+SOFT_LINK_CLASS(UIFoundation, NSTextTab)
+
+SOFT_LINK_CONSTANT(UIFoundation, NSFontAttributeName, NSString *)
+#define NSFontAttributeName getNSFontAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSForegroundColorAttributeName, NSString *)
+#define NSForegroundColorAttributeName getNSForegroundColorAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSBackgroundColorAttributeName, NSString *)
+#define NSBackgroundColorAttributeName getNSBackgroundColorAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSStrokeColorAttributeName, NSString *)
+#define NSStrokeColorAttributeName getNSStrokeColorAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSStrokeWidthAttributeName, NSString *)
+#define NSStrokeWidthAttributeName getNSStrokeWidthAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSShadowAttributeName, NSString *)
+#define NSShadowAttributeName getNSShadowAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSKernAttributeName, NSString *)
+#define NSKernAttributeName getNSKernAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSLigatureAttributeName, NSString *)
+#define NSLigatureAttributeName getNSLigatureAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSUnderlineStyleAttributeName, NSString *)
+#define NSUnderlineStyleAttributeName getNSUnderlineStyleAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSStrikethroughStyleAttributeName, NSString *)
+#define NSStrikethroughStyleAttributeName getNSStrikethroughStyleAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSBaselineOffsetAttributeName, NSString *)
+#define NSBaselineOffsetAttributeName getNSBaselineOffsetAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSWritingDirectionAttributeName, NSString *)
+#define NSWritingDirectionAttributeName getNSWritingDirectionAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSParagraphStyleAttributeName, NSString *)
+#define NSParagraphStyleAttributeName getNSParagraphStyleAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSAttachmentAttributeName, NSString *)
+#define NSAttachmentAttributeName getNSAttachmentAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSLinkAttributeName, NSString *)
+#define NSLinkAttributeName getNSLinkAttributeName()
+SOFT_LINK_CONSTANT(UIFoundation, NSAuthorDocumentAttribute, NSString *)
+#define NSAuthorDocumentAttribute getNSAuthorDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSEditorDocumentAttribute, NSString *)
+#define NSEditorDocumentAttribute getNSEditorDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSGeneratorDocumentAttribute, NSString *)
+#define NSGeneratorDocumentAttribute getNSGeneratorDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSCompanyDocumentAttribute, NSString *)
+#define NSCompanyDocumentAttribute getNSCompanyDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSDisplayNameDocumentAttribute, NSString *)
+#define NSDisplayNameDocumentAttribute getNSDisplayNameDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSCopyrightDocumentAttribute, NSString *)
+#define NSCopyrightDocumentAttribute getNSCopyrightDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSSubjectDocumentAttribute, NSString *)
+#define NSSubjectDocumentAttribute getNSSubjectDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSCommentDocumentAttribute, NSString *)
+#define NSCommentDocumentAttribute getNSCommentDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSNoIndexDocumentAttribute, NSString *)
+#define NSNoIndexDocumentAttribute getNSNoIndexDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSKeywordsDocumentAttribute, NSString *)
+#define NSKeywordsDocumentAttribute getNSKeywordsDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSCreationTimeDocumentAttribute, NSString *)
+#define NSCreationTimeDocumentAttribute getNSCreationTimeDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSModificationTimeDocumentAttribute, NSString *)
+#define NSModificationTimeDocumentAttribute getNSModificationTimeDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSConvertedDocumentAttribute, NSString *)
+#define NSConvertedDocumentAttribute getNSConvertedDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSCocoaVersionDocumentAttribute, NSString *)
+#define NSCocoaVersionDocumentAttribute getNSCocoaVersionDocumentAttribute()
+
+#define PlatformNSShadow            getNSShadowClass()
+#define PlatformNSTextAttachment    getNSTextAttachmentClass()
+#define PlatformNSParagraphStyle    getNSParagraphStyleClass()
+#define PlatformNSTextList          getNSTextListClass()
+#define PlatformNSTextTableBlock    getNSTextTableBlockClass()
+#define PlatformNSTextTable         getNSTextTableClass()
+#define PlatformNSTextTab           getNSTextTabClass()
+#define PlatformColor               UIColor
+#define PlatformColorClass          getUIColorClass()
+#define PlatformNSColorClass        getNSColorClass()
+#define PlatformFont                UIFont
+#define PlatformFontClass           getUIFontClass()
+
+// We don't softlink NSSuperscriptAttributeName because UIFoundation stopped exporting it.
+// This attribute is being deprecated at the API level, but internally UIFoundation
+// will continue to support it.
+static NSString *const NSSuperscriptAttributeName = @&quot;NSSuperscript&quot;;
+#else
+
+#define PlatformNSShadow            NSShadow
+#define PlatformNSTextAttachment    NSTextAttachment
+#define PlatformNSParagraphStyle    NSParagraphStyle
+#define PlatformNSTextList          NSTextList
+#define PlatformNSTextTableBlock    NSTextTableBlock
+#define PlatformNSTextTable         NSTextTable
+#define PlatformNSTextTab           NSTextTab
+#define PlatformColor               NSColor
+#define PlatformColorClass          NSColor
+#define PlatformNSColorClass        NSColor
+#define PlatformFont                NSFont
+#define PlatformFontClass           NSFont
+
+#define NSTextAlignmentLeft         NSLeftTextAlignment
+#define NSTextAlignmentRight        NSRightTextAlignment
+#define NSTextAlignmentCenter       NSCenterTextAlignment
+#define NSTextAlignmentJustified    NSJustifiedTextAlignment
+#endif
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+#if PLATFORM(IOS)
+
+typedef enum {
+    UIFontTraitPlain       = 0x00000000,
+    UIFontTraitItalic      = 0x00000001, // 1 &lt;&lt; 0
+    UIFontTraitBold        = 0x00000002, // 1 &lt;&lt; 1
+    UIFontTraitThin        = (1 &lt;&lt; 2),
+    UIFontTraitLight       = (1 &lt;&lt; 3),
+    UIFontTraitUltraLight  = (1 &lt;&lt; 4)
+} UIFontTrait;
+
+typedef NS_ENUM(NSInteger, NSUnderlineStyle) {
+    NSUnderlineStyleNone                                = 0x00,
+    NSUnderlineStyleSingle                              = 0x01,
+    NSUnderlineStyleThick NS_ENUM_AVAILABLE_IOS(7_0)    = 0x02,
+    NSUnderlineStyleDouble NS_ENUM_AVAILABLE_IOS(7_0)   = 0x09,
+
+    NSUnderlinePatternSolid NS_ENUM_AVAILABLE_IOS(7_0)      = 0x0000,
+    NSUnderlinePatternDot NS_ENUM_AVAILABLE_IOS(7_0)        = 0x0100,
+    NSUnderlinePatternDash NS_ENUM_AVAILABLE_IOS(7_0)       = 0x0200,
+    NSUnderlinePatternDashDot NS_ENUM_AVAILABLE_IOS(7_0)    = 0x0300,
+    NSUnderlinePatternDashDotDot NS_ENUM_AVAILABLE_IOS(7_0) = 0x0400,
+
+    NSUnderlineByWord NS_ENUM_AVAILABLE_IOS(7_0) = 0x8000
+};
+
+enum {
+    NSTextBlockAbsoluteValueType    = 0,    // Absolute value in points
+    NSTextBlockPercentageValueType  = 1     // Percentage value (out of 100)
+};
+typedef NSUInteger NSTextBlockValueType;
+
+enum {
+    NSTextBlockWidth            = 0,
+    NSTextBlockMinimumWidth     = 1,
+    NSTextBlockMaximumWidth     = 2,
+    NSTextBlockHeight           = 4,
+    NSTextBlockMinimumHeight    = 5,
+    NSTextBlockMaximumHeight    = 6
+};
+typedef NSUInteger NSTextBlockDimension;
+
+enum {
+    NSTextBlockPadding  = -1,
+    NSTextBlockBorder   =  0,
+    NSTextBlockMargin   =  1
+};
+typedef NSInteger NSTextBlockLayer;
+
+enum {
+    NSTextTableAutomaticLayoutAlgorithm = 0,
+    NSTextTableFixedLayoutAlgorithm     = 1
+};
+typedef NSUInteger NSTextTableLayoutAlgorithm;
+
+enum {
+    NSTextBlockTopAlignment         = 0,
+    NSTextBlockMiddleAlignment      = 1,
+    NSTextBlockBottomAlignment      = 2,
+    NSTextBlockBaselineAlignment    = 3
+};
+typedef NSUInteger NSTextBlockVerticalAlignment;
+
+typedef NS_ENUM(NSInteger, NSTextAlignment) {
+    NSTextAlignmentLeft      = 0,    // Visually left aligned
+    NSTextAlignmentCenter    = 1,    // Visually centered
+    NSTextAlignmentRight     = 2,    // Visually right aligned
+    NSTextAlignmentJustified = 3,    // Fully-justified. The last line in a paragraph is natural-aligned.
+    NSTextAlignmentNatural   = 4,    // Indicates the default alignment for script
+} NS_ENUM_AVAILABLE_IOS(6_0);
+
+typedef NS_ENUM(NSInteger, NSWritingDirection) {
+    NSWritingDirectionNatural       = -1,    // Determines direction using the Unicode Bidi Algorithm rules P2 and P3
+    NSWritingDirectionLeftToRight   =  0,    // Left to right writing direction
+    NSWritingDirectionRightToLeft   =  1     // Right to left writing direction
+} NS_ENUM_AVAILABLE_IOS(6_0);
+
+typedef NS_ENUM(NSInteger, NSTextWritingDirection) {
+    NSTextWritingDirectionEmbedding     = (0 &lt;&lt; 1),
+    NSTextWritingDirectionOverride      = (1 &lt;&lt; 1)
+} NS_ENUM_AVAILABLE_IOS(7_0);
+
+enum {
+    NSEnterCharacter                = 0x0003,
+    NSBackspaceCharacter            = 0x0008,
+    NSTabCharacter                  = 0x0009,
+    NSNewlineCharacter              = 0x000a,
+    NSFormFeedCharacter             = 0x000c,
+    NSCarriageReturnCharacter       = 0x000d,
+    NSBackTabCharacter              = 0x0019,
+    NSDeleteCharacter               = 0x007f,
+    NSLineSeparatorCharacter        = 0x2028,
+    NSParagraphSeparatorCharacter   = 0x2029,
+    NSAttachmentCharacter           = 0xFFFC // Replacement character is used for attachments
+};
+
+enum {
+    NSLeftTabStopType = 0,
+    NSRightTabStopType,
+    NSCenterTabStopType,
+    NSDecimalTabStopType
+};
+typedef NSUInteger NSTextTabType;
+
+@interface UIColor : NSObject
++ (UIColor *)clearColor;
+- (CGFloat)alphaComponent;
++ (UIColor *)_disambiguated_due_to_CIImage_colorWithCGColor:(CGColorRef)cgColor;
+@end
+
+@interface NSColor : UIColor
++ (id)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
+@end
+
+@interface UIFont
++ (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;
++ (UIFont *)fontWithFamilyName:(NSString *)familyName traits:(UIFontTrait)traits size:(CGFloat)fontSize;
+- (NSString *)familyName;
+- (CGFloat)pointSize;
+- (UIFont *)fontWithSize:(CGFloat)fontSize;
++ (NSArray *)familyNames;
++ (NSArray *)fontNamesForFamilyName:(NSString *)familyName;
++ (UIFont *)systemFontOfSize:(CGFloat)fontSize;
+@end
+
+@interface NSTextTab
+- (id)initWithType:(NSTextTabType)type location:(CGFloat)loc;
+- (id)initWithTextAlignment:(NSTextAlignment)alignment location:(CGFloat)loc options:(NSDictionary *)options;
+- (CGFloat)location;
+- (void)release;
+@end
+
+@interface NSParagraphStyle : NSObject
++ (NSParagraphStyle *)defaultParagraphStyle;
+- (void)setAlignment:(NSTextAlignment)alignment;
+- (void)setBaseWritingDirection:(NSWritingDirection)writingDirection;
+- (void)setHeadIndent:(CGFloat)aFloat;
+- (CGFloat)headIndent;
+- (void)setHeaderLevel:(NSInteger)level;
+- (void)setFirstLineHeadIndent:(CGFloat)aFloat;
+- (void)setTailIndent:(CGFloat)aFloat;
+- (void)setParagraphSpacing:(CGFloat)paragraphSpacing;
+- (void)setTextLists:(NSArray *)array;
+- (void)setTextBlocks:(NSArray *)array;
+- (void)setMinimumLineHeight:(CGFloat)aFloat;
+- (NSArray *)textLists;
+- (void)removeTabStop:(NSTextTab *)anObject;
+- (void)addTabStop:(NSTextTab *)anObject;
+- (NSArray *)tabStops;
+- (void)setHyphenationFactor:(float)aFactor;
+@end
+
+@interface NSShadow
+- (void)setShadowOffset:(CGSize)size;
+- (void)setShadowBlurRadius:(CGFloat)radius;
+- (void)setShadowColor:(UIColor *)color;
+@end
+
+@interface NSTextBlock : NSObject
+- (void)setValue:(CGFloat)val type:(NSTextBlockValueType)type forDimension:(NSTextBlockDimension)dimension;
+- (void)setWidth:(CGFloat)val type:(NSTextBlockValueType)type forLayer:(NSTextBlockLayer)layer edge:(NSRectEdge)edge;
+- (void)setBackgroundColor:(UIColor *)color;
+- (UIColor *)backgroundColor;
+- (void)setBorderColor:(UIColor *)color forEdge:(NSRectEdge)edge;
+- (void)setBorderColor:(UIColor *)color;        // Convenience method sets all edges at once
+- (void)setVerticalAlignment:(NSTextBlockVerticalAlignment)alignment;
+@end
+
+@interface NSTextList
+- (id)initWithMarkerFormat:(NSString *)format options:(NSUInteger)mask;
+- (void)setStartingItemNumber:(NSInteger)itemNum;
+- (NSInteger)startingItemNumber;
+- (NSString *)markerForItemNumber:(NSInteger)itemNum;
+- (void)release;
+@end
+
+@interface NSMutableParagraphStyle : NSParagraphStyle
+- (void)setDefaultTabInterval:(CGFloat)aFloat;
+- (void)setTabStops:(NSArray *)array;
+@end
+
+@interface NSTextAttachment : NSObject
+- (id)initWithFileWrapper:(NSFileWrapper *)fileWrapper;
+#if PLATFORM(IOS)
+- (void)setBounds:(CGRect)bounds;
+#endif
+- (void)release;
+@end
+
+@interface NSTextTable : NSTextBlock
+- (void)setNumberOfColumns:(NSUInteger)numCols;
+- (void)setCollapsesBorders:(BOOL)flag;
+- (void)setHidesEmptyCells:(BOOL)flag;
+- (void)setLayoutAlgorithm:(NSTextTableLayoutAlgorithm)algorithm;
+- (NSUInteger)numberOfColumns;
+- (void)release;
+@end
+
+@interface NSTextTableBlock : NSTextBlock
+- (id)initWithTable:(NSTextTable *)table startingRow:(NSInteger)row rowSpan:(NSInteger)rowSpan startingColumn:(NSInteger)col columnSpan:(NSInteger)colSpan;     // Designated initializer
+- (NSInteger)startingColumn;
+- (NSInteger)startingRow;
+- (NSUInteger)numberOfColumns;
+- (NSInteger)columnSpan;
+- (NSInteger)rowSpan;
+@end
+
+#else
+static NSFileWrapper *fileWrapperForURL(DocumentLoader *, NSURL *);
+static NSFileWrapper *fileWrapperForElement(Element*);
+
+@interface NSTextAttachment (WebCoreNSTextAttachment)
+- (void)setIgnoresOrientation:(BOOL)flag;
+- (void)setBounds:(CGRect)bounds;
+- (BOOL)ignoresOrientation;
+@end
+
+#endif
+
+// Additional control Unicode characters
+const unichar WebNextLineCharacter = 0x0085;
+
+class HTMLConverterCaches {
+public:
+    String propertyValueForNode(Node&amp;, CSSPropertyID );
+    bool floatPropertyValueForNode(Node&amp;, CSSPropertyID, float&amp;);
+    Color colorPropertyValueForNode(Node&amp;, CSSPropertyID);
+
+    bool isBlockElement(Element&amp;);
+    bool elementHasOwnBackgroundColor(Element&amp;);
+
+    PassRefPtr&lt;CSSValue&gt; computedStylePropertyForElement(Element&amp;, CSSPropertyID);
+    PassRefPtr&lt;CSSValue&gt; inlineStylePropertyForElement(Element&amp;, CSSPropertyID);
+
+private:
+    HashMap&lt;Element*, std::unique_ptr&lt;ComputedStyleExtractor&gt;&gt; m_computedStyles;
+};
+
+@interface NSTextList (WebCoreNSTextListDetails)
++ (NSDictionary *)_standardMarkerAttributesForAttributes:(NSDictionary *)attrs;
+@end
+
+@interface NSURL (WebCoreNSURLDetails)
+// FIXME: What is the reason to use this Foundation method, and not +[NSURL URLWithString:relativeToURL:]?
++ (NSURL *)_web_URLWithString:(NSString *)string relativeToURL:(NSURL *)baseURL;
+@end
+
+@interface NSObject(WebMessageDocumentSimulation)
++ (void)document:(NSObject **)outDocument attachment:(NSTextAttachment **)outAttachment forURL:(NSURL *)url;
+@end
+
+@interface WebHTMLConverter : NSObject {
+    NSMutableAttributedString *_attrStr;
+    NSMutableDictionary *_documentAttrs;
+    NSURL *_baseURL;
+    DOMDocument *_document;
+    DOMRange *_domRange;
+    NSMutableArray *_domStartAncestors;
+    WebCore::DocumentLoader *_dataSource;
+    NSString *_standardFontFamily;
+    CGFloat _textSizeMultiplier;
+    CGFloat _webViewTextSizeMultiplier;
+    CGFloat _defaultTabInterval;
+    CGFloat _defaultFontSize;
+    CGFloat _minimumFontSize;
+    NSMutableArray *_textLists;
+    NSMutableArray *_textBlocks;
+    NSMutableArray *_textTables;
+    NSMutableDictionary *_textTableFooters;
+    NSMutableArray *_textTableSpacings;
+    NSMutableArray *_textTablePaddings;
+    NSMutableArray *_textTableRows;
+    NSMutableArray *_textTableRowArrays;
+    NSMutableArray *_textTableRowBackgroundColors;
+    NSMutableDictionary *_colorsForNodes;
+    NSMutableDictionary *_attributesForElements;
+    NSMutableDictionary *_fontCache;
+    NSMutableArray *_writingDirectionArray;
+    NSUInteger _domRangeStartIndex;
+    NSInteger _indexingLimit;
+    NSUInteger _thumbnailLimit;
+    NSInteger _errorCode;
+    NSInteger _quoteLevel;
+
+    std::unique_ptr&lt;HTMLConverterCaches&gt; _caches;
+
+    struct {
+        unsigned int isSoft:1;
+        unsigned int reachedStart:1;
+        unsigned int reachedEnd:1;
+        unsigned int isIndexing:1;
+        unsigned int isTesting:1;
+        unsigned int hasTrailingNewline:1;
+        unsigned int pad:26;
+    } _flags;
+}
+
++ (NSAttributedString *)attributedStringFromRange:(Range*)range;
+#if !PLATFORM(IOS)
++ (NSAttributedString *)editingAttributedStringFromRange:(Range*)range;
+#endif
+@end
+
+@interface WebHTMLConverter(WebHTMLConverterInternal)
+
+- (id)init;
+- (id)initWithDOMRange:(DOMRange *)domRange;
+- (NSAttributedString *)attributedString;
+
+- (NSString *)_stringForNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
+- (PlatformColor *)_colorForNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
+- (BOOL)_getFloat:(CGFloat *)val forNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
+
+- (void)_traverseNode:(DOMNode *)node depth:(NSInteger)depth embedded:(BOOL)embedded;
+- (void)_traverseFooterNode:(DOMNode *)node depth:(NSInteger)depth;
+
+@end
+
+@implementation WebHTMLConverter
+
+#if !PLATFORM(IOS)
+// Returns the font to be used if the NSFontAttributeName doesn't exist
+static NSFont *WebDefaultFont()
+{
+    static NSFont *defaultFont = nil;
+    if (defaultFont)
+        return defaultFont;
+
+    NSFont *font = [NSFont fontWithName:@&quot;Helvetica&quot; size:12];
+    if (!font)
+        font = [NSFont systemFontOfSize:12];
+
+    defaultFont = [font retain];
+    return defaultFont;
+}
+#endif
+
+static PlatformFont *_fontForNameAndSize(NSString *fontName, CGFloat size, NSMutableDictionary *cache)
+{
+    PlatformFont *font = [cache objectForKey:fontName];
+#if PLATFORM(IOS)
+    if (font)
+        return [font fontWithSize:size];
+
+    font = [PlatformFontClass fontWithName:fontName size:size];
+#else
+    NSFontManager *fontManager = [NSFontManager sharedFontManager];
+    if (font) {
+        font = [fontManager convertFont:font toSize:size];
+        return font;
+    }
+    font = [fontManager fontWithFamily:fontName traits:0 weight:0 size:size];
+#endif
+    if (!font) {
+#if PLATFORM(IOS)
+        NSArray *availableFamilyNames = [PlatformFontClass familyNames];
+#else
+        NSArray *availableFamilyNames = [fontManager availableFontFamilies];
+#endif
+        NSRange dividingRange;
+        NSRange dividingSpaceRange = [fontName rangeOfString:@&quot; &quot; options:NSBackwardsSearch];
+        NSRange dividingDashRange = [fontName rangeOfString:@&quot;-&quot; options:NSBackwardsSearch];
+        dividingRange = (0 &lt; dividingSpaceRange.length &amp;&amp; 0 &lt; dividingDashRange.length) ? (dividingSpaceRange.location &gt; dividingDashRange.location ? dividingSpaceRange : dividingDashRange) : (0 &lt; dividingSpaceRange.length ? dividingSpaceRange : dividingDashRange);
+
+        while (dividingRange.length &gt; 0) {
+            NSString *familyName = [fontName substringToIndex:dividingRange.location];
+            if ([availableFamilyNames containsObject:familyName]) {
+#if PLATFORM(IOS)
+                NSString *faceName = [fontName substringFromIndex:(dividingRange.location + dividingRange.length)];
+                NSArray *familyMemberFaceNames = [PlatformFontClass fontNamesForFamilyName:familyName];
+                for (NSString *familyMemberFaceName in familyMemberFaceNames) {
+                    if ([familyMemberFaceName compare:faceName options:NSCaseInsensitiveSearch] == NSOrderedSame) {
+                        font = [PlatformFontClass fontWithName:familyMemberFaceName size:size];
+                        break;
+                    }
+                }
+                if (!font &amp;&amp; [familyMemberFaceNames count])
+                    font = [getUIFontClass() fontWithName:familyName size:size];
+#else
+                NSArray *familyMemberArray;
+                NSString *faceName = [fontName substringFromIndex:(dividingRange.location + dividingRange.length)];
+                NSArray *familyMemberArrays = [fontManager availableMembersOfFontFamily:familyName];
+                NSEnumerator *familyMemberArraysEnum = [familyMemberArrays objectEnumerator];
+                while ((familyMemberArray = [familyMemberArraysEnum nextObject])) {
+                    NSString *familyMemberFaceName = [familyMemberArray objectAtIndex:1];
+                    if ([familyMemberFaceName compare:faceName options:NSCaseInsensitiveSearch] == NSOrderedSame) {
+                        NSFontTraitMask traits = [[familyMemberArray objectAtIndex:3] integerValue];
+                        NSInteger weight = [[familyMemberArray objectAtIndex:2] integerValue];
+                        font = [fontManager fontWithFamily:familyName traits:traits weight:weight size:size];
+                        break;
+                    }
+                }
+                if (!font) {
+                    if (0 &lt; [familyMemberArrays count]) {
+                        NSArray *familyMemberArray = [familyMemberArrays objectAtIndex:0];
+                        NSFontTraitMask traits = [[familyMemberArray objectAtIndex:3] integerValue];
+                        NSInteger weight = [[familyMemberArray objectAtIndex:2] integerValue];
+                        font = [fontManager fontWithFamily:familyName traits:traits weight:weight size:size];
+                    }
+                }
+#endif
+                break;
+            } else {
+                dividingSpaceRange = [familyName rangeOfString:@&quot; &quot; options:NSBackwardsSearch];
+                dividingDashRange = [familyName rangeOfString:@&quot;-&quot; options:NSBackwardsSearch];
+                dividingRange = (0 &lt; dividingSpaceRange.length &amp;&amp; 0 &lt; dividingDashRange.length) ? (dividingSpaceRange.location &gt; dividingDashRange.location ? dividingSpaceRange : dividingDashRange) : (0 &lt; dividingSpaceRange.length ? dividingSpaceRange : dividingDashRange);
+            }
+        }
+    }
+#if PLATFORM(IOS)
+    if (!font)
+        font = [PlatformFontClass systemFontOfSize:size];
+#else
+    if (!font)
+        font = [NSFont fontWithName:@&quot;Times&quot; size:size];
+    if (!font)
+        font = [NSFont userFontOfSize:size];
+    if (!font)
+        font = [fontManager convertFont:WebDefaultFont() toSize:size];
+    if (!font)
+        font = WebDefaultFont();
+#endif
+    [cache setObject:font forKey:fontName];
+
+    return font;
+}
+
++ (NSParagraphStyle *)defaultParagraphStyle
+{
+    static NSMutableParagraphStyle *defaultParagraphStyle = nil;
+    if (!defaultParagraphStyle) {
+        defaultParagraphStyle = [[PlatformNSParagraphStyle defaultParagraphStyle] mutableCopy];
+        [defaultParagraphStyle setDefaultTabInterval:36];
+        [defaultParagraphStyle setTabStops:[NSArray array]];
+    }
+    return defaultParagraphStyle;
+}
+
+- (NSArray *)_childrenForNode:(DOMNode *)node
+{
+    NSMutableArray *array = [NSMutableArray array];
+    DOMNode *child = [node firstChild];
+    while (child) {
+        [array addObject:child];
+        child = [child nextSibling];
+    }
+    return array;
+}
+
+PassRefPtr&lt;CSSValue&gt; HTMLConverterCaches::computedStylePropertyForElement(Element&amp; element, CSSPropertyID propertyId)
+{
+    if (propertyId == CSSPropertyInvalid)
+        return nullptr;
+
+    auto result = m_computedStyles.add(&amp;element, nullptr);
+    if (result.isNewEntry)
+        result.iterator-&gt;value = std::make_unique&lt;ComputedStyleExtractor&gt;(&amp;element, true);
+    ComputedStyleExtractor&amp; computedStyle = *result.iterator-&gt;value;
+    return computedStyle.propertyValue(propertyId);
+}
+
+PassRefPtr&lt;CSSValue&gt; HTMLConverterCaches::inlineStylePropertyForElement(Element&amp; element, CSSPropertyID propertyId)
+{
+    if (propertyId == CSSPropertyInvalid || !element.isStyledElement())
+        return nullptr;
+    const StyleProperties* properties = toStyledElement(element).inlineStyle();
+    if (!properties)
+        return nullptr;
+    return properties-&gt;getPropertyCSSValue(propertyId);
+}
+
+static bool stringFromCSSValue(CSSValue&amp; value, String&amp; result)
+{
+    if (value.isPrimitiveValue()) {
+        unsigned short primitiveType = toCSSPrimitiveValue(value).primitiveType();
+        if (primitiveType == CSSPrimitiveValue::CSS_STRING || primitiveType == CSSPrimitiveValue::CSS_URI ||
+            primitiveType == CSSPrimitiveValue::CSS_IDENT || primitiveType == CSSPrimitiveValue::CSS_ATTR) {
+            String stringValue = value.cssText();
+            if (stringValue.length()) {
+                result = stringValue;
+                return true;
+            }
+        }
+    } else if (value.isValueList()) {
+        result = value.cssText();
+        return true;
+    }
+    return false;
+}
+
+String HTMLConverterCaches::propertyValueForNode(Node&amp; node, CSSPropertyID propertyId)
+{
+    if (!node.isElementNode()) {
+        if (Node* parent = node.parentNode())
+            return propertyValueForNode(*parent, propertyId);
+        return String();
+    }
+
+    bool inherit = false;
+    Element&amp; element = toElement(node);
+    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
+        String result;
+        if (stringFromCSSValue(*value, result))
+            return result;
+    }
+
+    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
+        String result;
+        if (value-&gt;isInheritedValue())
+            inherit = true;
+        else if (stringFromCSSValue(*value, result))
+            return result;
+    }
+
+    switch (propertyId) {
+    case CSSPropertyDisplay:
+        if (element.hasTagName(headTag) || element.hasTagName(scriptTag) || element.hasTagName(appletTag) || element.hasTagName(noframesTag))
+            return &quot;none&quot;;
+        else if (element.hasTagName(addressTag) || element.hasTagName(blockquoteTag) || element.hasTagName(bodyTag) || element.hasTagName(centerTag)
+             || element.hasTagName(ddTag) || element.hasTagName(dirTag) || element.hasTagName(divTag) || element.hasTagName(dlTag)
+             || element.hasTagName(dtTag) || element.hasTagName(fieldsetTag) || element.hasTagName(formTag) || element.hasTagName(frameTag)
+             || element.hasTagName(framesetTag) || element.hasTagName(hrTag) || element.hasTagName(htmlTag) || element.hasTagName(h1Tag)
+             || element.hasTagName(h2Tag) || element.hasTagName(h3Tag) || element.hasTagName(h4Tag) || element.hasTagName(h5Tag)
+             || element.hasTagName(h6Tag) || element.hasTagName(iframeTag) || element.hasTagName(menuTag) || element.hasTagName(noscriptTag)
+             || element.hasTagName(olTag) || element.hasTagName(pTag) || element.hasTagName(preTag) || element.hasTagName(ulTag))
+            return &quot;block&quot;;
+        else if (element.hasTagName(liTag))
+            return &quot;list-item&quot;;
+        else if (element.hasTagName(tableTag))
+            return &quot;table&quot;;
+        else if (element.hasTagName(trTag))
+            return &quot;table-row&quot;;
+        else if (element.hasTagName(thTag) || element.hasTagName(tdTag))
+            return &quot;table-cell&quot;;
+        else if (element.hasTagName(theadTag))
+            return &quot;table-header-group&quot;;
+        else if (element.hasTagName(tbodyTag))
+            return &quot;table-row-group&quot;;
+        else if (element.hasTagName(tfootTag))
+            return &quot;table-footer-group&quot;;
+        else if (element.hasTagName(colTag))
+            return &quot;table-column&quot;;
+        else if (element.hasTagName(colgroupTag))
+            return &quot;table-column-group&quot;;
+        else if (element.hasTagName(captionTag))
+            return &quot;table-caption&quot;;
+        break;
+    case CSSPropertyWhiteSpace:
+        if (element.hasTagName(preTag))
+            return &quot;pre&quot;;
+        inherit = true;
+        break;
+    case CSSPropertyFontStyle:
+        if (element.hasTagName(iTag) || element.hasTagName(citeTag) || element.hasTagName(emTag) || element.hasTagName(varTag) || element.hasTagName(addressTag))
+            return &quot;italic&quot;;
+        inherit = true;
+        break;
+    case CSSPropertyFontWeight:
+        if (element.hasTagName(bTag) || element.hasTagName(strongTag) || element.hasTagName(thTag))
+            return &quot;bolder&quot;;
+        inherit = true;
+        break;
+    case CSSPropertyTextDecoration:
+        if (element.hasTagName(uTag) || element.hasTagName(insTag))
+            return &quot;underline&quot;;
+        else if (element.hasTagName(sTag) || element.hasTagName(strikeTag) || element.hasTagName(delTag))
+            return &quot;line-through&quot;;
+        inherit = true; // FIXME: This is not strictly correct
+        break;
+    case CSSPropertyTextAlign:
+        if (element.hasTagName(centerTag) || element.hasTagName(captionTag) || element.hasTagName(thTag))
+            return &quot;center&quot;;
+        inherit = true;
+        break;
+    case CSSPropertyVerticalAlign:
+        if (element.hasTagName(supTag))
+            return &quot;super&quot;;
+        else if (element.hasTagName(subTag))
+            return &quot;sub&quot;;
+        else if (element.hasTagName(theadTag) || element.hasTagName(tbodyTag) || element.hasTagName(tfootTag))
+            return &quot;middle&quot;;
+        else if (element.hasTagName(trTag) || element.hasTagName(thTag) || element.hasTagName(tdTag))
+            inherit = true;
+        break;
+    case CSSPropertyFontFamily:
+    case CSSPropertyFontVariant:
+    case CSSPropertyTextTransform:
+    case CSSPropertyTextShadow:
+    case CSSPropertyVisibility:
+    case CSSPropertyBorderCollapse:
+    case CSSPropertyEmptyCells:
+    case CSSPropertyWordSpacing:
+    case CSSPropertyListStyleType:
+    case CSSPropertyDirection:
+        inherit = true; // FIXME: Let classes in the css component figure this out.
+        break;
+    default:
+        break;
+    }
+
+    if (inherit) {
+        if (Node* parent = node.parentNode())
+            return propertyValueForNode(*parent, propertyId);
+    }
+    
+    return String();
+}
+
+- (NSString *)_stringForNode:(DOMNode *)node property:(CSSPropertyID)propertyId
+{
+    Node* coreNode = core(node);
+    if (!coreNode)
+        return nil;
+    String result = _caches-&gt;propertyValueForNode(*coreNode, propertyId);
+    if (!result.length())
+        return nil;
+    return result;
+}
+
+static inline bool floatValueFromPrimitiveValue(CSSPrimitiveValue&amp; primitiveValue, float&amp; result)
+{
+    // FIXME: Use CSSPrimitiveValue::computeValue.
+    switch (primitiveValue.primitiveType()) {
+    case CSSPrimitiveValue::CSS_PX:
+        result = primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PX);
+        return true;
+    case CSSPrimitiveValue::CSS_PT:
+        result = 4 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PT) / 3;
+        return true;
+    case CSSPrimitiveValue::CSS_PC:
+        result = 16 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC);
+        return true;
+    case CSSPrimitiveValue::CSS_CM:
+        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC) / 2.54;
+        return true;
+    case CSSPrimitiveValue::CSS_MM:
+        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC) / 25.4;
+        return true;
+    case CSSPrimitiveValue::CSS_IN:
+        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_IN);
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool HTMLConverterCaches::floatPropertyValueForNode(Node&amp; node, CSSPropertyID propertyId, float&amp; result)
+{
+    if (!node.isElementNode()) {
+        if (ContainerNode* parent = node.parentNode())
+            return floatPropertyValueForNode(*parent, propertyId, result);
+        return false;
+    }
+
+    Element&amp; element = toElement(node);
+    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
+        if (value-&gt;isPrimitiveValue() &amp;&amp; floatValueFromPrimitiveValue(toCSSPrimitiveValue(*value), result))
+            return true;
+    }
+
+    bool inherit = false;
+    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
+        if (value-&gt;isPrimitiveValue() &amp;&amp; floatValueFromPrimitiveValue(toCSSPrimitiveValue(*value), result))
+            return true;
+        if (value-&gt;isInheritedValue())
+            inherit = true;
+    }
+
+    switch (propertyId) {
+    case CSSPropertyTextIndent:
+    case CSSPropertyLetterSpacing:
+    case CSSPropertyWordSpacing:
+    case CSSPropertyLineHeight:
+    case CSSPropertyWidows:
+    case CSSPropertyOrphans:
+        inherit = true;
+        break;
+    default:
+        break;
+    }
+
+    if (inherit) {
+        if (ContainerNode* parent = node.parentNode())
+            return floatPropertyValueForNode(*parent, propertyId, result);
+    }
+
+    return false;
+}
+
+- (BOOL)_getFloat:(CGFloat *)val forNode:(DOMNode *)node property:(CSSPropertyID)propertyId
+{
+    Node* coreNode = core(node);
+    if (!coreNode)
+        return NO;
+    float result;
+    if (!_caches-&gt;floatPropertyValueForNode(*coreNode, propertyId, result))
+        return NO;
+    if (val)
+        *val = result;
+    return YES;
+}
+
+static NSString *_NSFirstPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde)
+{
+    NSArray *array = NSSearchPathForDirectoriesInDomains(directory, domainMask, expandTilde);
+    return [array count] &gt;= 1 ? [array objectAtIndex:0] : nil;
+}
+
+static NSString *_NSSystemLibraryPath(void)
+{
+    return _NSFirstPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES);
+}
+
+- (NSBundle *)_webKitBundle
+{
+    NSBundle *bundle = [NSBundle bundleWithIdentifier:@&quot;com.apple.WebKit&quot;];
+    if (!bundle)
+        bundle = [NSBundle bundleWithPath:[_NSSystemLibraryPath() stringByAppendingPathComponent:@&quot;Frameworks/WebKit.framework&quot;]];
+    return bundle;
+}
+
+#if PLATFORM(IOS)
+static inline UIColor *_platformColor(Color color)
+{
+    return [getUIColorClass() _disambiguated_due_to_CIImage_colorWithCGColor:cachedCGColor(color, WebCore::ColorSpaceDeviceRGB)];
+}
+#else
+static inline NSColor *_platformColor(Color color)
+{
+    return nsColor(color);
+}
+#endif
+
+static inline NSShadow *_shadowForShadowStyle(NSString *shadowStyle)
+{
+    NSShadow *shadow = nil;
+    NSUInteger shadowStyleLength = [shadowStyle length];
+    NSRange openParenRange = [shadowStyle rangeOfString:@&quot;(&quot;];
+    NSRange closeParenRange = [shadowStyle rangeOfString:@&quot;)&quot;];
+    NSRange firstRange = NSMakeRange(NSNotFound, 0);
+    NSRange secondRange = NSMakeRange(NSNotFound, 0);
+    NSRange thirdRange = NSMakeRange(NSNotFound, 0);
+    NSRange spaceRange;
+    if (openParenRange.length &gt; 0 &amp;&amp; closeParenRange.length &gt; 0 &amp;&amp; NSMaxRange(openParenRange) &lt; closeParenRange.location) {
+        NSArray *components = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(openParenRange), closeParenRange.location - NSMaxRange(openParenRange))] componentsSeparatedByString:@&quot;,&quot;];
+        if ([components count] &gt;= 3) {
+            CGFloat red = [[components objectAtIndex:0] floatValue] / 255;
+            CGFloat green = [[components objectAtIndex:1] floatValue] / 255;
+            CGFloat blue = [[components objectAtIndex:2] floatValue] / 255;
+            CGFloat alpha = ([components count] &gt;= 4) ? [[components objectAtIndex:3] floatValue] / 255 : 1;
+            NSColor *shadowColor = [PlatformNSColorClass colorWithCalibratedRed:red green:green blue:blue alpha:alpha];
+            NSSize shadowOffset;
+            CGFloat shadowBlurRadius;
+            firstRange = [shadowStyle rangeOfString:@&quot;px&quot;];
+            if (firstRange.length &gt; 0 &amp;&amp; NSMaxRange(firstRange) &lt; shadowStyleLength)
+                secondRange = [shadowStyle rangeOfString:@&quot;px&quot; options:0 range:NSMakeRange(NSMaxRange(firstRange), shadowStyleLength - NSMaxRange(firstRange))];
+            if (secondRange.length &gt; 0 &amp;&amp; NSMaxRange(secondRange) &lt; shadowStyleLength)
+                thirdRange = [shadowStyle rangeOfString:@&quot;px&quot; options:0 range:NSMakeRange(NSMaxRange(secondRange), shadowStyleLength - NSMaxRange(secondRange))];
+            if (firstRange.location &gt; 0 &amp;&amp; firstRange.length &gt; 0 &amp;&amp; secondRange.length &gt; 0 &amp;&amp; thirdRange.length &gt; 0) {
+                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, firstRange.location)];
+                if (spaceRange.length == 0)
+                    spaceRange = NSMakeRange(0, 0);
+                shadowOffset.width = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), firstRange.location - NSMaxRange(spaceRange))] floatValue];
+                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, secondRange.location)];
+                if (!spaceRange.length)
+                    spaceRange = NSMakeRange(0, 0);
+                CGFloat shadowHeight = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), secondRange.location - NSMaxRange(spaceRange))] floatValue];
+                // I don't know why we have this difference between the two platforms.
+#if PLATFORM(IOS)
+                shadowOffset.height = shadowHeight;
+#else
+                shadowOffset.height = -shadowHeight;
+#endif
+                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, thirdRange.location)];
+                if (!spaceRange.length)
+                    spaceRange = NSMakeRange(0, 0);
+                shadowBlurRadius = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), thirdRange.location - NSMaxRange(spaceRange))] floatValue];
+                shadow = [[[PlatformNSShadow alloc] init] autorelease];
+                [shadow setShadowColor:shadowColor];
+                [shadow setShadowOffset:shadowOffset];
+                [shadow setShadowBlurRadius:shadowBlurRadius];
+            }
+        }
+    }
+    return shadow;
+}
+
+bool HTMLConverterCaches::isBlockElement(Element&amp; element)
+{
+    String displayValue = propertyValueForNode(element, CSSPropertyDisplay);
+    if (displayValue == &quot;block&quot; || displayValue == &quot;list-item&quot; || displayValue.startsWith(&quot;table&quot;))
+        return true;
+    String floatValue = propertyValueForNode(element, CSSPropertyFloat);
+    if (floatValue == &quot;left&quot; || floatValue == &quot;right&quot;)
+        return true;
+    return false;
+}
+
+bool HTMLConverterCaches::elementHasOwnBackgroundColor(Element&amp; element)
+{
+    if (!isBlockElement(element))
+        return false;
+    // In the text system, text blocks (table elements) and documents (body elements)
+    // have their own background colors, which should not be inherited.
+    return element.hasTagName(htmlTag) || element.hasTagName(bodyTag) || propertyValueForNode(element, CSSPropertyDisplay).startsWith(&quot;table&quot;);
+}
+
+- (BOOL)_elementIsBlockLevel:(DOMElement *)element
+{
+    return element &amp;&amp; _caches-&gt;isBlockElement(*core(element));
+}
+
+- (BOOL)_elementHasOwnBackgroundColor:(DOMElement *)element
+{
+    return element &amp;&amp; _caches-&gt;elementHasOwnBackgroundColor(*core(element));
+}
+
+- (DOMElement *)_blockLevelElementForNode:(DOMNode *)node
+{
+    DOMElement *element = (DOMElement *)node;
+    while (element &amp;&amp; [element nodeType] != DOM_ELEMENT_NODE)
+        element = (DOMElement *)[element parentNode];
+    if (element &amp;&amp; ![self _elementIsBlockLevel:element])
+        element = [self _blockLevelElementForNode:[element parentNode]];
+    return element;
+}
+
+static Color normalizedColor(Color color, bool ignoreBlack)
+{
+    const double ColorEpsilon = 1 / (2 * (double)255.0);
+    
+    double red, green, blue, alpha;
+    color.getRGBA(red, green, blue, alpha);
+    if (red &lt; ColorEpsilon &amp;&amp; green &lt; ColorEpsilon &amp;&amp; blue &lt; ColorEpsilon &amp;&amp; (ignoreBlack || alpha &lt; ColorEpsilon))
+        return Color();
+    
+    return color;
+}
+
+Color HTMLConverterCaches::colorPropertyValueForNode(Node&amp; node, CSSPropertyID propertyId)
+{
+    if (!node.isElementNode()) {
+        if (Node* parent = node.parentNode())
+            return colorPropertyValueForNode(*parent, propertyId);
+        return Color();
+    }
+
+    Element&amp; element = toElement(node);
+    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
+        if (value-&gt;isPrimitiveValue() &amp;&amp; toCSSPrimitiveValue(*value).isRGBColor())
+            return normalizedColor(Color(toCSSPrimitiveValue(*value).getRGBA32Value()), propertyId == CSSPropertyColor);
+    }
+
+    bool inherit = false;
+    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
+        if (value-&gt;isPrimitiveValue() &amp;&amp; toCSSPrimitiveValue(*value).isRGBColor())
+            return normalizedColor(Color(toCSSPrimitiveValue(*value).getRGBA32Value()), propertyId == CSSPropertyColor);
+        if (value-&gt;isInheritedValue())
+            inherit = true;
+    }
+
+    switch (propertyId) {
+    case CSSPropertyColor:
+        inherit = true;
+        break;
+    case CSSPropertyBackgroundColor:
+        if (!elementHasOwnBackgroundColor(element)) {
+            if (Element* parentElement = node.parentElement()) {
+                if (!elementHasOwnBackgroundColor(*parentElement))
+                    inherit = true;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (inherit) {
+        if (Node* parent = node.parentNode())
+            return colorPropertyValueForNode(*parent, propertyId);
+    }
+
+    return Color();
+}
+
+- (PlatformColor *)_colorForNode:(DOMNode *)node property:(CSSPropertyID)propertyId
+{
+    Node* coreNode = core(node);
+    if (!coreNode)
+        return nil;
+    Color result = _caches-&gt;colorPropertyValueForNode(*coreNode, propertyId);
+    if (!result.isValid())
+        return nil;
+    PlatformColor *platformResult = _platformColor(result);
+    if ([[PlatformColorClass clearColor] isEqual:platformResult] || ([platformResult alphaComponent] == 0.0))
+        return nil;
+    return platformResult;
+}
+
+#define UIFloatIsZero(number) (fabs(number - 0) &lt; FLT_EPSILON)
+
+- (NSDictionary *)_computedAttributesForElement:(DOMElement *)element
+{
+    DOMElement *blockElement = [self _blockLevelElementForNode:element];
+    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
+#if !PLATFORM(IOS)
+    NSFontManager *fontManager = [NSFontManager sharedFontManager];
+#endif
+    NSString *textDecoration = [self _stringForNode:element property:CSSPropertyTextDecoration];
+    NSString *verticalAlign = [self _stringForNode:element property:CSSPropertyVerticalAlign];
+    NSString *textShadow = [self _stringForNode:element property:CSSPropertyTextShadow];
+    NSString *fontLigatures = [self _stringForNode:element property:CSSPropertyWebkitFontVariantLigatures];
+    NSString *fontKerning = [self _stringForNode:element property:CSSPropertyWebkitFontKerning];
+    NSString *letterSpacing = [self _stringForNode:element property:CSSPropertyLetterSpacing];
+    CGFloat fontSize = 0;
+    CGFloat baselineOffset = 0;
+    CGFloat strokeWidth = 0.0;
+    PlatformFont *font = nil;
+    PlatformFont *actualFont = (PlatformFont *)[element _font];
+    PlatformColor *foregroundColor = [self _colorForNode:element property:CSSPropertyColor];
+    PlatformColor *backgroundColor = [self _colorForNode:element property:CSSPropertyBackgroundColor];
+    PlatformColor *strokeColor = [self _colorForNode:element property:CSSPropertyWebkitTextStrokeColor];
+
+    if (![self _getFloat:&amp;fontSize forNode:element property:CSSPropertyFontSize] || fontSize &lt;= 0.0)
+        fontSize = _defaultFontSize;
+    fontSize *= _textSizeMultiplier;
+    if (fontSize &lt; _minimumFontSize) fontSize = _minimumFontSize;
+    if (fabs(floor(2.0 * fontSize + 0.5) / 2.0 - fontSize) &lt; 0.05)
+        fontSize = (CGFloat)floor(2.0 * fontSize + 0.5) / 2;
+    else if (fabs(floor(10.0 * fontSize + 0.5) / 10.0 - fontSize) &lt; 0.005)
+        fontSize = (CGFloat)floor(10.0 * fontSize + 0.5) / 10;
+
+    if (fontSize &lt;= 0.0)
+        fontSize = 12;
+    
+#if PLATFORM(IOS)
+    if (actualFont)
+        font = [actualFont fontWithSize:fontSize];
+#else
+    if (actualFont)
+        font = [fontManager convertFont:actualFont toSize:fontSize];
+#endif
+    if (!font) {
+        NSString *fontName = [[self _stringForNode:element property:CSSPropertyFontFamily] capitalizedString];
+        NSString *fontStyle = [self _stringForNode:element property:CSSPropertyFontStyle];
+        NSString *fontWeight = [self _stringForNode:element property:CSSPropertyFontWeight];
+#if !PLATFORM(IOS)
+        NSString *fontVariant = [self _stringForNode:element property:CSSPropertyFontVariant];
+#endif
+        if (!fontName)
+            fontName = _standardFontFamily;
+        if (fontName)
+            font = _fontForNameAndSize(fontName, fontSize, _fontCache);
+        if (!font)
+            font = [PlatformFontClass fontWithName:@&quot;Times&quot; size:fontSize];
+        if ([@&quot;italic&quot; isEqualToString:fontStyle] || [@&quot;oblique&quot; isEqualToString:fontStyle]) {
+            PlatformFont *originalFont = font;
+#if PLATFORM(IOS)
+            font = [PlatformFontClass fontWithFamilyName:[font familyName] traits:UIFontTraitItalic size:[font pointSize]];
+#else
+            font = [fontManager convertFont:font toHaveTrait:NSItalicFontMask];
+#endif
+            if (!font)
+                font = originalFont;
+        }
+        if ([fontWeight hasPrefix:@&quot;bold&quot;] || [fontWeight integerValue] &gt;= 700) {
+            // ??? handle weight properly using NSFontManager
+            PlatformFont *originalFont = font;
+#if PLATFORM(IOS)
+            font = [PlatformFontClass fontWithFamilyName:[font familyName] traits:UIFontTraitBold size:[font pointSize]];
+#else
+            font = [fontManager convertFont:font toHaveTrait:NSBoldFontMask];
+#endif
+            if (!font)
+                font = originalFont;
+        }
+#if !PLATFORM(IOS) // IJB: No small caps support on iOS
+        if ([@&quot;small-caps&quot; isEqualToString:fontVariant]) {
+            // ??? synthesize small-caps if [font isEqual:originalFont]
+            NSFont *originalFont = font;
+            font = [fontManager convertFont:font toHaveTrait:NSSmallCapsFontMask];
+            if (!font)
+                font = originalFont;
+        }
+#endif
+    }
+    if (font)
+        [attrs setObject:font forKey:NSFontAttributeName];
+    if (foregroundColor)
+        [attrs setObject:foregroundColor forKey:NSForegroundColorAttributeName];
+    if (backgroundColor &amp;&amp; ![self _elementHasOwnBackgroundColor:element])
+        [attrs setObject:backgroundColor forKey:NSBackgroundColorAttributeName];
+
+    if ([self _getFloat:&amp;strokeWidth forNode:element property:CSSPropertyWebkitTextStrokeWidth]) {
+        float textStrokeWidth = strokeWidth / ([font pointSize] * 0.01);
+        [attrs setObject:[NSNumber numberWithDouble:textStrokeWidth] forKey:NSStrokeWidthAttributeName];
+    }
+    if(strokeColor)
+        [attrs setObject:strokeColor forKey:NSStrokeColorAttributeName];
+    if (fontKerning || letterSpacing) {
+        if ([fontKerning rangeOfString:@&quot;none&quot;].location != NSNotFound)
+            [attrs setObject:@0.0 forKey:NSKernAttributeName];
+        else {
+            double kernVal = letterSpacing ? [letterSpacing doubleValue] : 0.0;
+            if (UIFloatIsZero(kernVal))
+                [attrs setObject:@0.0 forKey:NSKernAttributeName]; // auto and normal, the other possible values, are both &quot;kerning enabled&quot;
+            else
+                [attrs setObject:[NSNumber numberWithDouble:kernVal] forKey:NSKernAttributeName];
+        }
+    }
+    if (fontLigatures) {
+        if ([fontLigatures rangeOfString:@&quot;normal&quot;].location != NSNotFound)
+            ;   // default: whatever the system decides to do
+        else if ([fontLigatures rangeOfString:@&quot;common-ligatures&quot;].location != NSNotFound)
+            [attrs setObject:@1 forKey:NSLigatureAttributeName];   // explicitly enabled
+        else if ([fontLigatures rangeOfString:@&quot;no-common-ligatures&quot;].location != NSNotFound)
+            [attrs setObject:@0 forKey:NSLigatureAttributeName];  // explicitly disabled
+    }
+
+    if (textDecoration &amp;&amp; [textDecoration length] &gt; 4) {
+        if ([textDecoration rangeOfString:@&quot;underline&quot;].location != NSNotFound)
+            [attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
+        if ([textDecoration rangeOfString:@&quot;line-through&quot;].location != NSNotFound)
+            [attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
+    }
+    if (verticalAlign) {
+        if ([verticalAlign rangeOfString:@&quot;super&quot;].location != NSNotFound)
+            [attrs setObject:[NSNumber numberWithInteger:1] forKey:NSSuperscriptAttributeName];
+        if ([verticalAlign rangeOfString:@&quot;sub&quot;].location != NSNotFound)
+            [attrs setObject:[NSNumber numberWithInteger:-1] forKey:NSSuperscriptAttributeName];
+    }
+    if ([self _getFloat:&amp;baselineOffset forNode:element property:CSSPropertyVerticalAlign])
+        [attrs setObject:[NSNumber numberWithDouble:baselineOffset] forKey:NSBaselineOffsetAttributeName];
+    if (textShadow &amp;&amp; [textShadow length] &gt; 4) {
+        NSShadow *shadow = _shadowForShadowStyle(textShadow);
+        if (shadow)
+            [attrs setObject:shadow forKey:NSShadowAttributeName];
+    }
+    if (element != blockElement &amp;&amp; [_writingDirectionArray count] &gt; 0)
+        [attrs setObject:[NSArray arrayWithArray:_writingDirectionArray] forKey:NSWritingDirectionAttributeName];
+    
+    if (blockElement) {
+        NSMutableParagraphStyle *paragraphStyle = [[[self class] defaultParagraphStyle] mutableCopy];
+        NSString *blockTag = [blockElement tagName];
+        BOOL isParagraph = ([@&quot;P&quot; isEqualToString:blockTag] || [@&quot;LI&quot; isEqualToString:blockTag] || ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]));
+        NSString *textAlign = [self _stringForNode:blockElement property:CSSPropertyTextAlign];
+        NSString *direction = [self _stringForNode:blockElement property:CSSPropertyDirection];
+        NSString *hyphenation = [self _stringForNode:blockElement property:CSSPropertyWebkitHyphens];
+        CGFloat leftMargin = 0;
+        CGFloat rightMargin = 0;
+        CGFloat bottomMargin = 0;
+        CGFloat textIndent = 0;
+        CGFloat lineHeight = 0;
+        if (textAlign) {
+            // WebKit can return -khtml-left, -khtml-right, -khtml-center
+            if ([textAlign hasSuffix:@&quot;left&quot;])
+                [paragraphStyle setAlignment:NSTextAlignmentLeft];
+            else if ([textAlign hasSuffix:@&quot;right&quot;])
+                [paragraphStyle setAlignment:NSTextAlignmentRight];
+            else if ([textAlign hasSuffix:@&quot;center&quot;])
+                [paragraphStyle setAlignment:NSTextAlignmentCenter];
+            else if ([textAlign hasSuffix:@&quot;justify&quot;])
+                [paragraphStyle setAlignment:NSTextAlignmentJustified];
+        }
+        if (direction) {
+            if ([direction isEqualToString:@&quot;ltr&quot;])
+                [paragraphStyle setBaseWritingDirection:NSWritingDirectionLeftToRight];
+            else if ([direction isEqualToString:@&quot;rtl&quot;])
+                [paragraphStyle setBaseWritingDirection:NSWritingDirectionRightToLeft];
+        }
+        if(hyphenation) {
+            if ([hyphenation isEqualToString:@&quot;auto&quot;])
+                [paragraphStyle setHyphenationFactor:1.0];
+            else
+                [paragraphStyle setHyphenationFactor:0.0];
+        }
+        if ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]) {
+            NSInteger headerLevel = [blockTag characterAtIndex:1] - '0';
+            if (1 &lt;= headerLevel &amp;&amp; headerLevel &lt;= 6)
+                [paragraphStyle setHeaderLevel:headerLevel];
+        }
+        if (isParagraph) {
+            if ([self _getFloat:&amp;leftMargin forNode:blockElement property:CSSPropertyMarginLeft] &amp;&amp; leftMargin &gt; 0.0)
+                [paragraphStyle setHeadIndent:leftMargin];
+            if ([self _getFloat:&amp;textIndent forNode:blockElement property:CSSPropertyTextIndent])
+                [paragraphStyle setFirstLineHeadIndent:[paragraphStyle headIndent] + textIndent];
+            if ([self _getFloat:&amp;rightMargin forNode:blockElement property:CSSPropertyMarginRight] &amp;&amp; rightMargin &gt; 0.0)
+                [paragraphStyle setTailIndent:-rightMargin];
+            if ([self _getFloat:&amp;bottomMargin forNode:blockElement property:CSSPropertyMarginBottom] &amp;&amp; bottomMargin &gt; 0.0)
+                [paragraphStyle setParagraphSpacing:bottomMargin];
+        }
+        if (_webViewTextSizeMultiplier &gt; 0.0 &amp;&amp; [self _getFloat:&amp;lineHeight forNode:element property:CSSPropertyLineHeight] &amp;&amp; lineHeight &gt; 0.0)
+            [paragraphStyle setMinimumLineHeight:lineHeight / _webViewTextSizeMultiplier];
+        if ([_textLists count] &gt; 0)
+            [paragraphStyle setTextLists:_textLists];
+        if ([_textBlocks count] &gt; 0)
+            [paragraphStyle setTextBlocks:_textBlocks];
+        [attrs setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
+        [paragraphStyle release];
+    }
+    return attrs;
+}
+
+- (NSDictionary *)_attributesForElement:(DOMElement *)element
+{
+    NSDictionary *result;
+    if (element) {
+        result = [_attributesForElements objectForKey:element];
+        if (!result) {
+            result = [self _computedAttributesForElement:element];
+            [_attributesForElements setObject:result forKey:element];
+        }
+    } else
+        result = [NSDictionary dictionary];
+    return result;
+
+}
+
+- (void)_newParagraphForElement:(DOMElement *)element tag:(NSString *)tag allowEmpty:(BOOL)flag suppressTrailingSpace:(BOOL)suppress
+{
+    NSUInteger textLength = [_attrStr length];
+    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
+    NSRange rangeToReplace = (suppress &amp;&amp; _flags.isSoft &amp;&amp; (lastChar == ' ' || lastChar == NSLineSeparatorCharacter)) ? NSMakeRange(textLength - 1, 1) : NSMakeRange(textLength, 0);
+    BOOL needBreak = (flag || lastChar != '\n');
+    if (needBreak) {
+        NSString *string = (([@&quot;BODY&quot; isEqualToString:tag] || [@&quot;HTML&quot; isEqualToString:tag]) ? @&quot;&quot; : @&quot;\n&quot;);
+        [_writingDirectionArray removeAllObjects];
+        [_attrStr replaceCharactersInRange:rangeToReplace withString:string];
+        if (rangeToReplace.location &lt; _domRangeStartIndex)
+            _domRangeStartIndex += [string length] - rangeToReplace.length;
+        rangeToReplace.length = [string length];
+        if (!_flags.isIndexing) {
+            NSDictionary *attrs = [self _attributesForElement:element];
+            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+                [_attrStr setAttributes:attrs range:rangeToReplace];
+        }
+        _flags.isSoft = YES;
+    }
+}
+
+- (void)_newLineForElement:(DOMElement *)element
+{
+    unichar c = NSLineSeparatorCharacter;
+    RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithCharacters:&amp;c length:1]);
+    NSUInteger textLength = [_attrStr length];
+    NSRange rangeToReplace = NSMakeRange(textLength, 0);
+    [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
+    rangeToReplace.length = [string length];
+    if (rangeToReplace.location &lt; _domRangeStartIndex) _domRangeStartIndex += rangeToReplace.length;
+    if (!_flags.isIndexing) {
+        NSDictionary *attrs = [self _attributesForElement:element];
+        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+            [_attrStr setAttributes:attrs range:rangeToReplace];
+    }
+    _flags.isSoft = YES;
+}
+
+- (void)_newTabForElement:(DOMElement *)element
+{
+    NSString *string = @&quot;\t&quot;;
+    NSUInteger textLength = [_attrStr length];
+    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
+    NSRange rangeToReplace = (_flags.isSoft &amp;&amp; lastChar == ' ') ? NSMakeRange(textLength - 1, 1) : NSMakeRange(textLength, 0);
+    [_attrStr replaceCharactersInRange:rangeToReplace withString:string];
+    rangeToReplace.length = [string length];
+    if (rangeToReplace.location &lt; _domRangeStartIndex)
+        _domRangeStartIndex += rangeToReplace.length;
+    if (!_flags.isIndexing) {
+        NSDictionary *attrs = [self _attributesForElement:element];
+        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+            [_attrStr setAttributes:attrs range:rangeToReplace];
+    }
+    _flags.isSoft = YES;
+}
+
+- (Class)_WebMessageDocumentClass
+{
+    static Class _WebMessageDocumentClass = Nil;
+    static BOOL lookedUpClass = NO;
+    if (!lookedUpClass) {
+        // If the class is not there, we don't want to try again
+        _WebMessageDocumentClass = objc_lookUpClass(&quot;MFWebMessageDocument&quot;);
+        if (_WebMessageDocumentClass &amp;&amp; ![_WebMessageDocumentClass respondsToSelector:@selector(document:attachment:forURL:)])
+            _WebMessageDocumentClass = Nil;
+        lookedUpClass = YES;
+    }
+    return _WebMessageDocumentClass;
+}
+
+- (BOOL)_addAttachmentForElement:(DOMElement *)element URL:(NSURL *)url needsParagraph:(BOOL)needsParagraph usePlaceholder:(BOOL)flag
+{
+    BOOL retval = NO, notFound = NO;
+    NSFileWrapper *fileWrapper = nil;
+    Frame* frame = core([element ownerDocument])-&gt;frame();
+    DocumentLoader *dataSource = frame-&gt;loader().frameHasLoaded() ? frame-&gt;loader().documentLoader() : 0;
+    BOOL ignoreOrientation = YES;
+
+    if (_flags.isIndexing)
+        return NO;
+    if ([url isFileURL]) {
+        NSString *path = [[url path] stringByStandardizingPath];
+        if (path)
+            fileWrapper = [[[NSFileWrapper alloc] initWithURL:url options:0 error:NULL] autorelease];
+    }
+    if (!fileWrapper) {
+        RefPtr&lt;ArchiveResource&gt; resource = dataSource-&gt;subresource(url);
+        if (!resource)
+            resource = dataSource-&gt;subresource(url);
+
+        const String&amp; mimeType = resource-&gt;mimeType();
+        if (flag &amp;&amp; resource &amp;&amp; mimeType == &quot;text/html&quot;)
+            notFound = YES;
+        if (resource &amp;&amp; !notFound) {
+            fileWrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:resource-&gt;data()-&gt;createNSData().get()] autorelease];
+            [fileWrapper setPreferredFilename:suggestedFilenameWithMIMEType(url, mimeType)];
+        }
+    }
+#if !PLATFORM(IOS)
+    if (!fileWrapper &amp;&amp; !notFound) {
+        fileWrapper = fileWrapperForURL(dataSource, url);
+        if (flag &amp;&amp; fileWrapper &amp;&amp; [[[[fileWrapper preferredFilename] pathExtension] lowercaseString] hasPrefix:@&quot;htm&quot;]) notFound = YES;
+        if (notFound) fileWrapper = nil;
+    }
+    if (!fileWrapper &amp;&amp; !notFound) {
+        fileWrapper = fileWrapperForURL(_dataSource, url);
+        if (flag &amp;&amp; fileWrapper &amp;&amp; [[[[fileWrapper preferredFilename] pathExtension] lowercaseString] hasPrefix:@&quot;htm&quot;]) notFound = YES;
+        if (notFound) fileWrapper = nil;
+    }
+#endif
+    if (!fileWrapper &amp;&amp; !notFound &amp;&amp; url) {
+        // Special handling for Mail attachments, until WebKit provides a standard way to get the data.
+        Class WebMessageDocumentClass = [self _WebMessageDocumentClass];
+        if (WebMessageDocumentClass) {
+            NSTextAttachment *mimeTextAttachment = nil;
+            [WebMessageDocumentClass document:NULL attachment:&amp;mimeTextAttachment forURL:url];
+            if (mimeTextAttachment &amp;&amp; [mimeTextAttachment respondsToSelector:@selector(fileWrapper)]) {
+                fileWrapper = [mimeTextAttachment performSelector:@selector(fileWrapper)];
+                ignoreOrientation = NO;
+            }
+        }
+    }
+    if (fileWrapper || flag) {
+        NSUInteger textLength = [_attrStr length];
+        RetainPtr&lt;NSTextAttachment&gt; attachment = adoptNS([[PlatformNSTextAttachment alloc] initWithFileWrapper:fileWrapper]);
+#if PLATFORM(IOS)
+        NSString *vAlign = [self _stringForNode:element property:CSSPropertyVerticalAlign];
+        attachment.get().bounds = CGRectMake(0, ([vAlign floatValue] / 100.) * element.clientHeight, element.clientWidth, element.clientHeight);
+#endif
+        RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithFormat:(needsParagraph ? @&quot;%C\n&quot; : @&quot;%C&quot;), static_cast&lt;unichar&gt;(NSAttachmentCharacter)]);
+        NSRange rangeToReplace = NSMakeRange(textLength, 0);
+        NSDictionary *attrs;
+        if (fileWrapper) {
+#if !PLATFORM(IOS)
+            if (ignoreOrientation)
+                [attachment setIgnoresOrientation:YES];
+#endif
+        } else {
+#if PLATFORM(IOS)
+            [attachment release];
+            NSURL *missingImageURL = [[self _webKitBundle] URLForResource:@&quot;missing_image&quot; withExtension:@&quot;tiff&quot;];
+            ASSERT_WITH_MESSAGE(missingImageURL != nil, &quot;Unable to find missing_image.tiff!&quot;);
+            NSFileWrapper *missingImageFileWrapper = [[[NSFileWrapper alloc] initWithURL:missingImageURL options:0 error:NULL] autorelease];
+            attachment = [[PlatformNSTextAttachment alloc] initWithFileWrapper:missingImageFileWrapper];
+#else
+            static NSImage *missingImage = nil;
+            NSTextAttachmentCell *cell;
+            cell = [[NSTextAttachmentCell alloc] initImageCell:missingImage];
+            [attachment setAttachmentCell:cell];
+            [cell release];
+#endif
+        }
+        [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
+        rangeToReplace.length = [string length];
+        if (rangeToReplace.location &lt; _domRangeStartIndex)
+            _domRangeStartIndex += rangeToReplace.length;
+        attrs = [self _attributesForElement:element];
+        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0) {
+            [_attrStr setAttributes:attrs range:rangeToReplace];
+            rangeToReplace.length = 1;
+            [_attrStr addAttribute:NSAttachmentAttributeName value:attachment.get() range:rangeToReplace];
+        }
+        _flags.isSoft = NO;
+        retval = YES;
+    }
+    return retval;
+}
+
+- (void)_addQuoteForElement:(DOMElement *)element opening:(BOOL)opening level:(NSInteger)level
+{
+    unichar c = ((level % 2) == 0) ? (opening ? 0x201c : 0x201d) : (opening ? 0x2018 : 0x2019);
+    RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithCharacters:&amp;c length:1]);
+    NSUInteger textLength = [_attrStr length];
+    NSRange rangeToReplace = NSMakeRange(textLength, 0);
+    [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
+    rangeToReplace.length = [string length];
+    if (rangeToReplace.location &lt; _domRangeStartIndex)
+        _domRangeStartIndex += rangeToReplace.length;
+    if (!_flags.isIndexing) {
+        RetainPtr&lt;NSDictionary&gt; attrs = [self _attributesForElement:element];
+        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+            [_attrStr setAttributes:attrs.get() range:rangeToReplace];
+    }
+    _flags.isSoft = NO;
+}
+
+- (void)_addValue:(NSString *)value forElement:(DOMElement *)element
+{
+    NSUInteger textLength = [_attrStr length];
+    NSUInteger valueLength = [value length];
+    NSRange rangeToReplace = NSMakeRange(textLength, 0);
+    if (valueLength) {
+        [_attrStr replaceCharactersInRange:rangeToReplace withString:value];
+        rangeToReplace.length = valueLength;
+        if (rangeToReplace.location &lt; _domRangeStartIndex)
+            _domRangeStartIndex += rangeToReplace.length;
+        if (!_flags.isIndexing) {
+            RetainPtr&lt;NSDictionary&gt; attrs = [self _attributesForElement:element];
+            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+                [_attrStr setAttributes:attrs.get() range:rangeToReplace];
+        }
+        _flags.isSoft = NO;
+    }
+}
+
+- (void)_fillInBlock:(NSTextBlock *)block forElement:(DOMElement *)element backgroundColor:(PlatformColor *)backgroundColor extraMargin:(CGFloat)extraMargin extraPadding:(CGFloat)extraPadding isTable:(BOOL)isTable
+{
+    CGFloat val = 0;
+    PlatformColor *color = nil;
+    BOOL isTableCellElement = [element isKindOfClass:[DOMHTMLTableCellElement class]];
+    NSString *width = isTableCellElement ? [(DOMHTMLTableCellElement *)element width] : [element getAttribute:@&quot;width&quot;];
+
+    if ((width &amp;&amp; [width length]) || !isTable) {
+        if ([self _getFloat:&amp;val forNode:element property:CSSPropertyWidth])
+            [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockWidth];
+    }
+    
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMinWidth])
+        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMinimumWidth];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMaxWidth])
+        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMaximumWidth];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMinHeight])
+        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMinimumHeight];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMaxHeight])
+        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMaximumHeight];
+
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingLeft])
+        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinXEdge];
+    else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingTop])
+        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinYEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinYEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingRight])
+        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxXEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingBottom])
+        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxYEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxYEdge];
+    
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderLeftWidth])
+        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMinXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderTopWidth])
+        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMinYEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderRightWidth])
+        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMaxXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderBottomWidth])
+        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMaxYEdge];
+
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginLeft])
+        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinXEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginTop])
+        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinYEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinYEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginRight])
+        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxXEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxXEdge];
+    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginBottom])
+        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxYEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxYEdge];
+
+    if ((color = [self _colorForNode:element property:CSSPropertyBackgroundColor]))
+        [block setBackgroundColor:color];
+    if (!color &amp;&amp; backgroundColor) [block setBackgroundColor:backgroundColor];
+    if ((color = [self _colorForNode:element property:CSSPropertyBorderLeftColor]))
+        [block setBorderColor:color forEdge:NSMinXEdge];
+    if ((color = [self _colorForNode:element property:CSSPropertyBorderTopColor]))
+        [block setBorderColor:color forEdge:NSMinYEdge];
+    if ((color = [self _colorForNode:element property:CSSPropertyBorderRightColor]))
+        [block setBorderColor:color forEdge:NSMaxXEdge];
+    if ((color = [self _colorForNode:element property:CSSPropertyBorderBottomColor]))
+        [block setBorderColor:color forEdge:NSMaxYEdge];
+}
+
+static inline BOOL read2DigitNumber(const char **pp, int8_t *outval)
+{
+    BOOL result = NO;
+    char c1 = *(*pp)++, c2;
+    if (isASCIIDigit(c1)) {
+        c2 = *(*pp)++;
+        if (isASCIIDigit(c2)) {
+            *outval = 10 * (c1 - '0') + (c2 - '0');
+            result = YES;
+        }
+    }
+    return result;
+}
+
+static inline NSDate *_dateForString(NSString *string)
+{
+    const char *p = [string UTF8String];
+    RetainPtr&lt;NSDateComponents&gt; dateComponents = adoptNS([[NSDateComponents alloc] init]);
+
+    // Set the time zone to GMT
+    [dateComponents setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
+
+    NSInteger year = 0;
+    while (*p &amp;&amp; isASCIIDigit(*p))
+        year = 10 * year + *p++ - '0';
+    if (*p++ != '-')
+        return nil;
+    [dateComponents setYear:year];
+
+    int8_t component;
+    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != '-')
+        return nil;
+    [dateComponents setMonth:component];
+
+    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != 'T')
+        return nil;
+    [dateComponents setDay:component];
+
+    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != ':')
+        return nil;
+    [dateComponents setHour:component];
+
+    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != ':')
+        return nil;
+    [dateComponents setMinute:component];
+
+    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != 'Z')
+        return nil;
+    [dateComponents setSecond:component];
+    
+#if (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 80000) || (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 1090)
+    NSString *calendarIdentifier = NSCalendarIdentifierGregorian;
+#else
+    NSString *calendarIdentifier = NSGregorianCalendar;
+#endif
+
+    return [[[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier] autorelease] dateFromComponents:dateComponents.get()];
+}
+
+static NSInteger _colCompare(id block1, id block2, void *)
+{
+    NSInteger col1 = [(NSTextTableBlock *)block1 startingColumn];
+    NSInteger col2 = [(NSTextTableBlock *)block2 startingColumn];
+    return ((col1 &lt; col2) ? NSOrderedAscending : ((col1 == col2) ? NSOrderedSame : NSOrderedDescending));
+}
+
+- (void)_processMetaElementWithName:(NSString *)name content:(NSString *)content {
+    NSString *key = nil;
+    if (NSOrderedSame == [@&quot;CocoaVersion&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        CGFloat versionNumber = [content doubleValue];
+        if (versionNumber &gt; 0.0) {
+            // ??? this should be keyed off of version number in future
+            [_documentAttrs removeObjectForKey:NSConvertedDocumentAttribute];
+            [_documentAttrs setObject:[NSNumber numberWithDouble:versionNumber] forKey:NSCocoaVersionDocumentAttribute];
+        }
+#if PLATFORM(IOS)
+    } else if (NSOrderedSame == [@&quot;Generator&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        key = NSGeneratorDocumentAttribute;
+#endif
+    } else if (NSOrderedSame == [@&quot;Keywords&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        if (content &amp;&amp; [content length] &gt; 0) {
+            NSArray *array;
+            // ??? need better handling here and throughout
+            if ([content rangeOfString:@&quot;, &quot;].length == 0 &amp;&amp; [content rangeOfString:@&quot;,&quot;].length &gt; 0)
+                array = [content componentsSeparatedByString:@&quot;,&quot;];
+            else if ([content rangeOfString:@&quot;, &quot;].length == 0 &amp;&amp; [content rangeOfString:@&quot; &quot;].length &gt; 0)
+                array = [content componentsSeparatedByString:@&quot; &quot;];
+            else
+                array = [content componentsSeparatedByString:@&quot;, &quot;];
+            [_documentAttrs setObject:array forKey:NSKeywordsDocumentAttribute];
+        }
+    } else if (NSOrderedSame == [@&quot;Author&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSAuthorDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;LastAuthor&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSEditorDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;Company&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSCompanyDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;Copyright&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSCopyrightDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;Subject&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSSubjectDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;Description&quot; compare:name options:NSCaseInsensitiveSearch] || NSOrderedSame == [@&quot;Comment&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSCommentDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;CreationTime&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        if (content &amp;&amp; [content length] &gt; 0) {
+            NSDate *date = _dateForString(content);
+            if (date)
+                [_documentAttrs setObject:date forKey:NSCreationTimeDocumentAttribute];
+        }
+    } else if (NSOrderedSame == [@&quot;ModificationTime&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        if (content &amp;&amp; [content length] &gt; 0) {
+            NSDate *date = _dateForString(content);
+            if (date)
+                [_documentAttrs setObject:date forKey:NSModificationTimeDocumentAttribute];
+        }
+    }
+#if PLATFORM(IOS)
+    else if (NSOrderedSame == [@&quot;DisplayName&quot; compare:name options:NSCaseInsensitiveSearch] || NSOrderedSame == [@&quot;IndexTitle&quot; compare:name options:NSCaseInsensitiveSearch])
+        key = NSDisplayNameDocumentAttribute;
+    else if (NSOrderedSame == [@&quot;robots&quot; compare:name options:NSCaseInsensitiveSearch]) {
+        if ([content rangeOfString:@&quot;noindex&quot; options:NSCaseInsensitiveSearch].length &gt; 0)
+            [_documentAttrs setObject:[NSNumber numberWithInteger:1] forKey:NSNoIndexDocumentAttribute];
+    }
+#endif
+    if (key &amp;&amp; content &amp;&amp; [content length] &gt; 0)
+        [_documentAttrs setObject:content forKey:key];
+}
+
+- (void)_processHeadElement:(DOMElement *)element {
+    // ??? should gather data from other sources e.g. Word, but for that we would need to be able to get comments from DOM
+    NSArray *childNodes = [self _childrenForNode:element];
+    NSUInteger count = [childNodes count];
+    for (NSUInteger i = 0; i &lt; count; i++) {
+        DOMNode *node = [childNodes objectAtIndex:i];
+        unsigned short nodeType = [node nodeType];
+        if (DOM_ELEMENT_NODE == nodeType) {
+            DOMElement *element = (DOMElement *)node;
+            NSString *tag = [element tagName];
+            if ([@&quot;META&quot; isEqualToString:tag] &amp;&amp; [element respondsToSelector:@selector(name)] &amp;&amp; [element respondsToSelector:@selector(content)]) {
+                NSString *name = [(DOMHTMLMetaElement *)element name];
+                NSString *content = [(DOMHTMLMetaElement *)element content];
+                if (name &amp;&amp; content)
+                    [self _processMetaElementWithName:name content:content];
+            }
+        }
+    }
+}
+
+- (BOOL)_enterElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal embedded:(BOOL)embedded
+{
+    if ([@&quot;HEAD&quot; isEqualToString:tag] &amp;&amp; !embedded)
+        [self _processHeadElement:element];
+    else if (!displayVal || !([@&quot;none&quot; isEqualToString:displayVal] || [@&quot;table-column&quot; isEqualToString:displayVal] || [@&quot;table-column-group&quot; isEqualToString:displayVal])) {
+        if ([self _elementIsBlockLevel:element] &amp;&amp; ![@&quot;BR&quot; isEqualToString:tag] &amp;&amp; !([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] == 0) 
+            &amp;&amp; !([_textLists count] &gt; 0 &amp;&amp; [@&quot;block&quot; isEqualToString:displayVal] &amp;&amp; ![@&quot;LI&quot; isEqualToString:tag] &amp;&amp; ![@&quot;UL&quot; isEqualToString:tag] &amp;&amp; ![@&quot;OL&quot; isEqualToString:tag]))
+            [self _newParagraphForElement:element tag:tag allowEmpty:NO suppressTrailingSpace:YES];
+        return YES;
+    }
+    return NO;
+}
+
+- (void)_addTableForElement:(DOMElement *)tableElement
+{
+    RetainPtr&lt;NSTextTable&gt; table = adoptNS([[PlatformNSTextTable alloc] init]);
+    CGFloat cellSpacingVal = 1;
+    CGFloat cellPaddingVal = 1;
+    [table setNumberOfColumns:1];
+    [table setLayoutAlgorithm:NSTextTableAutomaticLayoutAlgorithm];
+    [table setCollapsesBorders:NO];
+    [table setHidesEmptyCells:NO];
+    if (tableElement) {
+        NSString *borderCollapse = [self _stringForNode:tableElement property:CSSPropertyBorderCollapse];
+        NSString *emptyCells = [self _stringForNode:tableElement property:CSSPropertyEmptyCells];
+        NSString *tableLayout = [self _stringForNode:tableElement property:CSSPropertyTableLayout];
+        if ([tableElement respondsToSelector:@selector(cellSpacing)]) {
+            NSString *cellSpacing = [(DOMHTMLTableElement *)tableElement cellSpacing];
+            if (cellSpacing &amp;&amp; [cellSpacing length] &gt; 0 &amp;&amp; ![cellSpacing hasSuffix:@&quot;%&quot;]) cellSpacingVal = [cellSpacing floatValue];
+        }
+        if ([tableElement respondsToSelector:@selector(cellPadding)]) {
+            NSString *cellPadding = [(DOMHTMLTableElement *)tableElement cellPadding];
+            if (cellPadding &amp;&amp; [cellPadding length] &gt; 0 &amp;&amp; ![cellPadding hasSuffix:@&quot;%&quot;]) cellPaddingVal = [cellPadding floatValue];
+        }
+        [self _fillInBlock:table.get() forElement:tableElement backgroundColor:nil extraMargin:0 extraPadding:0 isTable:YES];
+        if ([@&quot;collapse&quot; isEqualToString:borderCollapse]) {
+            [table setCollapsesBorders:YES];
+            cellSpacingVal = 0;
+        }
+        if ([@&quot;hide&quot; isEqualToString:emptyCells]) [table setHidesEmptyCells:YES];
+        if ([@&quot;fixed&quot; isEqualToString:tableLayout]) [table setLayoutAlgorithm:NSTextTableFixedLayoutAlgorithm];
+    }
+    [_textTables addObject:table.get()];
+    [_textTableSpacings addObject:[NSNumber numberWithDouble:cellSpacingVal]];
+    [_textTablePaddings addObject:[NSNumber numberWithDouble:cellPaddingVal]];
+    [_textTableRows addObject:[NSNumber numberWithInteger:0]];
+    [_textTableRowArrays addObject:[NSMutableArray array]];
+}
+
+- (void)_addTableCellForElement:(DOMElement *)tableCellElement
+{
+    NSTextTable *table = [_textTables lastObject];
+    NSInteger rowNumber = [[_textTableRows lastObject] integerValue];
+    NSInteger columnNumber = 0;
+    NSInteger rowSpan = 1;
+    NSInteger colSpan = 1;
+    NSMutableArray *rowArray = [_textTableRowArrays lastObject];
+    NSUInteger count = [rowArray count];
+    PlatformColor *color = ([_textTableRowBackgroundColors count] &gt; 0) ? [_textTableRowBackgroundColors lastObject] : nil;
+    NSTextTableBlock *previousBlock;
+    CGFloat cellSpacingVal = [[_textTableSpacings lastObject] floatValue];
+    if ([color isEqual:[PlatformColorClass clearColor]]) color = nil;
+    for (NSUInteger i = 0; i &lt; count; i++) {
+        previousBlock = [rowArray objectAtIndex:i];
+        if (columnNumber &gt;= [previousBlock startingColumn] &amp;&amp; columnNumber &lt; [previousBlock startingColumn] + [previousBlock columnSpan])
+            columnNumber = [previousBlock startingColumn] + [previousBlock columnSpan];
+    }
+    if (tableCellElement) {
+        if ([tableCellElement respondsToSelector:@selector(rowSpan)]) {
+            rowSpan = [(DOMHTMLTableCellElement *)tableCellElement rowSpan];
+            if (rowSpan &lt; 1)
+                rowSpan = 1;
+        }
+        if ([tableCellElement respondsToSelector:@selector(colSpan)]) {
+            colSpan = [(DOMHTMLTableCellElement *)tableCellElement colSpan];
+            if (colSpan &lt; 1)
+                colSpan = 1;
+        }
+    }
+    RetainPtr&lt;NSTextTableBlock&gt; block = adoptNS([[PlatformNSTextTableBlock alloc] initWithTable:table startingRow:rowNumber rowSpan:rowSpan startingColumn:columnNumber columnSpan:colSpan]);
+    if (tableCellElement) {
+        NSString *verticalAlign = [self _stringForNode:tableCellElement property:CSSPropertyVerticalAlign];
+        [self _fillInBlock:block.get() forElement:tableCellElement backgroundColor:color extraMargin:cellSpacingVal / 2 extraPadding:0 isTable:NO];
+        if ([@&quot;middle&quot; isEqualToString:verticalAlign])
+            [block setVerticalAlignment:NSTextBlockMiddleAlignment];
+        else if ([@&quot;bottom&quot; isEqualToString:verticalAlign])
+            [block setVerticalAlignment:NSTextBlockBottomAlignment];
+        else if ([@&quot;baseline&quot; isEqualToString:verticalAlign])
+            [block setVerticalAlignment:NSTextBlockBaselineAlignment];
+        else if ([@&quot;top&quot; isEqualToString:verticalAlign])
+            [block setVerticalAlignment:NSTextBlockTopAlignment];
+    }
+    [_textBlocks addObject:block.get()];
+    [rowArray addObject:block.get()];
+    [rowArray sortUsingFunction:_colCompare context:NULL];
+}
+
+- (BOOL)_processElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal depth:(NSInteger)depth
+{
+    BOOL retval = YES;
+    BOOL isBlockLevel = [self _elementIsBlockLevel:element];
+    if (isBlockLevel)
+        [_writingDirectionArray removeAllObjects];
+    else {
+        NSString *bidi = [self _stringForNode:element property:CSSPropertyUnicodeBidi];
+        if (bidi &amp;&amp; [bidi isEqualToString:@&quot;embed&quot;]) {
+            NSUInteger val = NSTextWritingDirectionEmbedding;
+            NSString *direction = [self _stringForNode:element property:CSSPropertyDirection];
+            if ([direction isEqualToString:@&quot;rtl&quot;])
+                val |= NSWritingDirectionRightToLeft;
+            [_writingDirectionArray addObject:[NSNumber numberWithUnsignedInteger:val]];
+        } else if (bidi &amp;&amp; [bidi isEqualToString:@&quot;bidi-override&quot;]) {
+            NSUInteger val = NSTextWritingDirectionOverride;
+            NSString *direction = [self _stringForNode:element property:CSSPropertyDirection];
+            if ([direction isEqualToString:@&quot;rtl&quot;])
+                val |= NSWritingDirectionRightToLeft;
+            [_writingDirectionArray addObject:[NSNumber numberWithUnsignedInteger:val]];
+        }
+    }
+    if ([@&quot;table&quot; isEqualToString:displayVal] || ([_textTables count] == 0 &amp;&amp; [@&quot;table-row-group&quot; isEqualToString:displayVal])) {
+        DOMElement *tableElement = element;
+        if ([@&quot;table-row-group&quot; isEqualToString:displayVal]) {
+            // If we are starting in medias res, the first thing we see may be the tbody, so go up to the table
+            tableElement = [self _blockLevelElementForNode:[element parentNode]];
+            if (![@&quot;table&quot; isEqualToString:[self _stringForNode:tableElement property:CSSPropertyDisplay]])
+                tableElement = element;
+        }
+        while ([_textTables count] &gt; [_textBlocks count])
+            [self _addTableCellForElement:nil];
+        [self _addTableForElement:tableElement];
+    } else if ([@&quot;table-footer-group&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
+        [_textTableFooters setObject:element forKey:[NSValue valueWithNonretainedObject:[_textTables lastObject]]];
+        retval = NO;
+    } else if ([@&quot;table-row&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
+        PlatformColor *color = [self _colorForNode:element property:CSSPropertyBackgroundColor];
+        if (!color) color = [PlatformColorClass clearColor];
+        [_textTableRowBackgroundColors addObject:color];
+    } else if ([@&quot;table-cell&quot; isEqualToString:displayVal]) {
+        while ([_textTables count] &lt; [_textBlocks count] + 1) {
+            [self _addTableForElement:nil];
+        }
+        [self _addTableCellForElement:element];
+    } else if ([@&quot;IMG&quot; isEqualToString:tag]) {
+        NSString *urlString = [element getAttribute:@&quot;src&quot;];
+        if (urlString &amp;&amp; [urlString length] &gt; 0) {
+            NSURL *url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
+            if (!url) url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
+#if PLATFORM(IOS)
+            BOOL usePlaceholderImage = NO;
+#else
+            BOOL usePlaceholderImage = YES;
+#endif
+            if (url)
+                [self _addAttachmentForElement:element URL:url needsParagraph:isBlockLevel usePlaceholder:usePlaceholderImage];
+        }
+        retval = NO;
+    } else if ([@&quot;OBJECT&quot; isEqualToString:tag]) {
+        NSString *baseString = [element getAttribute:@&quot;codebase&quot;];
+        NSString *urlString = [element getAttribute:@&quot;data&quot;];
+        NSString *declareString = [element getAttribute:@&quot;declare&quot;];
+        if (urlString &amp;&amp; [urlString length] &gt; 0 &amp;&amp; ![@&quot;true&quot; isEqualToString:declareString]) {
+            NSURL *baseURL = nil;
+            NSURL *url = nil;
+            if (baseString &amp;&amp; [baseString length] &gt; 0) {
+                baseURL = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(baseString));
+                if (!baseURL)
+                    baseURL = [NSURL _web_URLWithString:[baseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
+            }
+            if (baseURL)
+                url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:baseURL];
+            if (!url)
+                url =core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
+            if (!url)
+                url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
+            if (url)
+                retval = ![self _addAttachmentForElement:element URL:url needsParagraph:isBlockLevel usePlaceholder:NO];
+        }
+    } else if ([@&quot;FRAME&quot; isEqualToString:tag]) {
+        if ([element respondsToSelector:@selector(contentDocument)]) {
+            DOMDocument *contentDocument = [(DOMHTMLFrameElement *)element contentDocument];
+            if (contentDocument)
+                [self _traverseNode:contentDocument depth:depth + 1 embedded:YES];
+        }
+        retval = NO;
+    } else if ([@&quot;IFRAME&quot; isEqualToString:tag]) {
+        if ([element respondsToSelector:@selector(contentDocument)]) {
+            DOMDocument *contentDocument = [(DOMHTMLIFrameElement *)element contentDocument];
+            if (contentDocument) {
+                [self _traverseNode:contentDocument depth:depth + 1 embedded:YES];
+                retval = NO;
+            }
+        }
+    } else if ([@&quot;BR&quot; isEqualToString:tag]) {
+        DOMElement *blockElement = [self _blockLevelElementForNode:[element parentNode]];
+        NSString *breakClass = [element getAttribute:@&quot;class&quot;], *blockTag = [blockElement tagName];
+        BOOL isExtraBreak = [@&quot;Apple-interchange-newline&quot; isEqualToString:breakClass], blockElementIsParagraph = ([@&quot;P&quot; isEqualToString:blockTag] || [@&quot;LI&quot; isEqualToString:blockTag] || ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]));
+        if (isExtraBreak)
+            _flags.hasTrailingNewline = YES;
+        else {
+            if (blockElement &amp;&amp; blockElementIsParagraph)
+                [self _newLineForElement:element];
+            else
+                [self _newParagraphForElement:element tag:tag allowEmpty:YES suppressTrailingSpace:NO];
+        }
+    } else if ([@&quot;UL&quot; isEqualToString:tag]) {
+        RetainPtr&lt;NSTextList&gt; list;
+        NSString *listStyleType = [self _stringForNode:element property:CSSPropertyListStyleType];
+        if (!listStyleType || [listStyleType length] == 0)
+            listStyleType = @&quot;disc&quot;;
+        list = adoptNS([[PlatformNSTextList alloc] initWithMarkerFormat:[NSString stringWithFormat:@&quot;{%@}&quot;, listStyleType] options:0]);
+        [_textLists addObject:list.get()];
+    } else if ([@&quot;OL&quot; isEqualToString:tag]) {
+        RetainPtr&lt;NSTextList&gt; list;
+        NSString *listStyleType = [self _stringForNode:element property:CSSPropertyListStyleType];
+        if (!listStyleType || [listStyleType length] == 0) listStyleType = @&quot;decimal&quot;;
+        list = adoptNS([[PlatformNSTextList alloc] initWithMarkerFormat:[NSString stringWithFormat:@&quot;{%@}.&quot;, listStyleType] options:0]);
+        if ([element respondsToSelector:@selector(start)]) {
+            NSInteger startingItemNumber = [(DOMHTMLOListElement *)element start];
+            [list setStartingItemNumber:startingItemNumber];
+        }
+        [_textLists addObject:list.get()];
+    } else if ([@&quot;Q&quot; isEqualToString:tag]) {
+        [self _addQuoteForElement:element opening:YES level:_quoteLevel++];
+    } else if ([@&quot;INPUT&quot; isEqualToString:tag]) {
+        if ([element respondsToSelector:@selector(type)] &amp;&amp; [element respondsToSelector:@selector(value)] &amp;&amp; [@&quot;text&quot; compare:[(DOMHTMLInputElement *)element type] options:NSCaseInsensitiveSearch] == NSOrderedSame) {
+            NSString *value = [(DOMHTMLInputElement *)element value];
+            if (value &amp;&amp; [value length] &gt; 0) [self _addValue:value forElement:element];
+        }
+    } else if ([@&quot;TEXTAREA&quot; isEqualToString:tag]) {
+        if ([element respondsToSelector:@selector(value)]) {
+            NSString *value = [(DOMHTMLTextAreaElement *)element value];
+            if (value &amp;&amp; [value length] &gt; 0) [self _addValue:value forElement:element];
+        }
+        retval = NO;
+    }
+    return retval;
+}
+
+- (void)_addMarkersToList:(NSTextList *)list range:(NSRange)range
+{
+    NSInteger itemNum = [list startingItemNumber];
+    NSString *string = [_attrStr string];
+    NSString *stringToInsert;
+    NSDictionary *attrsToInsert = nil;
+    PlatformFont *font;
+    NSParagraphStyle *paragraphStyle;
+    NSMutableParagraphStyle *newStyle;
+    NSTextTab *tab = nil;
+    NSTextTab *tabToRemove;
+    NSRange paragraphRange;
+    NSRange styleRange;
+    NSUInteger textLength = [_attrStr length];
+    NSUInteger listIndex;
+    NSUInteger insertLength;
+    NSUInteger i;
+    NSUInteger count;
+    NSArray *textLists;
+    CGFloat markerLocation;
+    CGFloat listLocation;
+    CGFloat pointSize;
+    
+    if (range.length == 0 || range.location &gt;= textLength)
+        return;
+    if (NSMaxRange(range) &gt; textLength)
+        range.length = textLength - range.location;
+    paragraphStyle = [_attrStr attribute:NSParagraphStyleAttributeName atIndex:range.location effectiveRange:NULL];
+    if (paragraphStyle) {
+        textLists = [paragraphStyle textLists];
+        listIndex = [textLists indexOfObject:list];
+        if (textLists &amp;&amp; listIndex != NSNotFound) {
+            for (NSUInteger idx = range.location; idx &lt; NSMaxRange(range);) {
+                paragraphRange = [string paragraphRangeForRange:NSMakeRange(idx, 0)];
+                paragraphStyle = [_attrStr attribute:NSParagraphStyleAttributeName atIndex:idx effectiveRange:&amp;styleRange];
+                font = [_attrStr attribute:NSFontAttributeName atIndex:idx effectiveRange:NULL];
+                pointSize = font ? [font pointSize] : 12;
+                if ([[paragraphStyle textLists] count] == listIndex + 1) {
+                    stringToInsert = [NSString stringWithFormat:@&quot;\t%@\t&quot;, [list markerForItemNumber:itemNum++]];
+                    insertLength = [stringToInsert length];
+                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting)
+                        attrsToInsert = [PlatformNSTextList _standardMarkerAttributesForAttributes:[_attrStr attributesAtIndex:paragraphRange.location effectiveRange:NULL]];
+
+                    [_attrStr replaceCharactersInRange:NSMakeRange(paragraphRange.location, 0) withString:stringToInsert];
+                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting) [_attrStr setAttributes:attrsToInsert range:NSMakeRange(paragraphRange.location, insertLength)];
+                    range.length += insertLength;
+                    paragraphRange.length += insertLength;
+                    if (paragraphRange.location &lt; _domRangeStartIndex) _domRangeStartIndex += insertLength;
+                    
+                    newStyle = [paragraphStyle mutableCopy];
+                    listLocation = (listIndex + 1) * 36;
+                    markerLocation = listLocation - 25;
+                    [newStyle setFirstLineHeadIndent:0];
+                    [newStyle setHeadIndent:listLocation];
+                    while ((count = [[newStyle tabStops] count]) &gt; 0) {
+                        for (i = 0, tabToRemove = nil; !tabToRemove &amp;&amp; i &lt; count; i++) {
+                            tab = [[newStyle tabStops] objectAtIndex:i];
+                            if ([tab location] &lt;= listLocation) tabToRemove = tab;
+                        }
+                        if (tabToRemove) [newStyle removeTabStop:tab]; else break;
+                    }
+                    tab = [[PlatformNSTextTab alloc] initWithType:NSLeftTabStopType location:markerLocation];
+                    [newStyle addTabStop:tab];
+                    [tab release];
+#if PLATFORM(IOS)
+                    tab = [[PlatformNSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural location:listLocation options:nil];
+#else
+                    tab = [[PlatformNSTextTab alloc] initWithTextAlignment:NSNaturalTextAlignment location:listLocation options:nil];
+#endif
+                    [newStyle addTabStop:tab];
+                    [tab release];
+                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting) [_attrStr addAttribute:NSParagraphStyleAttributeName value:newStyle range:paragraphRange];
+                    [newStyle release];
+                    
+                    idx = NSMaxRange(paragraphRange);
+                } else {
+                    // skip any deeper-nested lists
+                    idx = NSMaxRange(styleRange);
+                }
+            }
+        }
+    }
+}
+
+- (void)_exitElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal depth:(NSInteger)depth startIndex:(NSUInteger)startIndex
+{
+    NSRange range = NSMakeRange(startIndex, [_attrStr length] - startIndex);
+    if (range.length &gt; 0 &amp;&amp; [@&quot;A&quot; isEqualToString:tag]) {
+        NSString *urlString = [element getAttribute:@&quot;href&quot;];
+        NSString *strippedString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        if (urlString &amp;&amp; [urlString length] &gt; 0 &amp;&amp; strippedString &amp;&amp; [strippedString length] &gt; 0 &amp;&amp; ![strippedString hasPrefix:@&quot;#&quot;]) {
+            NSURL *url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
+            if (!url)
+                url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(strippedString));
+            if (!url)
+                url = [NSURL _web_URLWithString:strippedString relativeToURL:_baseURL];
+            if (!_flags.isIndexing &amp;&amp; !_flags.isTesting)
+                [_attrStr addAttribute:NSLinkAttributeName value:url ? (id)url : (id)urlString range:range];
+        }
+    }
+    if (!_flags.reachedEnd &amp;&amp; [self _elementIsBlockLevel:element]) {
+        [_writingDirectionArray removeAllObjects];
+        if ([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textBlocks count] == 0) {
+            [self _newTabForElement:element];
+        } else if ([_textLists count] &gt; 0 &amp;&amp; [@&quot;block&quot; isEqualToString:displayVal] &amp;&amp; ![@&quot;LI&quot; isEqualToString:tag] &amp;&amp; ![@&quot;UL&quot; isEqualToString:tag] &amp;&amp; ![@&quot;OL&quot; isEqualToString:tag]) {
+            [self _newLineForElement:element];
+        } else {
+            [self _newParagraphForElement:element tag:tag allowEmpty:(range.length == 0) suppressTrailingSpace:YES];
+        }
+    } else if ([_writingDirectionArray count] &gt; 0) {
+        NSString *bidi = [self _stringForNode:element property:CSSPropertyUnicodeBidi];
+        if (bidi &amp;&amp; ([bidi isEqualToString:@&quot;embed&quot;] || [bidi isEqualToString:@&quot;bidi-override&quot;])) {
+            [_writingDirectionArray removeLastObject];
+        }
+    }
+    range = NSMakeRange(startIndex, [_attrStr length] - startIndex);
+    if ([@&quot;table&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
+        NSValue *key = [NSValue valueWithNonretainedObject:[_textTables lastObject]];
+        DOMNode *footer = [_textTableFooters objectForKey:key];
+        while ([_textTables count] &lt; [_textBlocks count] + 1)
+            [_textBlocks removeLastObject];
+        if (footer) {
+            [self _traverseFooterNode:footer depth:depth + 1];
+            [_textTableFooters removeObjectForKey:key];
+        }
+        [_textTables removeLastObject];
+        [_textTableSpacings removeLastObject];
+        [_textTablePaddings removeLastObject];
+        [_textTableRows removeLastObject];
+        [_textTableRowArrays removeLastObject];
+    } else if ([@&quot;table-row&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
+        NSTextTable *table = [_textTables lastObject];
+        NSTextTableBlock *block;
+        NSMutableArray *rowArray = [_textTableRowArrays lastObject], *previousRowArray;
+        NSUInteger i, count;
+        NSInteger numberOfColumns = [table numberOfColumns];
+        NSInteger openColumn;
+        NSInteger rowNumber = [[_textTableRows lastObject] integerValue];
+        do {
+            rowNumber++;
+            previousRowArray = rowArray;
+            rowArray = [NSMutableArray array];
+            count = [previousRowArray count];
+            for (i = 0; i &lt; count; i++) {
+                block = [previousRowArray objectAtIndex:i];
+                if ([block startingColumn] + [block columnSpan] &gt; numberOfColumns) numberOfColumns = [block startingColumn] + [block columnSpan];
+                if ([block startingRow] + [block rowSpan] &gt; rowNumber) [rowArray addObject:block];
+            }
+            count = [rowArray count];
+            openColumn = 0;
+            for (i = 0; i &lt; count; i++) {
+                block = [rowArray objectAtIndex:i];
+                if (openColumn &gt;= [block startingColumn] &amp;&amp; openColumn &lt; [block startingColumn] + [block columnSpan]) openColumn = [block startingColumn] + [block columnSpan];
+            }
+        } while (openColumn &gt;= numberOfColumns);
+        if ((NSUInteger)numberOfColumns &gt; [table numberOfColumns])
+            [table setNumberOfColumns:numberOfColumns];
+        [_textTableRows removeLastObject];
+        [_textTableRows addObject:[NSNumber numberWithInteger:rowNumber]];
+        [_textTableRowArrays removeLastObject];
+        [_textTableRowArrays addObject:rowArray];
+        if ([_textTableRowBackgroundColors count] &gt; 0)
+            [_textTableRowBackgroundColors removeLastObject];
+    } else if ([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textBlocks count] &gt; 0) {
+        while ([_textTables count] &gt; [_textBlocks count]) {
+            [_textTables removeLastObject];
+            [_textTableSpacings removeLastObject];
+            [_textTablePaddings removeLastObject];
+            [_textTableRows removeLastObject];
+            [_textTableRowArrays removeLastObject];
+        }
+        [_textBlocks removeLastObject];
+    } else if (([@&quot;UL&quot; isEqualToString:tag] || [@&quot;OL&quot; isEqualToString:tag]) &amp;&amp; [_textLists count] &gt; 0) {
+        NSTextList *list = [_textLists lastObject];
+        [self _addMarkersToList:list range:range];
+        [_textLists removeLastObject];
+    } else if ([@&quot;Q&quot; isEqualToString:tag]) {
+        [self _addQuoteForElement:element opening:NO level:--_quoteLevel];
+    } else if ([@&quot;SPAN&quot; isEqualToString:tag]) {
+        NSString *className = [element getAttribute:@&quot;class&quot;];
+        NSMutableString *mutableString;
+        NSUInteger i, count = 0;
+        unichar c;
+        if ([@&quot;Apple-converted-space&quot; isEqualToString:className]) {
+            mutableString = [_attrStr mutableString];
+            for (i = range.location; i &lt; NSMaxRange(range); i++) {
+                c = [mutableString characterAtIndex:i];
+                if (0xa0 == c)
+                    [mutableString replaceCharactersInRange:NSMakeRange(i, 1) withString:@&quot; &quot;];
+            }
+        } else if ([@&quot;Apple-converted-tab&quot; isEqualToString:className]) {
+            mutableString = [_attrStr mutableString];
+            for (i = range.location; i &lt; NSMaxRange(range); i++) {
+                NSRange rangeToReplace = NSMakeRange(NSNotFound, 0);
+                c = [mutableString characterAtIndex:i];
+                if (' ' == c || 0xa0 == c) {
+                    count++;
+                    if (count &gt;= 4 || i + 1 &gt;= NSMaxRange(range))
+                        rangeToReplace = NSMakeRange(i + 1 - count, count);
+                } else {
+                    if (count &gt; 0)
+                        rangeToReplace = NSMakeRange(i - count, count);
+                }
+                if (rangeToReplace.length &gt; 0) {
+                    [mutableString replaceCharactersInRange:rangeToReplace withString:@&quot;\t&quot;];
+                    range.length -= (rangeToReplace.length - 1);
+                    i -= (rangeToReplace.length - 1);
+                    if (NSMaxRange(rangeToReplace) &lt;= _domRangeStartIndex) {
+                        _domRangeStartIndex -= (rangeToReplace.length - 1);
+                    } else if (rangeToReplace.location &lt; _domRangeStartIndex) {
+                        _domRangeStartIndex = rangeToReplace.location;
+                    }
+                    count = 0;
+                }
+            }
+        }
+    }
+}
+
+- (void)_processText:(DOMCharacterData *)text
+{
+    NSString *instr = [text data];
+    NSString *outstr = instr;
+    NSString *whitespaceVal;
+    NSString *transformVal;
+    NSUInteger textLength = [_attrStr length];
+    NSUInteger startOffset = 0;
+    NSUInteger endOffset = [instr length];
+    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
+    BOOL wasSpace = NO;
+    BOOL wasLeading = YES;
+    BOOL suppressLeadingSpace = ((_flags.isSoft &amp;&amp; lastChar == ' ') || lastChar == '\n' || lastChar == '\r' || lastChar == '\t' || lastChar == NSParagraphSeparatorCharacter || lastChar == NSLineSeparatorCharacter || lastChar == NSFormFeedCharacter || lastChar == WebNextLineCharacter);
+    NSRange rangeToReplace = NSMakeRange(textLength, 0);
+    CFMutableStringRef mutstr = NULL;
+    whitespaceVal = [self _stringForNode:text property:CSSPropertyWhiteSpace];
+    transformVal = [self _stringForNode:text property:CSSPropertyTextTransform];
+    
+    if (_domRange) {
+        if (text == [_domRange startContainer]) {
+            startOffset = (NSUInteger)[_domRange startOffset];
+            _domRangeStartIndex = [_attrStr length];
+            _flags.reachedStart = YES;
+        }
+        if (text == [_domRange endContainer]) {
+            endOffset = (NSUInteger)[_domRange endOffset];
+            _flags.reachedEnd = YES;
+        }
+        if ((startOffset &gt; 0 || endOffset &lt; [instr length]) &amp;&amp; endOffset &gt;= startOffset) {
+            instr = [instr substringWithRange:NSMakeRange(startOffset, endOffset - startOffset)];
+            outstr = instr;
+        }
+    }
+    if ([whitespaceVal hasPrefix:@&quot;pre&quot;]) {
+        if (textLength &gt; 0 &amp;&amp; [instr length] &gt; 0 &amp;&amp; _flags.isSoft) {
+            unichar c = [instr characterAtIndex:0];
+            if (c == '\n' || c == '\r' || c == NSParagraphSeparatorCharacter || c == NSLineSeparatorCharacter || c == NSFormFeedCharacter || c == WebNextLineCharacter)
+                rangeToReplace = NSMakeRange(textLength - 1, 1);
+        }
+    } else {
+        CFStringInlineBuffer inlineBuffer;
+        const unsigned int TextBufferSize = 255;
+
+        unichar buffer[TextBufferSize + 1];
+        NSUInteger i, count = [instr length], idx = 0;
+
+        mutstr = CFStringCreateMutable(NULL, 0);
+        CFStringInitInlineBuffer((CFStringRef)instr, &amp;inlineBuffer, CFRangeMake(0, count));
+        for (i = 0; i &lt; count; i++) {
+            unichar c = CFStringGetCharacterFromInlineBuffer(&amp;inlineBuffer, i);
+            if (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == 0xc || c == 0x200b) {
+                wasSpace = (!wasLeading || !suppressLeadingSpace);
+            } else {
+                if (wasSpace)
+                    buffer[idx++] = ' ';
+                buffer[idx++] = c;
+                if (idx &gt;= TextBufferSize) {
+                    CFStringAppendCharacters(mutstr, buffer, idx);
+                    idx = 0;
+                }
+                wasSpace = wasLeading = NO;
+            }
+        }
+        if (wasSpace)
+            buffer[idx++] = ' ';
+        if (idx &gt; 0)
+            CFStringAppendCharacters(mutstr, buffer, idx);
+        outstr = (NSString *)mutstr;
+    }
+    if ([outstr length] &gt; 0) {
+        if ([@&quot;capitalize&quot; isEqualToString:transformVal])
+            outstr = [outstr capitalizedString];
+        else if ([@&quot;uppercase&quot; isEqualToString:transformVal])
+            outstr = [outstr uppercaseString];
+        else if ([@&quot;lowercase&quot; isEqualToString:transformVal])
+            outstr = [outstr lowercaseString];
+        [_attrStr replaceCharactersInRange:rangeToReplace withString:outstr];
+        rangeToReplace.length = [outstr length];
+        if (!_flags.isIndexing) {
+            RetainPtr&lt;NSDictionary&gt; attrs;
+            DOMElement *element = (DOMElement *)text;
+            while (element) {
+                // Fill attrs dictionary with attributes from parent nodes, not overwriting ones deeper in the tree
+                if([element nodeType] == DOM_ELEMENT_NODE) {
+                    RetainPtr&lt;NSMutableDictionary&gt; newAttrs = adoptNS([[self _attributesForElement:element] mutableCopy]);
+                    if (attrs) {
+                        // Already-set attributes (from lower in the tree) overwrite the higher ones.
+                        [newAttrs addEntriesFromDictionary:attrs.get()];
+                    }
+                    attrs = newAttrs;
+                }
+                element = (DOMElement *)[element parentNode];
+            }
+            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
+                [_attrStr setAttributes:attrs.get() range:rangeToReplace];
+        }
+        _flags.isSoft = wasSpace;
+    }
+    if (mutstr)
+        CFRelease(mutstr);
+}
+
+- (void)_traverseNode:(DOMNode *)node depth:(NSInteger)depth embedded:(BOOL)embedded
+{
+    unsigned short nodeType;
+    NSArray *childNodes;
+    NSUInteger count;
+    NSUInteger startOffset;
+    NSUInteger endOffset;
+    BOOL isStart = NO;
+    BOOL isEnd = NO;
+
+    if (_flags.reachedEnd)
+        return;
+    if (_domRange &amp;&amp; !_flags.reachedStart &amp;&amp; _domStartAncestors &amp;&amp; ![_domStartAncestors containsObject:node])
+        return;
+    
+    nodeType = [node nodeType];
+    childNodes = [self _childrenForNode:node];
+    count = [childNodes count];
+    startOffset = 0;
+    endOffset = count;
+
+    if (_domRange) {
+        if (node == [_domRange startContainer]) {
+            startOffset = (NSUInteger)[_domRange startOffset];
+            isStart = YES;
+            _flags.reachedStart = YES;
+        }
+        if (node == [_domRange endContainer]) {
+            endOffset = (NSUInteger)[_domRange endOffset];
+            isEnd = YES;
+        }
+    }
+    
+    if (nodeType == DOM_DOCUMENT_NODE || nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+        for (NSUInteger i = 0; i &lt; count; i++) {
+            if (isStart &amp;&amp; i == startOffset)
+                _domRangeStartIndex = [_attrStr length];
+            if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
+                [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:embedded];
+            if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
+                _flags.reachedEnd = YES;
+            if (_thumbnailLimit &gt; 0 &amp;&amp; [_attrStr length] &gt;= _thumbnailLimit)
+                _flags.reachedEnd = YES;
+            if (_flags.reachedEnd) break;
+        }
+    } else if (nodeType == DOM_ELEMENT_NODE) {
+        DOMElement *element = (DOMElement *)node;
+        NSString *tag = [element tagName], *displayVal = [self _stringForNode:element property:CSSPropertyDisplay];
+        if ([self _enterElement:element tag:tag display:displayVal embedded:embedded]) {
+            NSUInteger startIndex = [_attrStr length];
+            if ([self _processElement:element tag:tag display:displayVal depth:depth]) {
+                for (NSUInteger i = 0; i &lt; count; i++) {
+                    if (isStart &amp;&amp; i == startOffset)
+                        _domRangeStartIndex = [_attrStr length];
+                    if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
+                        [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:embedded];
+                    if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
+                        _flags.reachedEnd = YES;
+                    if (_flags.reachedEnd)
+                        break;
+                }
+                [self _exitElement:element tag:tag display:displayVal depth:depth startIndex:startIndex];
+            }
+        }
+    } else if (nodeType == DOM_TEXT_NODE || nodeType == DOM_CDATA_SECTION_NODE) {
+        [self _processText:(DOMCharacterData *)node];
+    }
+    
+    if (isEnd) _flags.reachedEnd = YES;
+}
+
+- (void)_traverseFooterNode:(DOMNode *)node depth:(NSInteger)depth
+{
+    DOMElement *element = (DOMElement *)node;
+    NSArray *childNodes = [self _childrenForNode:node];
+    NSString *tag = @&quot;TBODY&quot;, *displayVal = @&quot;table-row-group&quot;;
+    NSUInteger count = [childNodes count];
+    NSUInteger startOffset = 0;
+    NSUInteger endOffset = count;
+    BOOL isStart = NO;
+    BOOL isEnd = NO;
+
+    if (_flags.reachedEnd)
+        return;
+    if (_domRange &amp;&amp; !_flags.reachedStart &amp;&amp; _domStartAncestors &amp;&amp; ![_domStartAncestors containsObject:node])
+        return;
+    if (_domRange) {
+        if (node == [_domRange startContainer]) {
+            startOffset = (NSUInteger)[_domRange startOffset];
+            isStart = YES;
+            _flags.reachedStart = YES;
+        }
+        if (node == [_domRange endContainer]) {
+            endOffset = (NSUInteger)[_domRange endOffset];
+            isEnd = YES;
+        }
+    }
+    if ([self _enterElement:element tag:tag display:displayVal embedded:YES]) {
+        NSUInteger startIndex = [_attrStr length];
+        if ([self _processElement:element tag:tag display:displayVal depth:depth]) {
+            for (NSUInteger i = 0; i &lt; count; i++) {
+                if (isStart &amp;&amp; i == startOffset)
+                    _domRangeStartIndex = [_attrStr length];
+                if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
+                    [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:YES];
+                if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
+                    _flags.reachedEnd = YES;
+                if (_flags.reachedEnd)
+                    break;
+            }
+            [self _exitElement:element tag:tag display:displayVal depth:depth startIndex:startIndex];
+        }
+    }
+    if (isEnd)
+        _flags.reachedEnd = YES;
+}
+
+- (void)_adjustTrailingNewline
+{
+    NSUInteger textLength = [_attrStr length];
+    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : 0;
+    BOOL alreadyHasTrailingNewline = (lastChar == '\n' || lastChar == '\r' || lastChar == NSParagraphSeparatorCharacter || lastChar == NSLineSeparatorCharacter || lastChar == WebNextLineCharacter);
+    if (_flags.hasTrailingNewline &amp;&amp; !alreadyHasTrailingNewline)
+        [_attrStr replaceCharactersInRange:NSMakeRange(textLength, 0) withString:@&quot;\n&quot;];
+}
+
+- (void)_loadFromDOMRange
+{
+    if (-1 == _errorCode) {
+        DOMNode *commonAncestorContainer = [_domRange commonAncestorContainer];
+        DOMNode *ancestorContainer = [_domRange startContainer];
+        
+        _domStartAncestors = [[NSMutableArray alloc] init];
+        while (ancestorContainer) {
+            [_domStartAncestors addObject:ancestorContainer];
+            if (ancestorContainer == commonAncestorContainer)
+                break;
+            ancestorContainer = [ancestorContainer parentNode];
+        }
+        _document = [commonAncestorContainer ownerDocument];
+        _dataSource = (DocumentLoader *)core(_document)-&gt;frame()-&gt;loader().documentLoader();
+        if (_textSizeMultiplier &lt;= 0.0)
+            _textSizeMultiplier = 1;
+        if (_defaultFontSize &lt;= 0.0)
+            _defaultFontSize = 12;
+        if (_minimumFontSize &lt; 1.0)
+            _minimumFontSize = 1;
+        if (_document &amp;&amp; _dataSource) {
+            _domRangeStartIndex = 0;
+            _errorCode = 0;
+            [self _traverseNode:commonAncestorContainer depth:0 embedded:NO];
+            if (_domRangeStartIndex &gt; 0 &amp;&amp; _domRangeStartIndex &lt;= [_attrStr length])
+                [_attrStr deleteCharactersInRange:NSMakeRange(0, _domRangeStartIndex)];
+        }
+    }
+}
+
+- (void)dealloc
+{
+    [_attrStr release];
+    [_documentAttrs release];
+    [_domRange release];
+    [_domStartAncestors release];
+    [_standardFontFamily release];
+    [_textLists release];
+    [_textBlocks release];
+    [_textTables release];
+    [_textTableFooters release];
+    [_textTableSpacings release];
+    [_textTablePaddings release];
+    [_textTableRows release];
+    [_textTableRowArrays release];
+    [_textTableRowBackgroundColors release];
+    [_attributesForElements release];
+    [_fontCache release];
+    [_writingDirectionArray release];
+    [super dealloc];
+}
+
+- (id)init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    
+    _attrStr = [[NSMutableAttributedString alloc] init];
+    _documentAttrs = [[NSMutableDictionary alloc] init];
+
+    _textLists = [[NSMutableArray alloc] init];
+    _textBlocks = [[NSMutableArray alloc] init];
+    _textTables = [[NSMutableArray alloc] init];
+    _textTableFooters = [[NSMutableDictionary alloc] init];
+    _textTableSpacings = [[NSMutableArray alloc] init];
+    _textTablePaddings = [[NSMutableArray alloc] init];
+    _textTableRows = [[NSMutableArray alloc] init];
+    _textTableRowArrays = [[NSMutableArray alloc] init];
+    _textTableRowBackgroundColors = [[NSMutableArray alloc] init];
+    _attributesForElements = [[NSMutableDictionary alloc] init];
+    _fontCache = [[NSMutableDictionary alloc] init];
+    _writingDirectionArray = [[NSMutableArray alloc] init];
+
+    _textSizeMultiplier = 1;
+    _webViewTextSizeMultiplier = 0;
+    _defaultTabInterval = 36;
+    _defaultFontSize = 12;
+    _minimumFontSize = 1;
+    _errorCode = -1;
+    _indexingLimit = 0;
+    _thumbnailLimit = 0;
+    
+    _caches = std::make_unique&lt;HTMLConverterCaches&gt;();
+
+    _flags.isIndexing = (_indexingLimit &gt; 0);
+    _flags.isTesting = 0;
+    
+    return self;
+}
+
+- (id)initWithDOMRange:(DOMRange *)domRange
+{
+    self = [self init];
+    if (!self)
+        return nil;
+    _domRange = [domRange retain];
+    return self;
+}
+
+- (NSAttributedString *)attributedString
+{
+    [self _loadFromDOMRange];
+    return (!_errorCode) ? [[_attrStr retain] autorelease] : nil;
+}
+
+
+// This function supports more HTML features than the editing variant below, such as tables.
++ (NSAttributedString *)attributedStringFromRange:(Range*)range
+{
+    RetainPtr&lt;WebHTMLConverter&gt; converter = adoptNS([[WebHTMLConverter alloc] initWithDOMRange:kit(range)]);
+    return [converter attributedString];
+}
+
+#if !PLATFORM(IOS)
+
+// This function uses TextIterator, which makes offsets in its result compatible with HTML editing.
++ (NSAttributedString *)editingAttributedStringFromRange:(Range*)range
+{
+    NSFontManager *fontManager = [NSFontManager sharedFontManager];
+    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
+    NSUInteger stringLength = 0;
+    RetainPtr&lt;NSMutableDictionary&gt; attrs = adoptNS([[NSMutableDictionary alloc] init]);
+
+    for (TextIterator it(range); !it.atEnd(); it.advance()) {
+        RefPtr&lt;Range&gt; currentTextRange = it.range();
+        Node* startContainer = currentTextRange-&gt;startContainer();
+        Node* endContainer = currentTextRange-&gt;endContainer();
+        int startOffset = currentTextRange-&gt;startOffset();
+        int endOffset = currentTextRange-&gt;endOffset();
+        
+        if (startContainer == endContainer &amp;&amp; (startOffset == endOffset - 1)) {
+            Node* node = startContainer-&gt;childNode(startOffset);
+            if (node &amp;&amp; node-&gt;hasTagName(imgTag)) {
+                NSFileWrapper* fileWrapper = fileWrapperForElement(toElement(node));
+                NSTextAttachment* attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
+                [string appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
+                [attachment release];
+            }
+        }
+
+        int currentTextLength = it.text().length();
+        if (!currentTextLength)
+            continue;
+
+        RenderObject* renderer = startContainer-&gt;renderer();
+        ASSERT(renderer);
+        if (!renderer)
+            continue;
+        const RenderStyle&amp; style = renderer-&gt;style();
+        if (style.textDecorationsInEffect() &amp; TextDecorationUnderline)
+            [attrs.get() setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
+        if (style.textDecorationsInEffect() &amp; TextDecorationLineThrough)
+            [attrs.get() setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
+        if (NSFont *font = style.font().primaryFont()-&gt;getNSFont())
+            [attrs.get() setObject:font forKey:NSFontAttributeName];
+        else
+            [attrs.get() setObject:[fontManager convertFont:WebDefaultFont() toSize:style.font().primaryFont()-&gt;platformData().size()] forKey:NSFontAttributeName];
+        if (style.visitedDependentColor(CSSPropertyColor).alpha())
+            [attrs.get() setObject:nsColor(style.visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
+        else
+            [attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
+        if (style.visitedDependentColor(CSSPropertyBackgroundColor).alpha())
+            [attrs.get() setObject:nsColor(style.visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
+        else
+            [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
+
+        [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:it.text().createNSStringWithoutCopying().get()];
+        [string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)];
+        stringLength += currentTextLength;
+    }
+
+    return [string autorelease];
+}
+
+#endif
+
+@end
+
+#if !PLATFORM(IOS)
+
+static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
+{
+    if ([URL isFileURL])
+        return [[[NSFileWrapper alloc] initWithURL:[URL URLByResolvingSymlinksInPath] options:0 error:nullptr] autorelease];
+
+    RefPtr&lt;ArchiveResource&gt; resource = dataSource-&gt;subresource(URL);
+    if (resource) {
+        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:resource-&gt;data()-&gt;createNSData().get()] autorelease];
+        NSString *filename = resource-&gt;response().suggestedFilename();
+        if (!filename || ![filename length])
+            filename = suggestedFilenameWithMIMEType(resource-&gt;url(), resource-&gt;mimeType());
+        [wrapper setPreferredFilename:filename];
+        return wrapper;
+    }
+    
+    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
+
+    NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
+    [request release];
+    
+    if (cachedResponse) {
+        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
+        [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
+        return wrapper;
+    }
+    
+    return nil;
+}
+
+static NSFileWrapper *fileWrapperForElement(Element* element)
+{
+    NSFileWrapper *wrapper = nil;
+    
+    const AtomicString&amp; attr = element-&gt;getAttribute(srcAttr);
+    if (!attr.isEmpty()) {
+        NSURL *URL = element-&gt;document().completeURL(attr);
+        if (DocumentLoader* loader = element-&gt;document().loader())
+            wrapper = fileWrapperForURL(loader, URL);
+    }
+    if (!wrapper) {
+        RenderImage* renderer = toRenderImage(element-&gt;renderer());
+        if (renderer-&gt;cachedImage() &amp;&amp; !renderer-&gt;cachedImage()-&gt;errorOccurred()) {
+            wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:(NSData *)(renderer-&gt;cachedImage()-&gt;imageForRenderer(renderer)-&gt;getTIFFRepresentation())];
+            [wrapper setPreferredFilename:@&quot;image.tiff&quot;];
+            [wrapper autorelease];
+        }
+    }
+
+    return wrapper;
+}
+
+#endif
+
+namespace WebCore {
+    
+NSAttributedString *attributedStringFromRange(Range&amp; range)
+{
+    return [WebHTMLConverter attributedStringFromRange:&amp;range];
+}
+    
+#if !PLATFORM(IOS)
+NSAttributedString *editingAttributedStringFromRange(Range&amp; range)
+{
+    return [WebHTMLConverter editingAttributedStringFromRange:&amp;range];
+}
+#endif
+    
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHTMLConverterh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/mac/HTMLConverter.h (166146 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HTMLConverter.h        2014-03-23 21:47:52 UTC (rev 166146)
+++ trunk/Source/WebCore/platform/mac/HTMLConverter.h        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -1,42 +0,0 @@
</span><del>-/*
- * Copyright (C) 2010-2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLConverter_h
-#define HTMLConverter_h
-
-OBJC_CLASS NSAttributedString;
-
-namespace WebCore {
-    
-class Range;
-    
-NSAttributedString *attributedStringFromRange(Range&amp;);
-#if !PLATFORM(IOS)
-NSAttributedString *editingAttributedStringFromRange(Range&amp;);
-#endif
-
-}
-
-#endif // HTMLConverter_h
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHTMLConvertermm"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/mac/HTMLConverter.mm (166146 => 166147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HTMLConverter.mm        2014-03-23 21:47:52 UTC (rev 166146)
+++ trunk/Source/WebCore/platform/mac/HTMLConverter.mm        2014-03-23 22:14:20 UTC (rev 166147)
</span><span class="lines">@@ -1,2648 +0,0 @@
</span><del>-/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import &quot;config.h&quot;
-#import &quot;HTMLConverter.h&quot;
-
-#import &quot;ArchiveResource.h&quot;
-#import &quot;CachedImage.h&quot;
-#import &quot;ColorMac.h&quot;
-#import &quot;CSSComputedStyleDeclaration.h&quot;
-#import &quot;CSSParser.h&quot;
-#import &quot;CSSPrimitiveValue.h&quot;
-#import &quot;Document.h&quot;
-#import &quot;DocumentLoader.h&quot;
-#import &quot;DOMCSSPrimitiveValueInternal.h&quot;
-#import &quot;DOMDocumentInternal.h&quot;
-#import &quot;DOMElementInternal.h&quot;
-#import &quot;DOMHTMLTableCellElement.h&quot;
-#import &quot;DOMNodeInternal.h&quot;
-#import &quot;DOMPrivate.h&quot;
-#import &quot;DOMRGBColorInternal.h&quot;
-#import &quot;DOMRangeInternal.h&quot;
-#import &quot;Element.h&quot;
-#import &quot;Font.h&quot;
-#import &quot;Frame.h&quot;
-#import &quot;FrameLoader.h&quot;
-#import &quot;HTMLElement.h&quot;
-#import &quot;HTMLNames.h&quot;
-#import &quot;HTMLParserIdioms.h&quot;
-#import &quot;LoaderNSURLExtras.h&quot;
-#import &quot;RGBColor.h&quot;
-#import &quot;RenderImage.h&quot;
-#import &quot;SoftLinking.h&quot;
-#import &quot;StyleProperties.h&quot;
-#import &quot;StyledElement.h&quot;
-#import &quot;TextIterator.h&quot;
-#import &lt;objc/runtime.h&gt;
-#import &lt;wtf/ASCIICType.h&gt;
-
-#if PLATFORM(IOS)
-
-SOFT_LINK_FRAMEWORK(UIKit)
-SOFT_LINK_CLASS(UIKit, UIColor)
-
-SOFT_LINK_PRIVATE_FRAMEWORK(UIFoundation)
-SOFT_LINK_CLASS(UIFoundation, UIFont)
-SOFT_LINK_CLASS(UIFoundation, NSColor)
-SOFT_LINK_CLASS(UIFoundation, NSShadow)
-SOFT_LINK_CLASS(UIFoundation, NSTextAttachment)
-SOFT_LINK_CLASS(UIFoundation, NSMutableParagraphStyle)
-SOFT_LINK_CLASS(UIFoundation, NSParagraphStyle)
-SOFT_LINK_CLASS(UIFoundation, NSTextList)
-SOFT_LINK_CLASS(UIFoundation, NSTextBlock)
-SOFT_LINK_CLASS(UIFoundation, NSTextTableBlock)
-SOFT_LINK_CLASS(UIFoundation, NSTextTable)
-SOFT_LINK_CLASS(UIFoundation, NSTextTab)
-
-SOFT_LINK_CONSTANT(UIFoundation, NSFontAttributeName, NSString *)
-#define NSFontAttributeName getNSFontAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSForegroundColorAttributeName, NSString *)
-#define NSForegroundColorAttributeName getNSForegroundColorAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSBackgroundColorAttributeName, NSString *)
-#define NSBackgroundColorAttributeName getNSBackgroundColorAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSStrokeColorAttributeName, NSString *)
-#define NSStrokeColorAttributeName getNSStrokeColorAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSStrokeWidthAttributeName, NSString *)
-#define NSStrokeWidthAttributeName getNSStrokeWidthAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSShadowAttributeName, NSString *)
-#define NSShadowAttributeName getNSShadowAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSKernAttributeName, NSString *)
-#define NSKernAttributeName getNSKernAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSLigatureAttributeName, NSString *)
-#define NSLigatureAttributeName getNSLigatureAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSUnderlineStyleAttributeName, NSString *)
-#define NSUnderlineStyleAttributeName getNSUnderlineStyleAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSStrikethroughStyleAttributeName, NSString *)
-#define NSStrikethroughStyleAttributeName getNSStrikethroughStyleAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSBaselineOffsetAttributeName, NSString *)
-#define NSBaselineOffsetAttributeName getNSBaselineOffsetAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSWritingDirectionAttributeName, NSString *)
-#define NSWritingDirectionAttributeName getNSWritingDirectionAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSParagraphStyleAttributeName, NSString *)
-#define NSParagraphStyleAttributeName getNSParagraphStyleAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSAttachmentAttributeName, NSString *)
-#define NSAttachmentAttributeName getNSAttachmentAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSLinkAttributeName, NSString *)
-#define NSLinkAttributeName getNSLinkAttributeName()
-SOFT_LINK_CONSTANT(UIFoundation, NSAuthorDocumentAttribute, NSString *)
-#define NSAuthorDocumentAttribute getNSAuthorDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSEditorDocumentAttribute, NSString *)
-#define NSEditorDocumentAttribute getNSEditorDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSGeneratorDocumentAttribute, NSString *)
-#define NSGeneratorDocumentAttribute getNSGeneratorDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSCompanyDocumentAttribute, NSString *)
-#define NSCompanyDocumentAttribute getNSCompanyDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSDisplayNameDocumentAttribute, NSString *)
-#define NSDisplayNameDocumentAttribute getNSDisplayNameDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSCopyrightDocumentAttribute, NSString *)
-#define NSCopyrightDocumentAttribute getNSCopyrightDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSSubjectDocumentAttribute, NSString *)
-#define NSSubjectDocumentAttribute getNSSubjectDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSCommentDocumentAttribute, NSString *)
-#define NSCommentDocumentAttribute getNSCommentDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSNoIndexDocumentAttribute, NSString *)
-#define NSNoIndexDocumentAttribute getNSNoIndexDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSKeywordsDocumentAttribute, NSString *)
-#define NSKeywordsDocumentAttribute getNSKeywordsDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSCreationTimeDocumentAttribute, NSString *)
-#define NSCreationTimeDocumentAttribute getNSCreationTimeDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSModificationTimeDocumentAttribute, NSString *)
-#define NSModificationTimeDocumentAttribute getNSModificationTimeDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSConvertedDocumentAttribute, NSString *)
-#define NSConvertedDocumentAttribute getNSConvertedDocumentAttribute()
-SOFT_LINK_CONSTANT(UIFoundation, NSCocoaVersionDocumentAttribute, NSString *)
-#define NSCocoaVersionDocumentAttribute getNSCocoaVersionDocumentAttribute()
-
-#define PlatformNSShadow            getNSShadowClass()
-#define PlatformNSTextAttachment    getNSTextAttachmentClass()
-#define PlatformNSParagraphStyle    getNSParagraphStyleClass()
-#define PlatformNSTextList          getNSTextListClass()
-#define PlatformNSTextTableBlock    getNSTextTableBlockClass()
-#define PlatformNSTextTable         getNSTextTableClass()
-#define PlatformNSTextTab           getNSTextTabClass()
-#define PlatformColor               UIColor
-#define PlatformColorClass          getUIColorClass()
-#define PlatformNSColorClass        getNSColorClass()
-#define PlatformFont                UIFont
-#define PlatformFontClass           getUIFontClass()
-
-// We don't softlink NSSuperscriptAttributeName because UIFoundation stopped exporting it.
-// This attribute is being deprecated at the API level, but internally UIFoundation
-// will continue to support it.
-static NSString *const NSSuperscriptAttributeName = @&quot;NSSuperscript&quot;;
-#else
-
-#define PlatformNSShadow            NSShadow
-#define PlatformNSTextAttachment    NSTextAttachment
-#define PlatformNSParagraphStyle    NSParagraphStyle
-#define PlatformNSTextList          NSTextList
-#define PlatformNSTextTableBlock    NSTextTableBlock
-#define PlatformNSTextTable         NSTextTable
-#define PlatformNSTextTab           NSTextTab
-#define PlatformColor               NSColor
-#define PlatformColorClass          NSColor
-#define PlatformNSColorClass        NSColor
-#define PlatformFont                NSFont
-#define PlatformFontClass           NSFont
-
-#define NSTextAlignmentLeft         NSLeftTextAlignment
-#define NSTextAlignmentRight        NSRightTextAlignment
-#define NSTextAlignmentCenter       NSCenterTextAlignment
-#define NSTextAlignmentJustified    NSJustifiedTextAlignment
-#endif
-
-using namespace WebCore;
-using namespace HTMLNames;
-
-#if PLATFORM(IOS)
-
-typedef enum {
-    UIFontTraitPlain       = 0x00000000,
-    UIFontTraitItalic      = 0x00000001, // 1 &lt;&lt; 0
-    UIFontTraitBold        = 0x00000002, // 1 &lt;&lt; 1
-    UIFontTraitThin        = (1 &lt;&lt; 2),
-    UIFontTraitLight       = (1 &lt;&lt; 3),
-    UIFontTraitUltraLight  = (1 &lt;&lt; 4)
-} UIFontTrait;
-
-typedef NS_ENUM(NSInteger, NSUnderlineStyle) {
-    NSUnderlineStyleNone                                = 0x00,
-    NSUnderlineStyleSingle                              = 0x01,
-    NSUnderlineStyleThick NS_ENUM_AVAILABLE_IOS(7_0)    = 0x02,
-    NSUnderlineStyleDouble NS_ENUM_AVAILABLE_IOS(7_0)   = 0x09,
-
-    NSUnderlinePatternSolid NS_ENUM_AVAILABLE_IOS(7_0)      = 0x0000,
-    NSUnderlinePatternDot NS_ENUM_AVAILABLE_IOS(7_0)        = 0x0100,
-    NSUnderlinePatternDash NS_ENUM_AVAILABLE_IOS(7_0)       = 0x0200,
-    NSUnderlinePatternDashDot NS_ENUM_AVAILABLE_IOS(7_0)    = 0x0300,
-    NSUnderlinePatternDashDotDot NS_ENUM_AVAILABLE_IOS(7_0) = 0x0400,
-
-    NSUnderlineByWord NS_ENUM_AVAILABLE_IOS(7_0) = 0x8000
-};
-
-enum {
-    NSTextBlockAbsoluteValueType    = 0,    // Absolute value in points
-    NSTextBlockPercentageValueType  = 1     // Percentage value (out of 100)
-};
-typedef NSUInteger NSTextBlockValueType;
-
-enum {
-    NSTextBlockWidth            = 0,
-    NSTextBlockMinimumWidth     = 1,
-    NSTextBlockMaximumWidth     = 2,
-    NSTextBlockHeight           = 4,
-    NSTextBlockMinimumHeight    = 5,
-    NSTextBlockMaximumHeight    = 6
-};
-typedef NSUInteger NSTextBlockDimension;
-
-enum {
-    NSTextBlockPadding  = -1,
-    NSTextBlockBorder   =  0,
-    NSTextBlockMargin   =  1
-};
-typedef NSInteger NSTextBlockLayer;
-
-enum {
-    NSTextTableAutomaticLayoutAlgorithm = 0,
-    NSTextTableFixedLayoutAlgorithm     = 1
-};
-typedef NSUInteger NSTextTableLayoutAlgorithm;
-
-enum {
-    NSTextBlockTopAlignment         = 0,
-    NSTextBlockMiddleAlignment      = 1,
-    NSTextBlockBottomAlignment      = 2,
-    NSTextBlockBaselineAlignment    = 3
-};
-typedef NSUInteger NSTextBlockVerticalAlignment;
-
-typedef NS_ENUM(NSInteger, NSTextAlignment) {
-    NSTextAlignmentLeft      = 0,    // Visually left aligned
-    NSTextAlignmentCenter    = 1,    // Visually centered
-    NSTextAlignmentRight     = 2,    // Visually right aligned
-    NSTextAlignmentJustified = 3,    // Fully-justified. The last line in a paragraph is natural-aligned.
-    NSTextAlignmentNatural   = 4,    // Indicates the default alignment for script
-} NS_ENUM_AVAILABLE_IOS(6_0);
-
-typedef NS_ENUM(NSInteger, NSWritingDirection) {
-    NSWritingDirectionNatural       = -1,    // Determines direction using the Unicode Bidi Algorithm rules P2 and P3
-    NSWritingDirectionLeftToRight   =  0,    // Left to right writing direction
-    NSWritingDirectionRightToLeft   =  1     // Right to left writing direction
-} NS_ENUM_AVAILABLE_IOS(6_0);
-
-typedef NS_ENUM(NSInteger, NSTextWritingDirection) {
-    NSTextWritingDirectionEmbedding     = (0 &lt;&lt; 1),
-    NSTextWritingDirectionOverride      = (1 &lt;&lt; 1)
-} NS_ENUM_AVAILABLE_IOS(7_0);
-
-enum {
-    NSEnterCharacter                = 0x0003,
-    NSBackspaceCharacter            = 0x0008,
-    NSTabCharacter                  = 0x0009,
-    NSNewlineCharacter              = 0x000a,
-    NSFormFeedCharacter             = 0x000c,
-    NSCarriageReturnCharacter       = 0x000d,
-    NSBackTabCharacter              = 0x0019,
-    NSDeleteCharacter               = 0x007f,
-    NSLineSeparatorCharacter        = 0x2028,
-    NSParagraphSeparatorCharacter   = 0x2029,
-    NSAttachmentCharacter           = 0xFFFC // Replacement character is used for attachments
-};
-
-enum {
-    NSLeftTabStopType = 0,
-    NSRightTabStopType,
-    NSCenterTabStopType,
-    NSDecimalTabStopType
-};
-typedef NSUInteger NSTextTabType;
-
-@interface UIColor : NSObject
-+ (UIColor *)clearColor;
-- (CGFloat)alphaComponent;
-+ (UIColor *)_disambiguated_due_to_CIImage_colorWithCGColor:(CGColorRef)cgColor;
-@end
-
-@interface NSColor : UIColor
-+ (id)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
-@end
-
-@interface UIFont
-+ (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;
-+ (UIFont *)fontWithFamilyName:(NSString *)familyName traits:(UIFontTrait)traits size:(CGFloat)fontSize;
-- (NSString *)familyName;
-- (CGFloat)pointSize;
-- (UIFont *)fontWithSize:(CGFloat)fontSize;
-+ (NSArray *)familyNames;
-+ (NSArray *)fontNamesForFamilyName:(NSString *)familyName;
-+ (UIFont *)systemFontOfSize:(CGFloat)fontSize;
-@end
-
-@interface NSTextTab
-- (id)initWithType:(NSTextTabType)type location:(CGFloat)loc;
-- (id)initWithTextAlignment:(NSTextAlignment)alignment location:(CGFloat)loc options:(NSDictionary *)options;
-- (CGFloat)location;
-- (void)release;
-@end
-
-@interface NSParagraphStyle : NSObject
-+ (NSParagraphStyle *)defaultParagraphStyle;
-- (void)setAlignment:(NSTextAlignment)alignment;
-- (void)setBaseWritingDirection:(NSWritingDirection)writingDirection;
-- (void)setHeadIndent:(CGFloat)aFloat;
-- (CGFloat)headIndent;
-- (void)setHeaderLevel:(NSInteger)level;
-- (void)setFirstLineHeadIndent:(CGFloat)aFloat;
-- (void)setTailIndent:(CGFloat)aFloat;
-- (void)setParagraphSpacing:(CGFloat)paragraphSpacing;
-- (void)setTextLists:(NSArray *)array;
-- (void)setTextBlocks:(NSArray *)array;
-- (void)setMinimumLineHeight:(CGFloat)aFloat;
-- (NSArray *)textLists;
-- (void)removeTabStop:(NSTextTab *)anObject;
-- (void)addTabStop:(NSTextTab *)anObject;
-- (NSArray *)tabStops;
-- (void)setHyphenationFactor:(float)aFactor;
-@end
-
-@interface NSShadow
-- (void)setShadowOffset:(CGSize)size;
-- (void)setShadowBlurRadius:(CGFloat)radius;
-- (void)setShadowColor:(UIColor *)color;
-@end
-
-@interface NSTextBlock : NSObject
-- (void)setValue:(CGFloat)val type:(NSTextBlockValueType)type forDimension:(NSTextBlockDimension)dimension;
-- (void)setWidth:(CGFloat)val type:(NSTextBlockValueType)type forLayer:(NSTextBlockLayer)layer edge:(NSRectEdge)edge;
-- (void)setBackgroundColor:(UIColor *)color;
-- (UIColor *)backgroundColor;
-- (void)setBorderColor:(UIColor *)color forEdge:(NSRectEdge)edge;
-- (void)setBorderColor:(UIColor *)color;        // Convenience method sets all edges at once
-- (void)setVerticalAlignment:(NSTextBlockVerticalAlignment)alignment;
-@end
-
-@interface NSTextList
-- (id)initWithMarkerFormat:(NSString *)format options:(NSUInteger)mask;
-- (void)setStartingItemNumber:(NSInteger)itemNum;
-- (NSInteger)startingItemNumber;
-- (NSString *)markerForItemNumber:(NSInteger)itemNum;
-- (void)release;
-@end
-
-@interface NSMutableParagraphStyle : NSParagraphStyle
-- (void)setDefaultTabInterval:(CGFloat)aFloat;
-- (void)setTabStops:(NSArray *)array;
-@end
-
-@interface NSTextAttachment : NSObject
-- (id)initWithFileWrapper:(NSFileWrapper *)fileWrapper;
-#if PLATFORM(IOS)
-- (void)setBounds:(CGRect)bounds;
-#endif
-- (void)release;
-@end
-
-@interface NSTextTable : NSTextBlock
-- (void)setNumberOfColumns:(NSUInteger)numCols;
-- (void)setCollapsesBorders:(BOOL)flag;
-- (void)setHidesEmptyCells:(BOOL)flag;
-- (void)setLayoutAlgorithm:(NSTextTableLayoutAlgorithm)algorithm;
-- (NSUInteger)numberOfColumns;
-- (void)release;
-@end
-
-@interface NSTextTableBlock : NSTextBlock
-- (id)initWithTable:(NSTextTable *)table startingRow:(NSInteger)row rowSpan:(NSInteger)rowSpan startingColumn:(NSInteger)col columnSpan:(NSInteger)colSpan;     // Designated initializer
-- (NSInteger)startingColumn;
-- (NSInteger)startingRow;
-- (NSUInteger)numberOfColumns;
-- (NSInteger)columnSpan;
-- (NSInteger)rowSpan;
-@end
-
-#else
-static NSFileWrapper *fileWrapperForURL(DocumentLoader *, NSURL *);
-static NSFileWrapper *fileWrapperForElement(Element*);
-
-@interface NSTextAttachment (WebCoreNSTextAttachment)
-- (void)setIgnoresOrientation:(BOOL)flag;
-- (void)setBounds:(CGRect)bounds;
-- (BOOL)ignoresOrientation;
-@end
-
-#endif
-
-// Additional control Unicode characters
-const unichar WebNextLineCharacter = 0x0085;
-
-class HTMLConverterCaches {
-public:
-    String propertyValueForNode(Node&amp;, CSSPropertyID );
-    bool floatPropertyValueForNode(Node&amp;, CSSPropertyID, float&amp;);
-    Color colorPropertyValueForNode(Node&amp;, CSSPropertyID);
-
-    bool isBlockElement(Element&amp;);
-    bool elementHasOwnBackgroundColor(Element&amp;);
-
-    PassRefPtr&lt;CSSValue&gt; computedStylePropertyForElement(Element&amp;, CSSPropertyID);
-    PassRefPtr&lt;CSSValue&gt; inlineStylePropertyForElement(Element&amp;, CSSPropertyID);
-
-private:
-    HashMap&lt;Element*, std::unique_ptr&lt;ComputedStyleExtractor&gt;&gt; m_computedStyles;
-};
-
-@interface NSTextList (WebCoreNSTextListDetails)
-+ (NSDictionary *)_standardMarkerAttributesForAttributes:(NSDictionary *)attrs;
-@end
-
-@interface NSURL (WebCoreNSURLDetails)
-// FIXME: What is the reason to use this Foundation method, and not +[NSURL URLWithString:relativeToURL:]?
-+ (NSURL *)_web_URLWithString:(NSString *)string relativeToURL:(NSURL *)baseURL;
-@end
-
-@interface NSObject(WebMessageDocumentSimulation)
-+ (void)document:(NSObject **)outDocument attachment:(NSTextAttachment **)outAttachment forURL:(NSURL *)url;
-@end
-
-@interface WebHTMLConverter : NSObject {
-    NSMutableAttributedString *_attrStr;
-    NSMutableDictionary *_documentAttrs;
-    NSURL *_baseURL;
-    DOMDocument *_document;
-    DOMRange *_domRange;
-    NSMutableArray *_domStartAncestors;
-    WebCore::DocumentLoader *_dataSource;
-    NSString *_standardFontFamily;
-    CGFloat _textSizeMultiplier;
-    CGFloat _webViewTextSizeMultiplier;
-    CGFloat _defaultTabInterval;
-    CGFloat _defaultFontSize;
-    CGFloat _minimumFontSize;
-    NSMutableArray *_textLists;
-    NSMutableArray *_textBlocks;
-    NSMutableArray *_textTables;
-    NSMutableDictionary *_textTableFooters;
-    NSMutableArray *_textTableSpacings;
-    NSMutableArray *_textTablePaddings;
-    NSMutableArray *_textTableRows;
-    NSMutableArray *_textTableRowArrays;
-    NSMutableArray *_textTableRowBackgroundColors;
-    NSMutableDictionary *_colorsForNodes;
-    NSMutableDictionary *_attributesForElements;
-    NSMutableDictionary *_fontCache;
-    NSMutableArray *_writingDirectionArray;
-    NSUInteger _domRangeStartIndex;
-    NSInteger _indexingLimit;
-    NSUInteger _thumbnailLimit;
-    NSInteger _errorCode;
-    NSInteger _quoteLevel;
-
-    std::unique_ptr&lt;HTMLConverterCaches&gt; _caches;
-
-    struct {
-        unsigned int isSoft:1;
-        unsigned int reachedStart:1;
-        unsigned int reachedEnd:1;
-        unsigned int isIndexing:1;
-        unsigned int isTesting:1;
-        unsigned int hasTrailingNewline:1;
-        unsigned int pad:26;
-    } _flags;
-}
-
-+ (NSAttributedString *)attributedStringFromRange:(Range*)range;
-#if !PLATFORM(IOS)
-+ (NSAttributedString *)editingAttributedStringFromRange:(Range*)range;
-#endif
-@end
-
-@interface WebHTMLConverter(WebHTMLConverterInternal)
-
-- (id)init;
-- (id)initWithDOMRange:(DOMRange *)domRange;
-- (NSAttributedString *)attributedString;
-
-- (NSString *)_stringForNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
-- (PlatformColor *)_colorForNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
-- (BOOL)_getFloat:(CGFloat *)val forNode:(DOMNode *)node property:(CSSPropertyID)propertyId;
-
-- (void)_traverseNode:(DOMNode *)node depth:(NSInteger)depth embedded:(BOOL)embedded;
-- (void)_traverseFooterNode:(DOMNode *)node depth:(NSInteger)depth;
-
-@end
-
-@implementation WebHTMLConverter
-
-#if !PLATFORM(IOS)
-// Returns the font to be used if the NSFontAttributeName doesn't exist
-static NSFont *WebDefaultFont()
-{
-    static NSFont *defaultFont = nil;
-    if (defaultFont)
-        return defaultFont;
-
-    NSFont *font = [NSFont fontWithName:@&quot;Helvetica&quot; size:12];
-    if (!font)
-        font = [NSFont systemFontOfSize:12];
-
-    defaultFont = [font retain];
-    return defaultFont;
-}
-#endif
-
-static PlatformFont *_fontForNameAndSize(NSString *fontName, CGFloat size, NSMutableDictionary *cache)
-{
-    PlatformFont *font = [cache objectForKey:fontName];
-#if PLATFORM(IOS)
-    if (font)
-        return [font fontWithSize:size];
-
-    font = [PlatformFontClass fontWithName:fontName size:size];
-#else
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-    if (font) {
-        font = [fontManager convertFont:font toSize:size];
-        return font;
-    }
-    font = [fontManager fontWithFamily:fontName traits:0 weight:0 size:size];
-#endif
-    if (!font) {
-#if PLATFORM(IOS)
-        NSArray *availableFamilyNames = [PlatformFontClass familyNames];
-#else
-        NSArray *availableFamilyNames = [fontManager availableFontFamilies];
-#endif
-        NSRange dividingRange;
-        NSRange dividingSpaceRange = [fontName rangeOfString:@&quot; &quot; options:NSBackwardsSearch];
-        NSRange dividingDashRange = [fontName rangeOfString:@&quot;-&quot; options:NSBackwardsSearch];
-        dividingRange = (0 &lt; dividingSpaceRange.length &amp;&amp; 0 &lt; dividingDashRange.length) ? (dividingSpaceRange.location &gt; dividingDashRange.location ? dividingSpaceRange : dividingDashRange) : (0 &lt; dividingSpaceRange.length ? dividingSpaceRange : dividingDashRange);
-
-        while (dividingRange.length &gt; 0) {
-            NSString *familyName = [fontName substringToIndex:dividingRange.location];
-            if ([availableFamilyNames containsObject:familyName]) {
-#if PLATFORM(IOS)
-                NSString *faceName = [fontName substringFromIndex:(dividingRange.location + dividingRange.length)];
-                NSArray *familyMemberFaceNames = [PlatformFontClass fontNamesForFamilyName:familyName];
-                for (NSString *familyMemberFaceName in familyMemberFaceNames) {
-                    if ([familyMemberFaceName compare:faceName options:NSCaseInsensitiveSearch] == NSOrderedSame) {
-                        font = [PlatformFontClass fontWithName:familyMemberFaceName size:size];
-                        break;
-                    }
-                }
-                if (!font &amp;&amp; [familyMemberFaceNames count])
-                    font = [getUIFontClass() fontWithName:familyName size:size];
-#else
-                NSArray *familyMemberArray;
-                NSString *faceName = [fontName substringFromIndex:(dividingRange.location + dividingRange.length)];
-                NSArray *familyMemberArrays = [fontManager availableMembersOfFontFamily:familyName];
-                NSEnumerator *familyMemberArraysEnum = [familyMemberArrays objectEnumerator];
-                while ((familyMemberArray = [familyMemberArraysEnum nextObject])) {
-                    NSString *familyMemberFaceName = [familyMemberArray objectAtIndex:1];
-                    if ([familyMemberFaceName compare:faceName options:NSCaseInsensitiveSearch] == NSOrderedSame) {
-                        NSFontTraitMask traits = [[familyMemberArray objectAtIndex:3] integerValue];
-                        NSInteger weight = [[familyMemberArray objectAtIndex:2] integerValue];
-                        font = [fontManager fontWithFamily:familyName traits:traits weight:weight size:size];
-                        break;
-                    }
-                }
-                if (!font) {
-                    if (0 &lt; [familyMemberArrays count]) {
-                        NSArray *familyMemberArray = [familyMemberArrays objectAtIndex:0];
-                        NSFontTraitMask traits = [[familyMemberArray objectAtIndex:3] integerValue];
-                        NSInteger weight = [[familyMemberArray objectAtIndex:2] integerValue];
-                        font = [fontManager fontWithFamily:familyName traits:traits weight:weight size:size];
-                    }
-                }
-#endif
-                break;
-            } else {
-                dividingSpaceRange = [familyName rangeOfString:@&quot; &quot; options:NSBackwardsSearch];
-                dividingDashRange = [familyName rangeOfString:@&quot;-&quot; options:NSBackwardsSearch];
-                dividingRange = (0 &lt; dividingSpaceRange.length &amp;&amp; 0 &lt; dividingDashRange.length) ? (dividingSpaceRange.location &gt; dividingDashRange.location ? dividingSpaceRange : dividingDashRange) : (0 &lt; dividingSpaceRange.length ? dividingSpaceRange : dividingDashRange);
-            }
-        }
-    }
-#if PLATFORM(IOS)
-    if (!font)
-        font = [PlatformFontClass systemFontOfSize:size];
-#else
-    if (!font)
-        font = [NSFont fontWithName:@&quot;Times&quot; size:size];
-    if (!font)
-        font = [NSFont userFontOfSize:size];
-    if (!font)
-        font = [fontManager convertFont:WebDefaultFont() toSize:size];
-    if (!font)
-        font = WebDefaultFont();
-#endif
-    [cache setObject:font forKey:fontName];
-
-    return font;
-}
-
-+ (NSParagraphStyle *)defaultParagraphStyle
-{
-    static NSMutableParagraphStyle *defaultParagraphStyle = nil;
-    if (!defaultParagraphStyle) {
-        defaultParagraphStyle = [[PlatformNSParagraphStyle defaultParagraphStyle] mutableCopy];
-        [defaultParagraphStyle setDefaultTabInterval:36];
-        [defaultParagraphStyle setTabStops:[NSArray array]];
-    }
-    return defaultParagraphStyle;
-}
-
-- (NSArray *)_childrenForNode:(DOMNode *)node
-{
-    NSMutableArray *array = [NSMutableArray array];
-    DOMNode *child = [node firstChild];
-    while (child) {
-        [array addObject:child];
-        child = [child nextSibling];
-    }
-    return array;
-}
-
-PassRefPtr&lt;CSSValue&gt; HTMLConverterCaches::computedStylePropertyForElement(Element&amp; element, CSSPropertyID propertyId)
-{
-    if (propertyId == CSSPropertyInvalid)
-        return nullptr;
-
-    auto result = m_computedStyles.add(&amp;element, nullptr);
-    if (result.isNewEntry)
-        result.iterator-&gt;value = std::make_unique&lt;ComputedStyleExtractor&gt;(&amp;element, true);
-    ComputedStyleExtractor&amp; computedStyle = *result.iterator-&gt;value;
-    return computedStyle.propertyValue(propertyId);
-}
-
-PassRefPtr&lt;CSSValue&gt; HTMLConverterCaches::inlineStylePropertyForElement(Element&amp; element, CSSPropertyID propertyId)
-{
-    if (propertyId == CSSPropertyInvalid || !element.isStyledElement())
-        return nullptr;
-    const StyleProperties* properties = toStyledElement(element).inlineStyle();
-    if (!properties)
-        return nullptr;
-    return properties-&gt;getPropertyCSSValue(propertyId);
-}
-
-static bool stringFromCSSValue(CSSValue&amp; value, String&amp; result)
-{
-    if (value.isPrimitiveValue()) {
-        unsigned short primitiveType = toCSSPrimitiveValue(value).primitiveType();
-        if (primitiveType == CSSPrimitiveValue::CSS_STRING || primitiveType == CSSPrimitiveValue::CSS_URI ||
-            primitiveType == CSSPrimitiveValue::CSS_IDENT || primitiveType == CSSPrimitiveValue::CSS_ATTR) {
-            String stringValue = value.cssText();
-            if (stringValue.length()) {
-                result = stringValue;
-                return true;
-            }
-        }
-    } else if (value.isValueList()) {
-        result = value.cssText();
-        return true;
-    }
-    return false;
-}
-
-String HTMLConverterCaches::propertyValueForNode(Node&amp; node, CSSPropertyID propertyId)
-{
-    if (!node.isElementNode()) {
-        if (Node* parent = node.parentNode())
-            return propertyValueForNode(*parent, propertyId);
-        return String();
-    }
-
-    bool inherit = false;
-    Element&amp; element = toElement(node);
-    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
-        String result;
-        if (stringFromCSSValue(*value, result))
-            return result;
-    }
-
-    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
-        String result;
-        if (value-&gt;isInheritedValue())
-            inherit = true;
-        else if (stringFromCSSValue(*value, result))
-            return result;
-    }
-
-    switch (propertyId) {
-    case CSSPropertyDisplay:
-        if (element.hasTagName(headTag) || element.hasTagName(scriptTag) || element.hasTagName(appletTag) || element.hasTagName(noframesTag))
-            return &quot;none&quot;;
-        else if (element.hasTagName(addressTag) || element.hasTagName(blockquoteTag) || element.hasTagName(bodyTag) || element.hasTagName(centerTag)
-             || element.hasTagName(ddTag) || element.hasTagName(dirTag) || element.hasTagName(divTag) || element.hasTagName(dlTag)
-             || element.hasTagName(dtTag) || element.hasTagName(fieldsetTag) || element.hasTagName(formTag) || element.hasTagName(frameTag)
-             || element.hasTagName(framesetTag) || element.hasTagName(hrTag) || element.hasTagName(htmlTag) || element.hasTagName(h1Tag)
-             || element.hasTagName(h2Tag) || element.hasTagName(h3Tag) || element.hasTagName(h4Tag) || element.hasTagName(h5Tag)
-             || element.hasTagName(h6Tag) || element.hasTagName(iframeTag) || element.hasTagName(menuTag) || element.hasTagName(noscriptTag)
-             || element.hasTagName(olTag) || element.hasTagName(pTag) || element.hasTagName(preTag) || element.hasTagName(ulTag))
-            return &quot;block&quot;;
-        else if (element.hasTagName(liTag))
-            return &quot;list-item&quot;;
-        else if (element.hasTagName(tableTag))
-            return &quot;table&quot;;
-        else if (element.hasTagName(trTag))
-            return &quot;table-row&quot;;
-        else if (element.hasTagName(thTag) || element.hasTagName(tdTag))
-            return &quot;table-cell&quot;;
-        else if (element.hasTagName(theadTag))
-            return &quot;table-header-group&quot;;
-        else if (element.hasTagName(tbodyTag))
-            return &quot;table-row-group&quot;;
-        else if (element.hasTagName(tfootTag))
-            return &quot;table-footer-group&quot;;
-        else if (element.hasTagName(colTag))
-            return &quot;table-column&quot;;
-        else if (element.hasTagName(colgroupTag))
-            return &quot;table-column-group&quot;;
-        else if (element.hasTagName(captionTag))
-            return &quot;table-caption&quot;;
-        break;
-    case CSSPropertyWhiteSpace:
-        if (element.hasTagName(preTag))
-            return &quot;pre&quot;;
-        inherit = true;
-        break;
-    case CSSPropertyFontStyle:
-        if (element.hasTagName(iTag) || element.hasTagName(citeTag) || element.hasTagName(emTag) || element.hasTagName(varTag) || element.hasTagName(addressTag))
-            return &quot;italic&quot;;
-        inherit = true;
-        break;
-    case CSSPropertyFontWeight:
-        if (element.hasTagName(bTag) || element.hasTagName(strongTag) || element.hasTagName(thTag))
-            return &quot;bolder&quot;;
-        inherit = true;
-        break;
-    case CSSPropertyTextDecoration:
-        if (element.hasTagName(uTag) || element.hasTagName(insTag))
-            return &quot;underline&quot;;
-        else if (element.hasTagName(sTag) || element.hasTagName(strikeTag) || element.hasTagName(delTag))
-            return &quot;line-through&quot;;
-        inherit = true; // FIXME: This is not strictly correct
-        break;
-    case CSSPropertyTextAlign:
-        if (element.hasTagName(centerTag) || element.hasTagName(captionTag) || element.hasTagName(thTag))
-            return &quot;center&quot;;
-        inherit = true;
-        break;
-    case CSSPropertyVerticalAlign:
-        if (element.hasTagName(supTag))
-            return &quot;super&quot;;
-        else if (element.hasTagName(subTag))
-            return &quot;sub&quot;;
-        else if (element.hasTagName(theadTag) || element.hasTagName(tbodyTag) || element.hasTagName(tfootTag))
-            return &quot;middle&quot;;
-        else if (element.hasTagName(trTag) || element.hasTagName(thTag) || element.hasTagName(tdTag))
-            inherit = true;
-        break;
-    case CSSPropertyFontFamily:
-    case CSSPropertyFontVariant:
-    case CSSPropertyTextTransform:
-    case CSSPropertyTextShadow:
-    case CSSPropertyVisibility:
-    case CSSPropertyBorderCollapse:
-    case CSSPropertyEmptyCells:
-    case CSSPropertyWordSpacing:
-    case CSSPropertyListStyleType:
-    case CSSPropertyDirection:
-        inherit = true; // FIXME: Let classes in the css component figure this out.
-        break;
-    default:
-        break;
-    }
-
-    if (inherit) {
-        if (Node* parent = node.parentNode())
-            return propertyValueForNode(*parent, propertyId);
-    }
-    
-    return String();
-}
-
-- (NSString *)_stringForNode:(DOMNode *)node property:(CSSPropertyID)propertyId
-{
-    Node* coreNode = core(node);
-    if (!coreNode)
-        return nil;
-    String result = _caches-&gt;propertyValueForNode(*coreNode, propertyId);
-    if (!result.length())
-        return nil;
-    return result;
-}
-
-static inline bool floatValueFromPrimitiveValue(CSSPrimitiveValue&amp; primitiveValue, float&amp; result)
-{
-    // FIXME: Use CSSPrimitiveValue::computeValue.
-    switch (primitiveValue.primitiveType()) {
-    case CSSPrimitiveValue::CSS_PX:
-        result = primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PX);
-        return true;
-    case CSSPrimitiveValue::CSS_PT:
-        result = 4 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PT) / 3;
-        return true;
-    case CSSPrimitiveValue::CSS_PC:
-        result = 16 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC);
-        return true;
-    case CSSPrimitiveValue::CSS_CM:
-        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC) / 2.54;
-        return true;
-    case CSSPrimitiveValue::CSS_MM:
-        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_PC) / 25.4;
-        return true;
-    case CSSPrimitiveValue::CSS_IN:
-        result = 96 * primitiveValue.getFloatValue(CSSPrimitiveValue::CSS_IN);
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool HTMLConverterCaches::floatPropertyValueForNode(Node&amp; node, CSSPropertyID propertyId, float&amp; result)
-{
-    if (!node.isElementNode()) {
-        if (ContainerNode* parent = node.parentNode())
-            return floatPropertyValueForNode(*parent, propertyId, result);
-        return false;
-    }
-
-    Element&amp; element = toElement(node);
-    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
-        if (value-&gt;isPrimitiveValue() &amp;&amp; floatValueFromPrimitiveValue(toCSSPrimitiveValue(*value), result))
-            return true;
-    }
-
-    bool inherit = false;
-    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
-        if (value-&gt;isPrimitiveValue() &amp;&amp; floatValueFromPrimitiveValue(toCSSPrimitiveValue(*value), result))
-            return true;
-        if (value-&gt;isInheritedValue())
-            inherit = true;
-    }
-
-    switch (propertyId) {
-    case CSSPropertyTextIndent:
-    case CSSPropertyLetterSpacing:
-    case CSSPropertyWordSpacing:
-    case CSSPropertyLineHeight:
-    case CSSPropertyWidows:
-    case CSSPropertyOrphans:
-        inherit = true;
-        break;
-    default:
-        break;
-    }
-
-    if (inherit) {
-        if (ContainerNode* parent = node.parentNode())
-            return floatPropertyValueForNode(*parent, propertyId, result);
-    }
-
-    return false;
-}
-
-- (BOOL)_getFloat:(CGFloat *)val forNode:(DOMNode *)node property:(CSSPropertyID)propertyId
-{
-    Node* coreNode = core(node);
-    if (!coreNode)
-        return NO;
-    float result;
-    if (!_caches-&gt;floatPropertyValueForNode(*coreNode, propertyId, result))
-        return NO;
-    if (val)
-        *val = result;
-    return YES;
-}
-
-static NSString *_NSFirstPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde)
-{
-    NSArray *array = NSSearchPathForDirectoriesInDomains(directory, domainMask, expandTilde);
-    return [array count] &gt;= 1 ? [array objectAtIndex:0] : nil;
-}
-
-static NSString *_NSSystemLibraryPath(void)
-{
-    return _NSFirstPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES);
-}
-
-- (NSBundle *)_webKitBundle
-{
-    NSBundle *bundle = [NSBundle bundleWithIdentifier:@&quot;com.apple.WebKit&quot;];
-    if (!bundle)
-        bundle = [NSBundle bundleWithPath:[_NSSystemLibraryPath() stringByAppendingPathComponent:@&quot;Frameworks/WebKit.framework&quot;]];
-    return bundle;
-}
-
-#if PLATFORM(IOS)
-static inline UIColor *_platformColor(Color color)
-{
-    return [getUIColorClass() _disambiguated_due_to_CIImage_colorWithCGColor:cachedCGColor(color, WebCore::ColorSpaceDeviceRGB)];
-}
-#else
-static inline NSColor *_platformColor(Color color)
-{
-    return nsColor(color);
-}
-#endif
-
-static inline NSShadow *_shadowForShadowStyle(NSString *shadowStyle)
-{
-    NSShadow *shadow = nil;
-    NSUInteger shadowStyleLength = [shadowStyle length];
-    NSRange openParenRange = [shadowStyle rangeOfString:@&quot;(&quot;];
-    NSRange closeParenRange = [shadowStyle rangeOfString:@&quot;)&quot;];
-    NSRange firstRange = NSMakeRange(NSNotFound, 0);
-    NSRange secondRange = NSMakeRange(NSNotFound, 0);
-    NSRange thirdRange = NSMakeRange(NSNotFound, 0);
-    NSRange spaceRange;
-    if (openParenRange.length &gt; 0 &amp;&amp; closeParenRange.length &gt; 0 &amp;&amp; NSMaxRange(openParenRange) &lt; closeParenRange.location) {
-        NSArray *components = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(openParenRange), closeParenRange.location - NSMaxRange(openParenRange))] componentsSeparatedByString:@&quot;,&quot;];
-        if ([components count] &gt;= 3) {
-            CGFloat red = [[components objectAtIndex:0] floatValue] / 255;
-            CGFloat green = [[components objectAtIndex:1] floatValue] / 255;
-            CGFloat blue = [[components objectAtIndex:2] floatValue] / 255;
-            CGFloat alpha = ([components count] &gt;= 4) ? [[components objectAtIndex:3] floatValue] / 255 : 1;
-            NSColor *shadowColor = [PlatformNSColorClass colorWithCalibratedRed:red green:green blue:blue alpha:alpha];
-            NSSize shadowOffset;
-            CGFloat shadowBlurRadius;
-            firstRange = [shadowStyle rangeOfString:@&quot;px&quot;];
-            if (firstRange.length &gt; 0 &amp;&amp; NSMaxRange(firstRange) &lt; shadowStyleLength)
-                secondRange = [shadowStyle rangeOfString:@&quot;px&quot; options:0 range:NSMakeRange(NSMaxRange(firstRange), shadowStyleLength - NSMaxRange(firstRange))];
-            if (secondRange.length &gt; 0 &amp;&amp; NSMaxRange(secondRange) &lt; shadowStyleLength)
-                thirdRange = [shadowStyle rangeOfString:@&quot;px&quot; options:0 range:NSMakeRange(NSMaxRange(secondRange), shadowStyleLength - NSMaxRange(secondRange))];
-            if (firstRange.location &gt; 0 &amp;&amp; firstRange.length &gt; 0 &amp;&amp; secondRange.length &gt; 0 &amp;&amp; thirdRange.length &gt; 0) {
-                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, firstRange.location)];
-                if (spaceRange.length == 0)
-                    spaceRange = NSMakeRange(0, 0);
-                shadowOffset.width = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), firstRange.location - NSMaxRange(spaceRange))] floatValue];
-                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, secondRange.location)];
-                if (!spaceRange.length)
-                    spaceRange = NSMakeRange(0, 0);
-                CGFloat shadowHeight = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), secondRange.location - NSMaxRange(spaceRange))] floatValue];
-                // I don't know why we have this difference between the two platforms.
-#if PLATFORM(IOS)
-                shadowOffset.height = shadowHeight;
-#else
-                shadowOffset.height = -shadowHeight;
-#endif
-                spaceRange = [shadowStyle rangeOfString:@&quot; &quot; options:NSBackwardsSearch range:NSMakeRange(0, thirdRange.location)];
-                if (!spaceRange.length)
-                    spaceRange = NSMakeRange(0, 0);
-                shadowBlurRadius = [[shadowStyle substringWithRange:NSMakeRange(NSMaxRange(spaceRange), thirdRange.location - NSMaxRange(spaceRange))] floatValue];
-                shadow = [[[PlatformNSShadow alloc] init] autorelease];
-                [shadow setShadowColor:shadowColor];
-                [shadow setShadowOffset:shadowOffset];
-                [shadow setShadowBlurRadius:shadowBlurRadius];
-            }
-        }
-    }
-    return shadow;
-}
-
-bool HTMLConverterCaches::isBlockElement(Element&amp; element)
-{
-    String displayValue = propertyValueForNode(element, CSSPropertyDisplay);
-    if (displayValue == &quot;block&quot; || displayValue == &quot;list-item&quot; || displayValue.startsWith(&quot;table&quot;))
-        return true;
-    String floatValue = propertyValueForNode(element, CSSPropertyFloat);
-    if (floatValue == &quot;left&quot; || floatValue == &quot;right&quot;)
-        return true;
-    return false;
-}
-
-bool HTMLConverterCaches::elementHasOwnBackgroundColor(Element&amp; element)
-{
-    if (!isBlockElement(element))
-        return false;
-    // In the text system, text blocks (table elements) and documents (body elements)
-    // have their own background colors, which should not be inherited.
-    return element.hasTagName(htmlTag) || element.hasTagName(bodyTag) || propertyValueForNode(element, CSSPropertyDisplay).startsWith(&quot;table&quot;);
-}
-
-- (BOOL)_elementIsBlockLevel:(DOMElement *)element
-{
-    return element &amp;&amp; _caches-&gt;isBlockElement(*core(element));
-}
-
-- (BOOL)_elementHasOwnBackgroundColor:(DOMElement *)element
-{
-    return element &amp;&amp; _caches-&gt;elementHasOwnBackgroundColor(*core(element));
-}
-
-- (DOMElement *)_blockLevelElementForNode:(DOMNode *)node
-{
-    DOMElement *element = (DOMElement *)node;
-    while (element &amp;&amp; [element nodeType] != DOM_ELEMENT_NODE)
-        element = (DOMElement *)[element parentNode];
-    if (element &amp;&amp; ![self _elementIsBlockLevel:element])
-        element = [self _blockLevelElementForNode:[element parentNode]];
-    return element;
-}
-
-static Color normalizedColor(Color color, bool ignoreBlack)
-{
-    const double ColorEpsilon = 1 / (2 * (double)255.0);
-    
-    double red, green, blue, alpha;
-    color.getRGBA(red, green, blue, alpha);
-    if (red &lt; ColorEpsilon &amp;&amp; green &lt; ColorEpsilon &amp;&amp; blue &lt; ColorEpsilon &amp;&amp; (ignoreBlack || alpha &lt; ColorEpsilon))
-        return Color();
-    
-    return color;
-}
-
-Color HTMLConverterCaches::colorPropertyValueForNode(Node&amp; node, CSSPropertyID propertyId)
-{
-    if (!node.isElementNode()) {
-        if (Node* parent = node.parentNode())
-            return colorPropertyValueForNode(*parent, propertyId);
-        return Color();
-    }
-
-    Element&amp; element = toElement(node);
-    if (RefPtr&lt;CSSValue&gt; value = computedStylePropertyForElement(element, propertyId)) {
-        if (value-&gt;isPrimitiveValue() &amp;&amp; toCSSPrimitiveValue(*value).isRGBColor())
-            return normalizedColor(Color(toCSSPrimitiveValue(*value).getRGBA32Value()), propertyId == CSSPropertyColor);
-    }
-
-    bool inherit = false;
-    if (RefPtr&lt;CSSValue&gt; value = inlineStylePropertyForElement(element, propertyId)) {
-        if (value-&gt;isPrimitiveValue() &amp;&amp; toCSSPrimitiveValue(*value).isRGBColor())
-            return normalizedColor(Color(toCSSPrimitiveValue(*value).getRGBA32Value()), propertyId == CSSPropertyColor);
-        if (value-&gt;isInheritedValue())
-            inherit = true;
-    }
-
-    switch (propertyId) {
-    case CSSPropertyColor:
-        inherit = true;
-        break;
-    case CSSPropertyBackgroundColor:
-        if (!elementHasOwnBackgroundColor(element)) {
-            if (Element* parentElement = node.parentElement()) {
-                if (!elementHasOwnBackgroundColor(*parentElement))
-                    inherit = true;
-            }
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (inherit) {
-        if (Node* parent = node.parentNode())
-            return colorPropertyValueForNode(*parent, propertyId);
-    }
-
-    return Color();
-}
-
-- (PlatformColor *)_colorForNode:(DOMNode *)node property:(CSSPropertyID)propertyId
-{
-    Node* coreNode = core(node);
-    if (!coreNode)
-        return nil;
-    Color result = _caches-&gt;colorPropertyValueForNode(*coreNode, propertyId);
-    if (!result.isValid())
-        return nil;
-    PlatformColor *platformResult = _platformColor(result);
-    if ([[PlatformColorClass clearColor] isEqual:platformResult] || ([platformResult alphaComponent] == 0.0))
-        return nil;
-    return platformResult;
-}
-
-#define UIFloatIsZero(number) (fabs(number - 0) &lt; FLT_EPSILON)
-
-- (NSDictionary *)_computedAttributesForElement:(DOMElement *)element
-{
-    DOMElement *blockElement = [self _blockLevelElementForNode:element];
-    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
-#if !PLATFORM(IOS)
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-#endif
-    NSString *textDecoration = [self _stringForNode:element property:CSSPropertyTextDecoration];
-    NSString *verticalAlign = [self _stringForNode:element property:CSSPropertyVerticalAlign];
-    NSString *textShadow = [self _stringForNode:element property:CSSPropertyTextShadow];
-    NSString *fontLigatures = [self _stringForNode:element property:CSSPropertyWebkitFontVariantLigatures];
-    NSString *fontKerning = [self _stringForNode:element property:CSSPropertyWebkitFontKerning];
-    NSString *letterSpacing = [self _stringForNode:element property:CSSPropertyLetterSpacing];
-    CGFloat fontSize = 0;
-    CGFloat baselineOffset = 0;
-    CGFloat strokeWidth = 0.0;
-    PlatformFont *font = nil;
-    PlatformFont *actualFont = (PlatformFont *)[element _font];
-    PlatformColor *foregroundColor = [self _colorForNode:element property:CSSPropertyColor];
-    PlatformColor *backgroundColor = [self _colorForNode:element property:CSSPropertyBackgroundColor];
-    PlatformColor *strokeColor = [self _colorForNode:element property:CSSPropertyWebkitTextStrokeColor];
-
-    if (![self _getFloat:&amp;fontSize forNode:element property:CSSPropertyFontSize] || fontSize &lt;= 0.0)
-        fontSize = _defaultFontSize;
-    fontSize *= _textSizeMultiplier;
-    if (fontSize &lt; _minimumFontSize) fontSize = _minimumFontSize;
-    if (fabs(floor(2.0 * fontSize + 0.5) / 2.0 - fontSize) &lt; 0.05)
-        fontSize = (CGFloat)floor(2.0 * fontSize + 0.5) / 2;
-    else if (fabs(floor(10.0 * fontSize + 0.5) / 10.0 - fontSize) &lt; 0.005)
-        fontSize = (CGFloat)floor(10.0 * fontSize + 0.5) / 10;
-
-    if (fontSize &lt;= 0.0)
-        fontSize = 12;
-    
-#if PLATFORM(IOS)
-    if (actualFont)
-        font = [actualFont fontWithSize:fontSize];
-#else
-    if (actualFont)
-        font = [fontManager convertFont:actualFont toSize:fontSize];
-#endif
-    if (!font) {
-        NSString *fontName = [[self _stringForNode:element property:CSSPropertyFontFamily] capitalizedString];
-        NSString *fontStyle = [self _stringForNode:element property:CSSPropertyFontStyle];
-        NSString *fontWeight = [self _stringForNode:element property:CSSPropertyFontWeight];
-#if !PLATFORM(IOS)
-        NSString *fontVariant = [self _stringForNode:element property:CSSPropertyFontVariant];
-#endif
-        if (!fontName)
-            fontName = _standardFontFamily;
-        if (fontName)
-            font = _fontForNameAndSize(fontName, fontSize, _fontCache);
-        if (!font)
-            font = [PlatformFontClass fontWithName:@&quot;Times&quot; size:fontSize];
-        if ([@&quot;italic&quot; isEqualToString:fontStyle] || [@&quot;oblique&quot; isEqualToString:fontStyle]) {
-            PlatformFont *originalFont = font;
-#if PLATFORM(IOS)
-            font = [PlatformFontClass fontWithFamilyName:[font familyName] traits:UIFontTraitItalic size:[font pointSize]];
-#else
-            font = [fontManager convertFont:font toHaveTrait:NSItalicFontMask];
-#endif
-            if (!font)
-                font = originalFont;
-        }
-        if ([fontWeight hasPrefix:@&quot;bold&quot;] || [fontWeight integerValue] &gt;= 700) {
-            // ??? handle weight properly using NSFontManager
-            PlatformFont *originalFont = font;
-#if PLATFORM(IOS)
-            font = [PlatformFontClass fontWithFamilyName:[font familyName] traits:UIFontTraitBold size:[font pointSize]];
-#else
-            font = [fontManager convertFont:font toHaveTrait:NSBoldFontMask];
-#endif
-            if (!font)
-                font = originalFont;
-        }
-#if !PLATFORM(IOS) // IJB: No small caps support on iOS
-        if ([@&quot;small-caps&quot; isEqualToString:fontVariant]) {
-            // ??? synthesize small-caps if [font isEqual:originalFont]
-            NSFont *originalFont = font;
-            font = [fontManager convertFont:font toHaveTrait:NSSmallCapsFontMask];
-            if (!font)
-                font = originalFont;
-        }
-#endif
-    }
-    if (font)
-        [attrs setObject:font forKey:NSFontAttributeName];
-    if (foregroundColor)
-        [attrs setObject:foregroundColor forKey:NSForegroundColorAttributeName];
-    if (backgroundColor &amp;&amp; ![self _elementHasOwnBackgroundColor:element])
-        [attrs setObject:backgroundColor forKey:NSBackgroundColorAttributeName];
-
-    if ([self _getFloat:&amp;strokeWidth forNode:element property:CSSPropertyWebkitTextStrokeWidth]) {
-        float textStrokeWidth = strokeWidth / ([font pointSize] * 0.01);
-        [attrs setObject:[NSNumber numberWithDouble:textStrokeWidth] forKey:NSStrokeWidthAttributeName];
-    }
-    if(strokeColor)
-        [attrs setObject:strokeColor forKey:NSStrokeColorAttributeName];
-    if (fontKerning || letterSpacing) {
-        if ([fontKerning rangeOfString:@&quot;none&quot;].location != NSNotFound)
-            [attrs setObject:@0.0 forKey:NSKernAttributeName];
-        else {
-            double kernVal = letterSpacing ? [letterSpacing doubleValue] : 0.0;
-            if (UIFloatIsZero(kernVal))
-                [attrs setObject:@0.0 forKey:NSKernAttributeName]; // auto and normal, the other possible values, are both &quot;kerning enabled&quot;
-            else
-                [attrs setObject:[NSNumber numberWithDouble:kernVal] forKey:NSKernAttributeName];
-        }
-    }
-    if (fontLigatures) {
-        if ([fontLigatures rangeOfString:@&quot;normal&quot;].location != NSNotFound)
-            ;   // default: whatever the system decides to do
-        else if ([fontLigatures rangeOfString:@&quot;common-ligatures&quot;].location != NSNotFound)
-            [attrs setObject:@1 forKey:NSLigatureAttributeName];   // explicitly enabled
-        else if ([fontLigatures rangeOfString:@&quot;no-common-ligatures&quot;].location != NSNotFound)
-            [attrs setObject:@0 forKey:NSLigatureAttributeName];  // explicitly disabled
-    }
-
-    if (textDecoration &amp;&amp; [textDecoration length] &gt; 4) {
-        if ([textDecoration rangeOfString:@&quot;underline&quot;].location != NSNotFound)
-            [attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
-        if ([textDecoration rangeOfString:@&quot;line-through&quot;].location != NSNotFound)
-            [attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
-    }
-    if (verticalAlign) {
-        if ([verticalAlign rangeOfString:@&quot;super&quot;].location != NSNotFound)
-            [attrs setObject:[NSNumber numberWithInteger:1] forKey:NSSuperscriptAttributeName];
-        if ([verticalAlign rangeOfString:@&quot;sub&quot;].location != NSNotFound)
-            [attrs setObject:[NSNumber numberWithInteger:-1] forKey:NSSuperscriptAttributeName];
-    }
-    if ([self _getFloat:&amp;baselineOffset forNode:element property:CSSPropertyVerticalAlign])
-        [attrs setObject:[NSNumber numberWithDouble:baselineOffset] forKey:NSBaselineOffsetAttributeName];
-    if (textShadow &amp;&amp; [textShadow length] &gt; 4) {
-        NSShadow *shadow = _shadowForShadowStyle(textShadow);
-        if (shadow)
-            [attrs setObject:shadow forKey:NSShadowAttributeName];
-    }
-    if (element != blockElement &amp;&amp; [_writingDirectionArray count] &gt; 0)
-        [attrs setObject:[NSArray arrayWithArray:_writingDirectionArray] forKey:NSWritingDirectionAttributeName];
-    
-    if (blockElement) {
-        NSMutableParagraphStyle *paragraphStyle = [[[self class] defaultParagraphStyle] mutableCopy];
-        NSString *blockTag = [blockElement tagName];
-        BOOL isParagraph = ([@&quot;P&quot; isEqualToString:blockTag] || [@&quot;LI&quot; isEqualToString:blockTag] || ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]));
-        NSString *textAlign = [self _stringForNode:blockElement property:CSSPropertyTextAlign];
-        NSString *direction = [self _stringForNode:blockElement property:CSSPropertyDirection];
-        NSString *hyphenation = [self _stringForNode:blockElement property:CSSPropertyWebkitHyphens];
-        CGFloat leftMargin = 0;
-        CGFloat rightMargin = 0;
-        CGFloat bottomMargin = 0;
-        CGFloat textIndent = 0;
-        CGFloat lineHeight = 0;
-        if (textAlign) {
-            // WebKit can return -khtml-left, -khtml-right, -khtml-center
-            if ([textAlign hasSuffix:@&quot;left&quot;])
-                [paragraphStyle setAlignment:NSTextAlignmentLeft];
-            else if ([textAlign hasSuffix:@&quot;right&quot;])
-                [paragraphStyle setAlignment:NSTextAlignmentRight];
-            else if ([textAlign hasSuffix:@&quot;center&quot;])
-                [paragraphStyle setAlignment:NSTextAlignmentCenter];
-            else if ([textAlign hasSuffix:@&quot;justify&quot;])
-                [paragraphStyle setAlignment:NSTextAlignmentJustified];
-        }
-        if (direction) {
-            if ([direction isEqualToString:@&quot;ltr&quot;])
-                [paragraphStyle setBaseWritingDirection:NSWritingDirectionLeftToRight];
-            else if ([direction isEqualToString:@&quot;rtl&quot;])
-                [paragraphStyle setBaseWritingDirection:NSWritingDirectionRightToLeft];
-        }
-        if(hyphenation) {
-            if ([hyphenation isEqualToString:@&quot;auto&quot;])
-                [paragraphStyle setHyphenationFactor:1.0];
-            else
-                [paragraphStyle setHyphenationFactor:0.0];
-        }
-        if ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]) {
-            NSInteger headerLevel = [blockTag characterAtIndex:1] - '0';
-            if (1 &lt;= headerLevel &amp;&amp; headerLevel &lt;= 6)
-                [paragraphStyle setHeaderLevel:headerLevel];
-        }
-        if (isParagraph) {
-            if ([self _getFloat:&amp;leftMargin forNode:blockElement property:CSSPropertyMarginLeft] &amp;&amp; leftMargin &gt; 0.0)
-                [paragraphStyle setHeadIndent:leftMargin];
-            if ([self _getFloat:&amp;textIndent forNode:blockElement property:CSSPropertyTextIndent])
-                [paragraphStyle setFirstLineHeadIndent:[paragraphStyle headIndent] + textIndent];
-            if ([self _getFloat:&amp;rightMargin forNode:blockElement property:CSSPropertyMarginRight] &amp;&amp; rightMargin &gt; 0.0)
-                [paragraphStyle setTailIndent:-rightMargin];
-            if ([self _getFloat:&amp;bottomMargin forNode:blockElement property:CSSPropertyMarginBottom] &amp;&amp; bottomMargin &gt; 0.0)
-                [paragraphStyle setParagraphSpacing:bottomMargin];
-        }
-        if (_webViewTextSizeMultiplier &gt; 0.0 &amp;&amp; [self _getFloat:&amp;lineHeight forNode:element property:CSSPropertyLineHeight] &amp;&amp; lineHeight &gt; 0.0)
-            [paragraphStyle setMinimumLineHeight:lineHeight / _webViewTextSizeMultiplier];
-        if ([_textLists count] &gt; 0)
-            [paragraphStyle setTextLists:_textLists];
-        if ([_textBlocks count] &gt; 0)
-            [paragraphStyle setTextBlocks:_textBlocks];
-        [attrs setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
-        [paragraphStyle release];
-    }
-    return attrs;
-}
-
-- (NSDictionary *)_attributesForElement:(DOMElement *)element
-{
-    NSDictionary *result;
-    if (element) {
-        result = [_attributesForElements objectForKey:element];
-        if (!result) {
-            result = [self _computedAttributesForElement:element];
-            [_attributesForElements setObject:result forKey:element];
-        }
-    } else
-        result = [NSDictionary dictionary];
-    return result;
-
-}
-
-- (void)_newParagraphForElement:(DOMElement *)element tag:(NSString *)tag allowEmpty:(BOOL)flag suppressTrailingSpace:(BOOL)suppress
-{
-    NSUInteger textLength = [_attrStr length];
-    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
-    NSRange rangeToReplace = (suppress &amp;&amp; _flags.isSoft &amp;&amp; (lastChar == ' ' || lastChar == NSLineSeparatorCharacter)) ? NSMakeRange(textLength - 1, 1) : NSMakeRange(textLength, 0);
-    BOOL needBreak = (flag || lastChar != '\n');
-    if (needBreak) {
-        NSString *string = (([@&quot;BODY&quot; isEqualToString:tag] || [@&quot;HTML&quot; isEqualToString:tag]) ? @&quot;&quot; : @&quot;\n&quot;);
-        [_writingDirectionArray removeAllObjects];
-        [_attrStr replaceCharactersInRange:rangeToReplace withString:string];
-        if (rangeToReplace.location &lt; _domRangeStartIndex)
-            _domRangeStartIndex += [string length] - rangeToReplace.length;
-        rangeToReplace.length = [string length];
-        if (!_flags.isIndexing) {
-            NSDictionary *attrs = [self _attributesForElement:element];
-            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-                [_attrStr setAttributes:attrs range:rangeToReplace];
-        }
-        _flags.isSoft = YES;
-    }
-}
-
-- (void)_newLineForElement:(DOMElement *)element
-{
-    unichar c = NSLineSeparatorCharacter;
-    RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithCharacters:&amp;c length:1]);
-    NSUInteger textLength = [_attrStr length];
-    NSRange rangeToReplace = NSMakeRange(textLength, 0);
-    [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
-    rangeToReplace.length = [string length];
-    if (rangeToReplace.location &lt; _domRangeStartIndex) _domRangeStartIndex += rangeToReplace.length;
-    if (!_flags.isIndexing) {
-        NSDictionary *attrs = [self _attributesForElement:element];
-        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-            [_attrStr setAttributes:attrs range:rangeToReplace];
-    }
-    _flags.isSoft = YES;
-}
-
-- (void)_newTabForElement:(DOMElement *)element
-{
-    NSString *string = @&quot;\t&quot;;
-    NSUInteger textLength = [_attrStr length];
-    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
-    NSRange rangeToReplace = (_flags.isSoft &amp;&amp; lastChar == ' ') ? NSMakeRange(textLength - 1, 1) : NSMakeRange(textLength, 0);
-    [_attrStr replaceCharactersInRange:rangeToReplace withString:string];
-    rangeToReplace.length = [string length];
-    if (rangeToReplace.location &lt; _domRangeStartIndex)
-        _domRangeStartIndex += rangeToReplace.length;
-    if (!_flags.isIndexing) {
-        NSDictionary *attrs = [self _attributesForElement:element];
-        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-            [_attrStr setAttributes:attrs range:rangeToReplace];
-    }
-    _flags.isSoft = YES;
-}
-
-- (Class)_WebMessageDocumentClass
-{
-    static Class _WebMessageDocumentClass = Nil;
-    static BOOL lookedUpClass = NO;
-    if (!lookedUpClass) {
-        // If the class is not there, we don't want to try again
-        _WebMessageDocumentClass = objc_lookUpClass(&quot;MFWebMessageDocument&quot;);
-        if (_WebMessageDocumentClass &amp;&amp; ![_WebMessageDocumentClass respondsToSelector:@selector(document:attachment:forURL:)])
-            _WebMessageDocumentClass = Nil;
-        lookedUpClass = YES;
-    }
-    return _WebMessageDocumentClass;
-}
-
-- (BOOL)_addAttachmentForElement:(DOMElement *)element URL:(NSURL *)url needsParagraph:(BOOL)needsParagraph usePlaceholder:(BOOL)flag
-{
-    BOOL retval = NO, notFound = NO;
-    NSFileWrapper *fileWrapper = nil;
-    Frame* frame = core([element ownerDocument])-&gt;frame();
-    DocumentLoader *dataSource = frame-&gt;loader().frameHasLoaded() ? frame-&gt;loader().documentLoader() : 0;
-    BOOL ignoreOrientation = YES;
-
-    if (_flags.isIndexing)
-        return NO;
-    if ([url isFileURL]) {
-        NSString *path = [[url path] stringByStandardizingPath];
-        if (path)
-            fileWrapper = [[[NSFileWrapper alloc] initWithURL:url options:0 error:NULL] autorelease];
-    }
-    if (!fileWrapper) {
-        RefPtr&lt;ArchiveResource&gt; resource = dataSource-&gt;subresource(url);
-        if (!resource)
-            resource = dataSource-&gt;subresource(url);
-
-        const String&amp; mimeType = resource-&gt;mimeType();
-        if (flag &amp;&amp; resource &amp;&amp; mimeType == &quot;text/html&quot;)
-            notFound = YES;
-        if (resource &amp;&amp; !notFound) {
-            fileWrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:resource-&gt;data()-&gt;createNSData().get()] autorelease];
-            [fileWrapper setPreferredFilename:suggestedFilenameWithMIMEType(url, mimeType)];
-        }
-    }
-#if !PLATFORM(IOS)
-    if (!fileWrapper &amp;&amp; !notFound) {
-        fileWrapper = fileWrapperForURL(dataSource, url);
-        if (flag &amp;&amp; fileWrapper &amp;&amp; [[[[fileWrapper preferredFilename] pathExtension] lowercaseString] hasPrefix:@&quot;htm&quot;]) notFound = YES;
-        if (notFound) fileWrapper = nil;
-    }
-    if (!fileWrapper &amp;&amp; !notFound) {
-        fileWrapper = fileWrapperForURL(_dataSource, url);
-        if (flag &amp;&amp; fileWrapper &amp;&amp; [[[[fileWrapper preferredFilename] pathExtension] lowercaseString] hasPrefix:@&quot;htm&quot;]) notFound = YES;
-        if (notFound) fileWrapper = nil;
-    }
-#endif
-    if (!fileWrapper &amp;&amp; !notFound &amp;&amp; url) {
-        // Special handling for Mail attachments, until WebKit provides a standard way to get the data.
-        Class WebMessageDocumentClass = [self _WebMessageDocumentClass];
-        if (WebMessageDocumentClass) {
-            NSTextAttachment *mimeTextAttachment = nil;
-            [WebMessageDocumentClass document:NULL attachment:&amp;mimeTextAttachment forURL:url];
-            if (mimeTextAttachment &amp;&amp; [mimeTextAttachment respondsToSelector:@selector(fileWrapper)]) {
-                fileWrapper = [mimeTextAttachment performSelector:@selector(fileWrapper)];
-                ignoreOrientation = NO;
-            }
-        }
-    }
-    if (fileWrapper || flag) {
-        NSUInteger textLength = [_attrStr length];
-        RetainPtr&lt;NSTextAttachment&gt; attachment = adoptNS([[PlatformNSTextAttachment alloc] initWithFileWrapper:fileWrapper]);
-#if PLATFORM(IOS)
-        NSString *vAlign = [self _stringForNode:element property:CSSPropertyVerticalAlign];
-        attachment.get().bounds = CGRectMake(0, ([vAlign floatValue] / 100.) * element.clientHeight, element.clientWidth, element.clientHeight);
-#endif
-        RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithFormat:(needsParagraph ? @&quot;%C\n&quot; : @&quot;%C&quot;), static_cast&lt;unichar&gt;(NSAttachmentCharacter)]);
-        NSRange rangeToReplace = NSMakeRange(textLength, 0);
-        NSDictionary *attrs;
-        if (fileWrapper) {
-#if !PLATFORM(IOS)
-            if (ignoreOrientation)
-                [attachment setIgnoresOrientation:YES];
-#endif
-        } else {
-#if PLATFORM(IOS)
-            [attachment release];
-            NSURL *missingImageURL = [[self _webKitBundle] URLForResource:@&quot;missing_image&quot; withExtension:@&quot;tiff&quot;];
-            ASSERT_WITH_MESSAGE(missingImageURL != nil, &quot;Unable to find missing_image.tiff!&quot;);
-            NSFileWrapper *missingImageFileWrapper = [[[NSFileWrapper alloc] initWithURL:missingImageURL options:0 error:NULL] autorelease];
-            attachment = [[PlatformNSTextAttachment alloc] initWithFileWrapper:missingImageFileWrapper];
-#else
-            static NSImage *missingImage = nil;
-            NSTextAttachmentCell *cell;
-            cell = [[NSTextAttachmentCell alloc] initImageCell:missingImage];
-            [attachment setAttachmentCell:cell];
-            [cell release];
-#endif
-        }
-        [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
-        rangeToReplace.length = [string length];
-        if (rangeToReplace.location &lt; _domRangeStartIndex)
-            _domRangeStartIndex += rangeToReplace.length;
-        attrs = [self _attributesForElement:element];
-        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0) {
-            [_attrStr setAttributes:attrs range:rangeToReplace];
-            rangeToReplace.length = 1;
-            [_attrStr addAttribute:NSAttachmentAttributeName value:attachment.get() range:rangeToReplace];
-        }
-        _flags.isSoft = NO;
-        retval = YES;
-    }
-    return retval;
-}
-
-- (void)_addQuoteForElement:(DOMElement *)element opening:(BOOL)opening level:(NSInteger)level
-{
-    unichar c = ((level % 2) == 0) ? (opening ? 0x201c : 0x201d) : (opening ? 0x2018 : 0x2019);
-    RetainPtr&lt;NSString&gt; string = adoptNS([[NSString alloc] initWithCharacters:&amp;c length:1]);
-    NSUInteger textLength = [_attrStr length];
-    NSRange rangeToReplace = NSMakeRange(textLength, 0);
-    [_attrStr replaceCharactersInRange:rangeToReplace withString:string.get()];
-    rangeToReplace.length = [string length];
-    if (rangeToReplace.location &lt; _domRangeStartIndex)
-        _domRangeStartIndex += rangeToReplace.length;
-    if (!_flags.isIndexing) {
-        RetainPtr&lt;NSDictionary&gt; attrs = [self _attributesForElement:element];
-        if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-            [_attrStr setAttributes:attrs.get() range:rangeToReplace];
-    }
-    _flags.isSoft = NO;
-}
-
-- (void)_addValue:(NSString *)value forElement:(DOMElement *)element
-{
-    NSUInteger textLength = [_attrStr length];
-    NSUInteger valueLength = [value length];
-    NSRange rangeToReplace = NSMakeRange(textLength, 0);
-    if (valueLength) {
-        [_attrStr replaceCharactersInRange:rangeToReplace withString:value];
-        rangeToReplace.length = valueLength;
-        if (rangeToReplace.location &lt; _domRangeStartIndex)
-            _domRangeStartIndex += rangeToReplace.length;
-        if (!_flags.isIndexing) {
-            RetainPtr&lt;NSDictionary&gt; attrs = [self _attributesForElement:element];
-            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-                [_attrStr setAttributes:attrs.get() range:rangeToReplace];
-        }
-        _flags.isSoft = NO;
-    }
-}
-
-- (void)_fillInBlock:(NSTextBlock *)block forElement:(DOMElement *)element backgroundColor:(PlatformColor *)backgroundColor extraMargin:(CGFloat)extraMargin extraPadding:(CGFloat)extraPadding isTable:(BOOL)isTable
-{
-    CGFloat val = 0;
-    PlatformColor *color = nil;
-    BOOL isTableCellElement = [element isKindOfClass:[DOMHTMLTableCellElement class]];
-    NSString *width = isTableCellElement ? [(DOMHTMLTableCellElement *)element width] : [element getAttribute:@&quot;width&quot;];
-
-    if ((width &amp;&amp; [width length]) || !isTable) {
-        if ([self _getFloat:&amp;val forNode:element property:CSSPropertyWidth])
-            [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockWidth];
-    }
-    
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMinWidth])
-        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMinimumWidth];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMaxWidth])
-        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMaximumWidth];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMinHeight])
-        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMinimumHeight];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMaxHeight])
-        [block setValue:val type:NSTextBlockAbsoluteValueType forDimension:NSTextBlockMaximumHeight];
-
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingLeft])
-        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinXEdge];
-    else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingTop])
-        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinYEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMinYEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingRight])
-        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxXEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyPaddingBottom])
-        [block setWidth:val + extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxYEdge]; else [block setWidth:extraPadding type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding edge:NSMaxYEdge];
-    
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderLeftWidth])
-        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMinXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderTopWidth])
-        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMinYEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderRightWidth])
-        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMaxXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyBorderBottomWidth])
-        [block setWidth:val type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder edge:NSMaxYEdge];
-
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginLeft])
-        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinXEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginTop])
-        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinYEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMinYEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginRight])
-        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxXEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxXEdge];
-    if ([self _getFloat:&amp;val forNode:element property:CSSPropertyMarginBottom])
-        [block setWidth:val + extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxYEdge]; else [block setWidth:extraMargin type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockMargin edge:NSMaxYEdge];
-
-    if ((color = [self _colorForNode:element property:CSSPropertyBackgroundColor]))
-        [block setBackgroundColor:color];
-    if (!color &amp;&amp; backgroundColor) [block setBackgroundColor:backgroundColor];
-    if ((color = [self _colorForNode:element property:CSSPropertyBorderLeftColor]))
-        [block setBorderColor:color forEdge:NSMinXEdge];
-    if ((color = [self _colorForNode:element property:CSSPropertyBorderTopColor]))
-        [block setBorderColor:color forEdge:NSMinYEdge];
-    if ((color = [self _colorForNode:element property:CSSPropertyBorderRightColor]))
-        [block setBorderColor:color forEdge:NSMaxXEdge];
-    if ((color = [self _colorForNode:element property:CSSPropertyBorderBottomColor]))
-        [block setBorderColor:color forEdge:NSMaxYEdge];
-}
-
-static inline BOOL read2DigitNumber(const char **pp, int8_t *outval)
-{
-    BOOL result = NO;
-    char c1 = *(*pp)++, c2;
-    if (isASCIIDigit(c1)) {
-        c2 = *(*pp)++;
-        if (isASCIIDigit(c2)) {
-            *outval = 10 * (c1 - '0') + (c2 - '0');
-            result = YES;
-        }
-    }
-    return result;
-}
-
-static inline NSDate *_dateForString(NSString *string)
-{
-    const char *p = [string UTF8String];
-    RetainPtr&lt;NSDateComponents&gt; dateComponents = adoptNS([[NSDateComponents alloc] init]);
-
-    // Set the time zone to GMT
-    [dateComponents setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
-
-    NSInteger year = 0;
-    while (*p &amp;&amp; isASCIIDigit(*p))
-        year = 10 * year + *p++ - '0';
-    if (*p++ != '-')
-        return nil;
-    [dateComponents setYear:year];
-
-    int8_t component;
-    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != '-')
-        return nil;
-    [dateComponents setMonth:component];
-
-    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != 'T')
-        return nil;
-    [dateComponents setDay:component];
-
-    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != ':')
-        return nil;
-    [dateComponents setHour:component];
-
-    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != ':')
-        return nil;
-    [dateComponents setMinute:component];
-
-    if (!read2DigitNumber(&amp;p, &amp;component) || *p++ != 'Z')
-        return nil;
-    [dateComponents setSecond:component];
-    
-#if (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 80000) || (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 1090)
-    NSString *calendarIdentifier = NSCalendarIdentifierGregorian;
-#else
-    NSString *calendarIdentifier = NSGregorianCalendar;
-#endif
-
-    return [[[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier] autorelease] dateFromComponents:dateComponents.get()];
-}
-
-static NSInteger _colCompare(id block1, id block2, void *)
-{
-    NSInteger col1 = [(NSTextTableBlock *)block1 startingColumn];
-    NSInteger col2 = [(NSTextTableBlock *)block2 startingColumn];
-    return ((col1 &lt; col2) ? NSOrderedAscending : ((col1 == col2) ? NSOrderedSame : NSOrderedDescending));
-}
-
-- (void)_processMetaElementWithName:(NSString *)name content:(NSString *)content {
-    NSString *key = nil;
-    if (NSOrderedSame == [@&quot;CocoaVersion&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        CGFloat versionNumber = [content doubleValue];
-        if (versionNumber &gt; 0.0) {
-            // ??? this should be keyed off of version number in future
-            [_documentAttrs removeObjectForKey:NSConvertedDocumentAttribute];
-            [_documentAttrs setObject:[NSNumber numberWithDouble:versionNumber] forKey:NSCocoaVersionDocumentAttribute];
-        }
-#if PLATFORM(IOS)
-    } else if (NSOrderedSame == [@&quot;Generator&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        key = NSGeneratorDocumentAttribute;
-#endif
-    } else if (NSOrderedSame == [@&quot;Keywords&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        if (content &amp;&amp; [content length] &gt; 0) {
-            NSArray *array;
-            // ??? need better handling here and throughout
-            if ([content rangeOfString:@&quot;, &quot;].length == 0 &amp;&amp; [content rangeOfString:@&quot;,&quot;].length &gt; 0)
-                array = [content componentsSeparatedByString:@&quot;,&quot;];
-            else if ([content rangeOfString:@&quot;, &quot;].length == 0 &amp;&amp; [content rangeOfString:@&quot; &quot;].length &gt; 0)
-                array = [content componentsSeparatedByString:@&quot; &quot;];
-            else
-                array = [content componentsSeparatedByString:@&quot;, &quot;];
-            [_documentAttrs setObject:array forKey:NSKeywordsDocumentAttribute];
-        }
-    } else if (NSOrderedSame == [@&quot;Author&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSAuthorDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;LastAuthor&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSEditorDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;Company&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSCompanyDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;Copyright&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSCopyrightDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;Subject&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSSubjectDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;Description&quot; compare:name options:NSCaseInsensitiveSearch] || NSOrderedSame == [@&quot;Comment&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSCommentDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;CreationTime&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        if (content &amp;&amp; [content length] &gt; 0) {
-            NSDate *date = _dateForString(content);
-            if (date)
-                [_documentAttrs setObject:date forKey:NSCreationTimeDocumentAttribute];
-        }
-    } else if (NSOrderedSame == [@&quot;ModificationTime&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        if (content &amp;&amp; [content length] &gt; 0) {
-            NSDate *date = _dateForString(content);
-            if (date)
-                [_documentAttrs setObject:date forKey:NSModificationTimeDocumentAttribute];
-        }
-    }
-#if PLATFORM(IOS)
-    else if (NSOrderedSame == [@&quot;DisplayName&quot; compare:name options:NSCaseInsensitiveSearch] || NSOrderedSame == [@&quot;IndexTitle&quot; compare:name options:NSCaseInsensitiveSearch])
-        key = NSDisplayNameDocumentAttribute;
-    else if (NSOrderedSame == [@&quot;robots&quot; compare:name options:NSCaseInsensitiveSearch]) {
-        if ([content rangeOfString:@&quot;noindex&quot; options:NSCaseInsensitiveSearch].length &gt; 0)
-            [_documentAttrs setObject:[NSNumber numberWithInteger:1] forKey:NSNoIndexDocumentAttribute];
-    }
-#endif
-    if (key &amp;&amp; content &amp;&amp; [content length] &gt; 0)
-        [_documentAttrs setObject:content forKey:key];
-}
-
-- (void)_processHeadElement:(DOMElement *)element {
-    // ??? should gather data from other sources e.g. Word, but for that we would need to be able to get comments from DOM
-    NSArray *childNodes = [self _childrenForNode:element];
-    NSUInteger count = [childNodes count];
-    for (NSUInteger i = 0; i &lt; count; i++) {
-        DOMNode *node = [childNodes objectAtIndex:i];
-        unsigned short nodeType = [node nodeType];
-        if (DOM_ELEMENT_NODE == nodeType) {
-            DOMElement *element = (DOMElement *)node;
-            NSString *tag = [element tagName];
-            if ([@&quot;META&quot; isEqualToString:tag] &amp;&amp; [element respondsToSelector:@selector(name)] &amp;&amp; [element respondsToSelector:@selector(content)]) {
-                NSString *name = [(DOMHTMLMetaElement *)element name];
-                NSString *content = [(DOMHTMLMetaElement *)element content];
-                if (name &amp;&amp; content)
-                    [self _processMetaElementWithName:name content:content];
-            }
-        }
-    }
-}
-
-- (BOOL)_enterElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal embedded:(BOOL)embedded
-{
-    if ([@&quot;HEAD&quot; isEqualToString:tag] &amp;&amp; !embedded)
-        [self _processHeadElement:element];
-    else if (!displayVal || !([@&quot;none&quot; isEqualToString:displayVal] || [@&quot;table-column&quot; isEqualToString:displayVal] || [@&quot;table-column-group&quot; isEqualToString:displayVal])) {
-        if ([self _elementIsBlockLevel:element] &amp;&amp; ![@&quot;BR&quot; isEqualToString:tag] &amp;&amp; !([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] == 0) 
-            &amp;&amp; !([_textLists count] &gt; 0 &amp;&amp; [@&quot;block&quot; isEqualToString:displayVal] &amp;&amp; ![@&quot;LI&quot; isEqualToString:tag] &amp;&amp; ![@&quot;UL&quot; isEqualToString:tag] &amp;&amp; ![@&quot;OL&quot; isEqualToString:tag]))
-            [self _newParagraphForElement:element tag:tag allowEmpty:NO suppressTrailingSpace:YES];
-        return YES;
-    }
-    return NO;
-}
-
-- (void)_addTableForElement:(DOMElement *)tableElement
-{
-    RetainPtr&lt;NSTextTable&gt; table = adoptNS([[PlatformNSTextTable alloc] init]);
-    CGFloat cellSpacingVal = 1;
-    CGFloat cellPaddingVal = 1;
-    [table setNumberOfColumns:1];
-    [table setLayoutAlgorithm:NSTextTableAutomaticLayoutAlgorithm];
-    [table setCollapsesBorders:NO];
-    [table setHidesEmptyCells:NO];
-    if (tableElement) {
-        NSString *borderCollapse = [self _stringForNode:tableElement property:CSSPropertyBorderCollapse];
-        NSString *emptyCells = [self _stringForNode:tableElement property:CSSPropertyEmptyCells];
-        NSString *tableLayout = [self _stringForNode:tableElement property:CSSPropertyTableLayout];
-        if ([tableElement respondsToSelector:@selector(cellSpacing)]) {
-            NSString *cellSpacing = [(DOMHTMLTableElement *)tableElement cellSpacing];
-            if (cellSpacing &amp;&amp; [cellSpacing length] &gt; 0 &amp;&amp; ![cellSpacing hasSuffix:@&quot;%&quot;]) cellSpacingVal = [cellSpacing floatValue];
-        }
-        if ([tableElement respondsToSelector:@selector(cellPadding)]) {
-            NSString *cellPadding = [(DOMHTMLTableElement *)tableElement cellPadding];
-            if (cellPadding &amp;&amp; [cellPadding length] &gt; 0 &amp;&amp; ![cellPadding hasSuffix:@&quot;%&quot;]) cellPaddingVal = [cellPadding floatValue];
-        }
-        [self _fillInBlock:table.get() forElement:tableElement backgroundColor:nil extraMargin:0 extraPadding:0 isTable:YES];
-        if ([@&quot;collapse&quot; isEqualToString:borderCollapse]) {
-            [table setCollapsesBorders:YES];
-            cellSpacingVal = 0;
-        }
-        if ([@&quot;hide&quot; isEqualToString:emptyCells]) [table setHidesEmptyCells:YES];
-        if ([@&quot;fixed&quot; isEqualToString:tableLayout]) [table setLayoutAlgorithm:NSTextTableFixedLayoutAlgorithm];
-    }
-    [_textTables addObject:table.get()];
-    [_textTableSpacings addObject:[NSNumber numberWithDouble:cellSpacingVal]];
-    [_textTablePaddings addObject:[NSNumber numberWithDouble:cellPaddingVal]];
-    [_textTableRows addObject:[NSNumber numberWithInteger:0]];
-    [_textTableRowArrays addObject:[NSMutableArray array]];
-}
-
-- (void)_addTableCellForElement:(DOMElement *)tableCellElement
-{
-    NSTextTable *table = [_textTables lastObject];
-    NSInteger rowNumber = [[_textTableRows lastObject] integerValue];
-    NSInteger columnNumber = 0;
-    NSInteger rowSpan = 1;
-    NSInteger colSpan = 1;
-    NSMutableArray *rowArray = [_textTableRowArrays lastObject];
-    NSUInteger count = [rowArray count];
-    PlatformColor *color = ([_textTableRowBackgroundColors count] &gt; 0) ? [_textTableRowBackgroundColors lastObject] : nil;
-    NSTextTableBlock *previousBlock;
-    CGFloat cellSpacingVal = [[_textTableSpacings lastObject] floatValue];
-    if ([color isEqual:[PlatformColorClass clearColor]]) color = nil;
-    for (NSUInteger i = 0; i &lt; count; i++) {
-        previousBlock = [rowArray objectAtIndex:i];
-        if (columnNumber &gt;= [previousBlock startingColumn] &amp;&amp; columnNumber &lt; [previousBlock startingColumn] + [previousBlock columnSpan])
-            columnNumber = [previousBlock startingColumn] + [previousBlock columnSpan];
-    }
-    if (tableCellElement) {
-        if ([tableCellElement respondsToSelector:@selector(rowSpan)]) {
-            rowSpan = [(DOMHTMLTableCellElement *)tableCellElement rowSpan];
-            if (rowSpan &lt; 1)
-                rowSpan = 1;
-        }
-        if ([tableCellElement respondsToSelector:@selector(colSpan)]) {
-            colSpan = [(DOMHTMLTableCellElement *)tableCellElement colSpan];
-            if (colSpan &lt; 1)
-                colSpan = 1;
-        }
-    }
-    RetainPtr&lt;NSTextTableBlock&gt; block = adoptNS([[PlatformNSTextTableBlock alloc] initWithTable:table startingRow:rowNumber rowSpan:rowSpan startingColumn:columnNumber columnSpan:colSpan]);
-    if (tableCellElement) {
-        NSString *verticalAlign = [self _stringForNode:tableCellElement property:CSSPropertyVerticalAlign];
-        [self _fillInBlock:block.get() forElement:tableCellElement backgroundColor:color extraMargin:cellSpacingVal / 2 extraPadding:0 isTable:NO];
-        if ([@&quot;middle&quot; isEqualToString:verticalAlign])
-            [block setVerticalAlignment:NSTextBlockMiddleAlignment];
-        else if ([@&quot;bottom&quot; isEqualToString:verticalAlign])
-            [block setVerticalAlignment:NSTextBlockBottomAlignment];
-        else if ([@&quot;baseline&quot; isEqualToString:verticalAlign])
-            [block setVerticalAlignment:NSTextBlockBaselineAlignment];
-        else if ([@&quot;top&quot; isEqualToString:verticalAlign])
-            [block setVerticalAlignment:NSTextBlockTopAlignment];
-    }
-    [_textBlocks addObject:block.get()];
-    [rowArray addObject:block.get()];
-    [rowArray sortUsingFunction:_colCompare context:NULL];
-}
-
-- (BOOL)_processElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal depth:(NSInteger)depth
-{
-    BOOL retval = YES;
-    BOOL isBlockLevel = [self _elementIsBlockLevel:element];
-    if (isBlockLevel)
-        [_writingDirectionArray removeAllObjects];
-    else {
-        NSString *bidi = [self _stringForNode:element property:CSSPropertyUnicodeBidi];
-        if (bidi &amp;&amp; [bidi isEqualToString:@&quot;embed&quot;]) {
-            NSUInteger val = NSTextWritingDirectionEmbedding;
-            NSString *direction = [self _stringForNode:element property:CSSPropertyDirection];
-            if ([direction isEqualToString:@&quot;rtl&quot;])
-                val |= NSWritingDirectionRightToLeft;
-            [_writingDirectionArray addObject:[NSNumber numberWithUnsignedInteger:val]];
-        } else if (bidi &amp;&amp; [bidi isEqualToString:@&quot;bidi-override&quot;]) {
-            NSUInteger val = NSTextWritingDirectionOverride;
-            NSString *direction = [self _stringForNode:element property:CSSPropertyDirection];
-            if ([direction isEqualToString:@&quot;rtl&quot;])
-                val |= NSWritingDirectionRightToLeft;
-            [_writingDirectionArray addObject:[NSNumber numberWithUnsignedInteger:val]];
-        }
-    }
-    if ([@&quot;table&quot; isEqualToString:displayVal] || ([_textTables count] == 0 &amp;&amp; [@&quot;table-row-group&quot; isEqualToString:displayVal])) {
-        DOMElement *tableElement = element;
-        if ([@&quot;table-row-group&quot; isEqualToString:displayVal]) {
-            // If we are starting in medias res, the first thing we see may be the tbody, so go up to the table
-            tableElement = [self _blockLevelElementForNode:[element parentNode]];
-            if (![@&quot;table&quot; isEqualToString:[self _stringForNode:tableElement property:CSSPropertyDisplay]])
-                tableElement = element;
-        }
-        while ([_textTables count] &gt; [_textBlocks count])
-            [self _addTableCellForElement:nil];
-        [self _addTableForElement:tableElement];
-    } else if ([@&quot;table-footer-group&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
-        [_textTableFooters setObject:element forKey:[NSValue valueWithNonretainedObject:[_textTables lastObject]]];
-        retval = NO;
-    } else if ([@&quot;table-row&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
-        PlatformColor *color = [self _colorForNode:element property:CSSPropertyBackgroundColor];
-        if (!color) color = [PlatformColorClass clearColor];
-        [_textTableRowBackgroundColors addObject:color];
-    } else if ([@&quot;table-cell&quot; isEqualToString:displayVal]) {
-        while ([_textTables count] &lt; [_textBlocks count] + 1) {
-            [self _addTableForElement:nil];
-        }
-        [self _addTableCellForElement:element];
-    } else if ([@&quot;IMG&quot; isEqualToString:tag]) {
-        NSString *urlString = [element getAttribute:@&quot;src&quot;];
-        if (urlString &amp;&amp; [urlString length] &gt; 0) {
-            NSURL *url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
-            if (!url) url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
-#if PLATFORM(IOS)
-            BOOL usePlaceholderImage = NO;
-#else
-            BOOL usePlaceholderImage = YES;
-#endif
-            if (url)
-                [self _addAttachmentForElement:element URL:url needsParagraph:isBlockLevel usePlaceholder:usePlaceholderImage];
-        }
-        retval = NO;
-    } else if ([@&quot;OBJECT&quot; isEqualToString:tag]) {
-        NSString *baseString = [element getAttribute:@&quot;codebase&quot;];
-        NSString *urlString = [element getAttribute:@&quot;data&quot;];
-        NSString *declareString = [element getAttribute:@&quot;declare&quot;];
-        if (urlString &amp;&amp; [urlString length] &gt; 0 &amp;&amp; ![@&quot;true&quot; isEqualToString:declareString]) {
-            NSURL *baseURL = nil;
-            NSURL *url = nil;
-            if (baseString &amp;&amp; [baseString length] &gt; 0) {
-                baseURL = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(baseString));
-                if (!baseURL)
-                    baseURL = [NSURL _web_URLWithString:[baseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
-            }
-            if (baseURL)
-                url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:baseURL];
-            if (!url)
-                url =core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
-            if (!url)
-                url = [NSURL _web_URLWithString:[urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] relativeToURL:_baseURL];
-            if (url)
-                retval = ![self _addAttachmentForElement:element URL:url needsParagraph:isBlockLevel usePlaceholder:NO];
-        }
-    } else if ([@&quot;FRAME&quot; isEqualToString:tag]) {
-        if ([element respondsToSelector:@selector(contentDocument)]) {
-            DOMDocument *contentDocument = [(DOMHTMLFrameElement *)element contentDocument];
-            if (contentDocument)
-                [self _traverseNode:contentDocument depth:depth + 1 embedded:YES];
-        }
-        retval = NO;
-    } else if ([@&quot;IFRAME&quot; isEqualToString:tag]) {
-        if ([element respondsToSelector:@selector(contentDocument)]) {
-            DOMDocument *contentDocument = [(DOMHTMLIFrameElement *)element contentDocument];
-            if (contentDocument) {
-                [self _traverseNode:contentDocument depth:depth + 1 embedded:YES];
-                retval = NO;
-            }
-        }
-    } else if ([@&quot;BR&quot; isEqualToString:tag]) {
-        DOMElement *blockElement = [self _blockLevelElementForNode:[element parentNode]];
-        NSString *breakClass = [element getAttribute:@&quot;class&quot;], *blockTag = [blockElement tagName];
-        BOOL isExtraBreak = [@&quot;Apple-interchange-newline&quot; isEqualToString:breakClass], blockElementIsParagraph = ([@&quot;P&quot; isEqualToString:blockTag] || [@&quot;LI&quot; isEqualToString:blockTag] || ([blockTag hasPrefix:@&quot;H&quot;] &amp;&amp; 2 == [blockTag length]));
-        if (isExtraBreak)
-            _flags.hasTrailingNewline = YES;
-        else {
-            if (blockElement &amp;&amp; blockElementIsParagraph)
-                [self _newLineForElement:element];
-            else
-                [self _newParagraphForElement:element tag:tag allowEmpty:YES suppressTrailingSpace:NO];
-        }
-    } else if ([@&quot;UL&quot; isEqualToString:tag]) {
-        RetainPtr&lt;NSTextList&gt; list;
-        NSString *listStyleType = [self _stringForNode:element property:CSSPropertyListStyleType];
-        if (!listStyleType || [listStyleType length] == 0)
-            listStyleType = @&quot;disc&quot;;
-        list = adoptNS([[PlatformNSTextList alloc] initWithMarkerFormat:[NSString stringWithFormat:@&quot;{%@}&quot;, listStyleType] options:0]);
-        [_textLists addObject:list.get()];
-    } else if ([@&quot;OL&quot; isEqualToString:tag]) {
-        RetainPtr&lt;NSTextList&gt; list;
-        NSString *listStyleType = [self _stringForNode:element property:CSSPropertyListStyleType];
-        if (!listStyleType || [listStyleType length] == 0) listStyleType = @&quot;decimal&quot;;
-        list = adoptNS([[PlatformNSTextList alloc] initWithMarkerFormat:[NSString stringWithFormat:@&quot;{%@}.&quot;, listStyleType] options:0]);
-        if ([element respondsToSelector:@selector(start)]) {
-            NSInteger startingItemNumber = [(DOMHTMLOListElement *)element start];
-            [list setStartingItemNumber:startingItemNumber];
-        }
-        [_textLists addObject:list.get()];
-    } else if ([@&quot;Q&quot; isEqualToString:tag]) {
-        [self _addQuoteForElement:element opening:YES level:_quoteLevel++];
-    } else if ([@&quot;INPUT&quot; isEqualToString:tag]) {
-        if ([element respondsToSelector:@selector(type)] &amp;&amp; [element respondsToSelector:@selector(value)] &amp;&amp; [@&quot;text&quot; compare:[(DOMHTMLInputElement *)element type] options:NSCaseInsensitiveSearch] == NSOrderedSame) {
-            NSString *value = [(DOMHTMLInputElement *)element value];
-            if (value &amp;&amp; [value length] &gt; 0) [self _addValue:value forElement:element];
-        }
-    } else if ([@&quot;TEXTAREA&quot; isEqualToString:tag]) {
-        if ([element respondsToSelector:@selector(value)]) {
-            NSString *value = [(DOMHTMLTextAreaElement *)element value];
-            if (value &amp;&amp; [value length] &gt; 0) [self _addValue:value forElement:element];
-        }
-        retval = NO;
-    }
-    return retval;
-}
-
-- (void)_addMarkersToList:(NSTextList *)list range:(NSRange)range
-{
-    NSInteger itemNum = [list startingItemNumber];
-    NSString *string = [_attrStr string];
-    NSString *stringToInsert;
-    NSDictionary *attrsToInsert = nil;
-    PlatformFont *font;
-    NSParagraphStyle *paragraphStyle;
-    NSMutableParagraphStyle *newStyle;
-    NSTextTab *tab = nil;
-    NSTextTab *tabToRemove;
-    NSRange paragraphRange;
-    NSRange styleRange;
-    NSUInteger textLength = [_attrStr length];
-    NSUInteger listIndex;
-    NSUInteger insertLength;
-    NSUInteger i;
-    NSUInteger count;
-    NSArray *textLists;
-    CGFloat markerLocation;
-    CGFloat listLocation;
-    CGFloat pointSize;
-    
-    if (range.length == 0 || range.location &gt;= textLength)
-        return;
-    if (NSMaxRange(range) &gt; textLength)
-        range.length = textLength - range.location;
-    paragraphStyle = [_attrStr attribute:NSParagraphStyleAttributeName atIndex:range.location effectiveRange:NULL];
-    if (paragraphStyle) {
-        textLists = [paragraphStyle textLists];
-        listIndex = [textLists indexOfObject:list];
-        if (textLists &amp;&amp; listIndex != NSNotFound) {
-            for (NSUInteger idx = range.location; idx &lt; NSMaxRange(range);) {
-                paragraphRange = [string paragraphRangeForRange:NSMakeRange(idx, 0)];
-                paragraphStyle = [_attrStr attribute:NSParagraphStyleAttributeName atIndex:idx effectiveRange:&amp;styleRange];
-                font = [_attrStr attribute:NSFontAttributeName atIndex:idx effectiveRange:NULL];
-                pointSize = font ? [font pointSize] : 12;
-                if ([[paragraphStyle textLists] count] == listIndex + 1) {
-                    stringToInsert = [NSString stringWithFormat:@&quot;\t%@\t&quot;, [list markerForItemNumber:itemNum++]];
-                    insertLength = [stringToInsert length];
-                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting)
-                        attrsToInsert = [PlatformNSTextList _standardMarkerAttributesForAttributes:[_attrStr attributesAtIndex:paragraphRange.location effectiveRange:NULL]];
-
-                    [_attrStr replaceCharactersInRange:NSMakeRange(paragraphRange.location, 0) withString:stringToInsert];
-                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting) [_attrStr setAttributes:attrsToInsert range:NSMakeRange(paragraphRange.location, insertLength)];
-                    range.length += insertLength;
-                    paragraphRange.length += insertLength;
-                    if (paragraphRange.location &lt; _domRangeStartIndex) _domRangeStartIndex += insertLength;
-                    
-                    newStyle = [paragraphStyle mutableCopy];
-                    listLocation = (listIndex + 1) * 36;
-                    markerLocation = listLocation - 25;
-                    [newStyle setFirstLineHeadIndent:0];
-                    [newStyle setHeadIndent:listLocation];
-                    while ((count = [[newStyle tabStops] count]) &gt; 0) {
-                        for (i = 0, tabToRemove = nil; !tabToRemove &amp;&amp; i &lt; count; i++) {
-                            tab = [[newStyle tabStops] objectAtIndex:i];
-                            if ([tab location] &lt;= listLocation) tabToRemove = tab;
-                        }
-                        if (tabToRemove) [newStyle removeTabStop:tab]; else break;
-                    }
-                    tab = [[PlatformNSTextTab alloc] initWithType:NSLeftTabStopType location:markerLocation];
-                    [newStyle addTabStop:tab];
-                    [tab release];
-#if PLATFORM(IOS)
-                    tab = [[PlatformNSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural location:listLocation options:nil];
-#else
-                    tab = [[PlatformNSTextTab alloc] initWithTextAlignment:NSNaturalTextAlignment location:listLocation options:nil];
-#endif
-                    [newStyle addTabStop:tab];
-                    [tab release];
-                    if (!_flags.isIndexing &amp;&amp; !_flags.isTesting) [_attrStr addAttribute:NSParagraphStyleAttributeName value:newStyle range:paragraphRange];
-                    [newStyle release];
-                    
-                    idx = NSMaxRange(paragraphRange);
-                } else {
-                    // skip any deeper-nested lists
-                    idx = NSMaxRange(styleRange);
-                }
-            }
-        }
-    }
-}
-
-- (void)_exitElement:(DOMElement *)element tag:(NSString *)tag display:(NSString *)displayVal depth:(NSInteger)depth startIndex:(NSUInteger)startIndex
-{
-    NSRange range = NSMakeRange(startIndex, [_attrStr length] - startIndex);
-    if (range.length &gt; 0 &amp;&amp; [@&quot;A&quot; isEqualToString:tag]) {
-        NSString *urlString = [element getAttribute:@&quot;href&quot;];
-        NSString *strippedString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-        if (urlString &amp;&amp; [urlString length] &gt; 0 &amp;&amp; strippedString &amp;&amp; [strippedString length] &gt; 0 &amp;&amp; ![strippedString hasPrefix:@&quot;#&quot;]) {
-            NSURL *url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
-            if (!url)
-                url = core([element ownerDocument])-&gt;completeURL(stripLeadingAndTrailingHTMLSpaces(strippedString));
-            if (!url)
-                url = [NSURL _web_URLWithString:strippedString relativeToURL:_baseURL];
-            if (!_flags.isIndexing &amp;&amp; !_flags.isTesting)
-                [_attrStr addAttribute:NSLinkAttributeName value:url ? (id)url : (id)urlString range:range];
-        }
-    }
-    if (!_flags.reachedEnd &amp;&amp; [self _elementIsBlockLevel:element]) {
-        [_writingDirectionArray removeAllObjects];
-        if ([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textBlocks count] == 0) {
-            [self _newTabForElement:element];
-        } else if ([_textLists count] &gt; 0 &amp;&amp; [@&quot;block&quot; isEqualToString:displayVal] &amp;&amp; ![@&quot;LI&quot; isEqualToString:tag] &amp;&amp; ![@&quot;UL&quot; isEqualToString:tag] &amp;&amp; ![@&quot;OL&quot; isEqualToString:tag]) {
-            [self _newLineForElement:element];
-        } else {
-            [self _newParagraphForElement:element tag:tag allowEmpty:(range.length == 0) suppressTrailingSpace:YES];
-        }
-    } else if ([_writingDirectionArray count] &gt; 0) {
-        NSString *bidi = [self _stringForNode:element property:CSSPropertyUnicodeBidi];
-        if (bidi &amp;&amp; ([bidi isEqualToString:@&quot;embed&quot;] || [bidi isEqualToString:@&quot;bidi-override&quot;])) {
-            [_writingDirectionArray removeLastObject];
-        }
-    }
-    range = NSMakeRange(startIndex, [_attrStr length] - startIndex);
-    if ([@&quot;table&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
-        NSValue *key = [NSValue valueWithNonretainedObject:[_textTables lastObject]];
-        DOMNode *footer = [_textTableFooters objectForKey:key];
-        while ([_textTables count] &lt; [_textBlocks count] + 1)
-            [_textBlocks removeLastObject];
-        if (footer) {
-            [self _traverseFooterNode:footer depth:depth + 1];
-            [_textTableFooters removeObjectForKey:key];
-        }
-        [_textTables removeLastObject];
-        [_textTableSpacings removeLastObject];
-        [_textTablePaddings removeLastObject];
-        [_textTableRows removeLastObject];
-        [_textTableRowArrays removeLastObject];
-    } else if ([@&quot;table-row&quot; isEqualToString:displayVal] &amp;&amp; [_textTables count] &gt; 0) {
-        NSTextTable *table = [_textTables lastObject];
-        NSTextTableBlock *block;
-        NSMutableArray *rowArray = [_textTableRowArrays lastObject], *previousRowArray;
-        NSUInteger i, count;
-        NSInteger numberOfColumns = [table numberOfColumns];
-        NSInteger openColumn;
-        NSInteger rowNumber = [[_textTableRows lastObject] integerValue];
-        do {
-            rowNumber++;
-            previousRowArray = rowArray;
-            rowArray = [NSMutableArray array];
-            count = [previousRowArray count];
-            for (i = 0; i &lt; count; i++) {
-                block = [previousRowArray objectAtIndex:i];
-                if ([block startingColumn] + [block columnSpan] &gt; numberOfColumns) numberOfColumns = [block startingColumn] + [block columnSpan];
-                if ([block startingRow] + [block rowSpan] &gt; rowNumber) [rowArray addObject:block];
-            }
-            count = [rowArray count];
-            openColumn = 0;
-            for (i = 0; i &lt; count; i++) {
-                block = [rowArray objectAtIndex:i];
-                if (openColumn &gt;= [block startingColumn] &amp;&amp; openColumn &lt; [block startingColumn] + [block columnSpan]) openColumn = [block startingColumn] + [block columnSpan];
-            }
-        } while (openColumn &gt;= numberOfColumns);
-        if ((NSUInteger)numberOfColumns &gt; [table numberOfColumns])
-            [table setNumberOfColumns:numberOfColumns];
-        [_textTableRows removeLastObject];
-        [_textTableRows addObject:[NSNumber numberWithInteger:rowNumber]];
-        [_textTableRowArrays removeLastObject];
-        [_textTableRowArrays addObject:rowArray];
-        if ([_textTableRowBackgroundColors count] &gt; 0)
-            [_textTableRowBackgroundColors removeLastObject];
-    } else if ([@&quot;table-cell&quot; isEqualToString:displayVal] &amp;&amp; [_textBlocks count] &gt; 0) {
-        while ([_textTables count] &gt; [_textBlocks count]) {
-            [_textTables removeLastObject];
-            [_textTableSpacings removeLastObject];
-            [_textTablePaddings removeLastObject];
-            [_textTableRows removeLastObject];
-            [_textTableRowArrays removeLastObject];
-        }
-        [_textBlocks removeLastObject];
-    } else if (([@&quot;UL&quot; isEqualToString:tag] || [@&quot;OL&quot; isEqualToString:tag]) &amp;&amp; [_textLists count] &gt; 0) {
-        NSTextList *list = [_textLists lastObject];
-        [self _addMarkersToList:list range:range];
-        [_textLists removeLastObject];
-    } else if ([@&quot;Q&quot; isEqualToString:tag]) {
-        [self _addQuoteForElement:element opening:NO level:--_quoteLevel];
-    } else if ([@&quot;SPAN&quot; isEqualToString:tag]) {
-        NSString *className = [element getAttribute:@&quot;class&quot;];
-        NSMutableString *mutableString;
-        NSUInteger i, count = 0;
-        unichar c;
-        if ([@&quot;Apple-converted-space&quot; isEqualToString:className]) {
-            mutableString = [_attrStr mutableString];
-            for (i = range.location; i &lt; NSMaxRange(range); i++) {
-                c = [mutableString characterAtIndex:i];
-                if (0xa0 == c)
-                    [mutableString replaceCharactersInRange:NSMakeRange(i, 1) withString:@&quot; &quot;];
-            }
-        } else if ([@&quot;Apple-converted-tab&quot; isEqualToString:className]) {
-            mutableString = [_attrStr mutableString];
-            for (i = range.location; i &lt; NSMaxRange(range); i++) {
-                NSRange rangeToReplace = NSMakeRange(NSNotFound, 0);
-                c = [mutableString characterAtIndex:i];
-                if (' ' == c || 0xa0 == c) {
-                    count++;
-                    if (count &gt;= 4 || i + 1 &gt;= NSMaxRange(range))
-                        rangeToReplace = NSMakeRange(i + 1 - count, count);
-                } else {
-                    if (count &gt; 0)
-                        rangeToReplace = NSMakeRange(i - count, count);
-                }
-                if (rangeToReplace.length &gt; 0) {
-                    [mutableString replaceCharactersInRange:rangeToReplace withString:@&quot;\t&quot;];
-                    range.length -= (rangeToReplace.length - 1);
-                    i -= (rangeToReplace.length - 1);
-                    if (NSMaxRange(rangeToReplace) &lt;= _domRangeStartIndex) {
-                        _domRangeStartIndex -= (rangeToReplace.length - 1);
-                    } else if (rangeToReplace.location &lt; _domRangeStartIndex) {
-                        _domRangeStartIndex = rangeToReplace.location;
-                    }
-                    count = 0;
-                }
-            }
-        }
-    }
-}
-
-- (void)_processText:(DOMCharacterData *)text
-{
-    NSString *instr = [text data];
-    NSString *outstr = instr;
-    NSString *whitespaceVal;
-    NSString *transformVal;
-    NSUInteger textLength = [_attrStr length];
-    NSUInteger startOffset = 0;
-    NSUInteger endOffset = [instr length];
-    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : '\n';
-    BOOL wasSpace = NO;
-    BOOL wasLeading = YES;
-    BOOL suppressLeadingSpace = ((_flags.isSoft &amp;&amp; lastChar == ' ') || lastChar == '\n' || lastChar == '\r' || lastChar == '\t' || lastChar == NSParagraphSeparatorCharacter || lastChar == NSLineSeparatorCharacter || lastChar == NSFormFeedCharacter || lastChar == WebNextLineCharacter);
-    NSRange rangeToReplace = NSMakeRange(textLength, 0);
-    CFMutableStringRef mutstr = NULL;
-    whitespaceVal = [self _stringForNode:text property:CSSPropertyWhiteSpace];
-    transformVal = [self _stringForNode:text property:CSSPropertyTextTransform];
-    
-    if (_domRange) {
-        if (text == [_domRange startContainer]) {
-            startOffset = (NSUInteger)[_domRange startOffset];
-            _domRangeStartIndex = [_attrStr length];
-            _flags.reachedStart = YES;
-        }
-        if (text == [_domRange endContainer]) {
-            endOffset = (NSUInteger)[_domRange endOffset];
-            _flags.reachedEnd = YES;
-        }
-        if ((startOffset &gt; 0 || endOffset &lt; [instr length]) &amp;&amp; endOffset &gt;= startOffset) {
-            instr = [instr substringWithRange:NSMakeRange(startOffset, endOffset - startOffset)];
-            outstr = instr;
-        }
-    }
-    if ([whitespaceVal hasPrefix:@&quot;pre&quot;]) {
-        if (textLength &gt; 0 &amp;&amp; [instr length] &gt; 0 &amp;&amp; _flags.isSoft) {
-            unichar c = [instr characterAtIndex:0];
-            if (c == '\n' || c == '\r' || c == NSParagraphSeparatorCharacter || c == NSLineSeparatorCharacter || c == NSFormFeedCharacter || c == WebNextLineCharacter)
-                rangeToReplace = NSMakeRange(textLength - 1, 1);
-        }
-    } else {
-        CFStringInlineBuffer inlineBuffer;
-        const unsigned int TextBufferSize = 255;
-
-        unichar buffer[TextBufferSize + 1];
-        NSUInteger i, count = [instr length], idx = 0;
-
-        mutstr = CFStringCreateMutable(NULL, 0);
-        CFStringInitInlineBuffer((CFStringRef)instr, &amp;inlineBuffer, CFRangeMake(0, count));
-        for (i = 0; i &lt; count; i++) {
-            unichar c = CFStringGetCharacterFromInlineBuffer(&amp;inlineBuffer, i);
-            if (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == 0xc || c == 0x200b) {
-                wasSpace = (!wasLeading || !suppressLeadingSpace);
-            } else {
-                if (wasSpace)
-                    buffer[idx++] = ' ';
-                buffer[idx++] = c;
-                if (idx &gt;= TextBufferSize) {
-                    CFStringAppendCharacters(mutstr, buffer, idx);
-                    idx = 0;
-                }
-                wasSpace = wasLeading = NO;
-            }
-        }
-        if (wasSpace)
-            buffer[idx++] = ' ';
-        if (idx &gt; 0)
-            CFStringAppendCharacters(mutstr, buffer, idx);
-        outstr = (NSString *)mutstr;
-    }
-    if ([outstr length] &gt; 0) {
-        if ([@&quot;capitalize&quot; isEqualToString:transformVal])
-            outstr = [outstr capitalizedString];
-        else if ([@&quot;uppercase&quot; isEqualToString:transformVal])
-            outstr = [outstr uppercaseString];
-        else if ([@&quot;lowercase&quot; isEqualToString:transformVal])
-            outstr = [outstr lowercaseString];
-        [_attrStr replaceCharactersInRange:rangeToReplace withString:outstr];
-        rangeToReplace.length = [outstr length];
-        if (!_flags.isIndexing) {
-            RetainPtr&lt;NSDictionary&gt; attrs;
-            DOMElement *element = (DOMElement *)text;
-            while (element) {
-                // Fill attrs dictionary with attributes from parent nodes, not overwriting ones deeper in the tree
-                if([element nodeType] == DOM_ELEMENT_NODE) {
-                    RetainPtr&lt;NSMutableDictionary&gt; newAttrs = adoptNS([[self _attributesForElement:element] mutableCopy]);
-                    if (attrs) {
-                        // Already-set attributes (from lower in the tree) overwrite the higher ones.
-                        [newAttrs addEntriesFromDictionary:attrs.get()];
-                    }
-                    attrs = newAttrs;
-                }
-                element = (DOMElement *)[element parentNode];
-            }
-            if (!_flags.isTesting &amp;&amp; rangeToReplace.length &gt; 0)
-                [_attrStr setAttributes:attrs.get() range:rangeToReplace];
-        }
-        _flags.isSoft = wasSpace;
-    }
-    if (mutstr)
-        CFRelease(mutstr);
-}
-
-- (void)_traverseNode:(DOMNode *)node depth:(NSInteger)depth embedded:(BOOL)embedded
-{
-    unsigned short nodeType;
-    NSArray *childNodes;
-    NSUInteger count;
-    NSUInteger startOffset;
-    NSUInteger endOffset;
-    BOOL isStart = NO;
-    BOOL isEnd = NO;
-
-    if (_flags.reachedEnd)
-        return;
-    if (_domRange &amp;&amp; !_flags.reachedStart &amp;&amp; _domStartAncestors &amp;&amp; ![_domStartAncestors containsObject:node])
-        return;
-    
-    nodeType = [node nodeType];
-    childNodes = [self _childrenForNode:node];
-    count = [childNodes count];
-    startOffset = 0;
-    endOffset = count;
-
-    if (_domRange) {
-        if (node == [_domRange startContainer]) {
-            startOffset = (NSUInteger)[_domRange startOffset];
-            isStart = YES;
-            _flags.reachedStart = YES;
-        }
-        if (node == [_domRange endContainer]) {
-            endOffset = (NSUInteger)[_domRange endOffset];
-            isEnd = YES;
-        }
-    }
-    
-    if (nodeType == DOM_DOCUMENT_NODE || nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
-        for (NSUInteger i = 0; i &lt; count; i++) {
-            if (isStart &amp;&amp; i == startOffset)
-                _domRangeStartIndex = [_attrStr length];
-            if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
-                [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:embedded];
-            if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
-                _flags.reachedEnd = YES;
-            if (_thumbnailLimit &gt; 0 &amp;&amp; [_attrStr length] &gt;= _thumbnailLimit)
-                _flags.reachedEnd = YES;
-            if (_flags.reachedEnd) break;
-        }
-    } else if (nodeType == DOM_ELEMENT_NODE) {
-        DOMElement *element = (DOMElement *)node;
-        NSString *tag = [element tagName], *displayVal = [self _stringForNode:element property:CSSPropertyDisplay];
-        if ([self _enterElement:element tag:tag display:displayVal embedded:embedded]) {
-            NSUInteger startIndex = [_attrStr length];
-            if ([self _processElement:element tag:tag display:displayVal depth:depth]) {
-                for (NSUInteger i = 0; i &lt; count; i++) {
-                    if (isStart &amp;&amp; i == startOffset)
-                        _domRangeStartIndex = [_attrStr length];
-                    if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
-                        [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:embedded];
-                    if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
-                        _flags.reachedEnd = YES;
-                    if (_flags.reachedEnd)
-                        break;
-                }
-                [self _exitElement:element tag:tag display:displayVal depth:depth startIndex:startIndex];
-            }
-        }
-    } else if (nodeType == DOM_TEXT_NODE || nodeType == DOM_CDATA_SECTION_NODE) {
-        [self _processText:(DOMCharacterData *)node];
-    }
-    
-    if (isEnd) _flags.reachedEnd = YES;
-}
-
-- (void)_traverseFooterNode:(DOMNode *)node depth:(NSInteger)depth
-{
-    DOMElement *element = (DOMElement *)node;
-    NSArray *childNodes = [self _childrenForNode:node];
-    NSString *tag = @&quot;TBODY&quot;, *displayVal = @&quot;table-row-group&quot;;
-    NSUInteger count = [childNodes count];
-    NSUInteger startOffset = 0;
-    NSUInteger endOffset = count;
-    BOOL isStart = NO;
-    BOOL isEnd = NO;
-
-    if (_flags.reachedEnd)
-        return;
-    if (_domRange &amp;&amp; !_flags.reachedStart &amp;&amp; _domStartAncestors &amp;&amp; ![_domStartAncestors containsObject:node])
-        return;
-    if (_domRange) {
-        if (node == [_domRange startContainer]) {
-            startOffset = (NSUInteger)[_domRange startOffset];
-            isStart = YES;
-            _flags.reachedStart = YES;
-        }
-        if (node == [_domRange endContainer]) {
-            endOffset = (NSUInteger)[_domRange endOffset];
-            isEnd = YES;
-        }
-    }
-    if ([self _enterElement:element tag:tag display:displayVal embedded:YES]) {
-        NSUInteger startIndex = [_attrStr length];
-        if ([self _processElement:element tag:tag display:displayVal depth:depth]) {
-            for (NSUInteger i = 0; i &lt; count; i++) {
-                if (isStart &amp;&amp; i == startOffset)
-                    _domRangeStartIndex = [_attrStr length];
-                if ((!isStart || startOffset &lt;= i) &amp;&amp; (!isEnd || endOffset &gt; i))
-                    [self _traverseNode:[childNodes objectAtIndex:i] depth:depth + 1 embedded:YES];
-                if (isEnd &amp;&amp; i + 1 &gt;= endOffset)
-                    _flags.reachedEnd = YES;
-                if (_flags.reachedEnd)
-                    break;
-            }
-            [self _exitElement:element tag:tag display:displayVal depth:depth startIndex:startIndex];
-        }
-    }
-    if (isEnd)
-        _flags.reachedEnd = YES;
-}
-
-- (void)_adjustTrailingNewline
-{
-    NSUInteger textLength = [_attrStr length];
-    unichar lastChar = (textLength &gt; 0) ? [[_attrStr string] characterAtIndex:textLength - 1] : 0;
-    BOOL alreadyHasTrailingNewline = (lastChar == '\n' || lastChar == '\r' || lastChar == NSParagraphSeparatorCharacter || lastChar == NSLineSeparatorCharacter || lastChar == WebNextLineCharacter);
-    if (_flags.hasTrailingNewline &amp;&amp; !alreadyHasTrailingNewline)
-        [_attrStr replaceCharactersInRange:NSMakeRange(textLength, 0) withString:@&quot;\n&quot;];
-}
-
-- (void)_loadFromDOMRange
-{
-    if (-1 == _errorCode) {
-        DOMNode *commonAncestorContainer = [_domRange commonAncestorContainer];
-        DOMNode *ancestorContainer = [_domRange startContainer];
-        
-        _domStartAncestors = [[NSMutableArray alloc] init];
-        while (ancestorContainer) {
-            [_domStartAncestors addObject:ancestorContainer];
-            if (ancestorContainer == commonAncestorContainer)
-                break;
-            ancestorContainer = [ancestorContainer parentNode];
-        }
-        _document = [commonAncestorContainer ownerDocument];
-        _dataSource = (DocumentLoader *)core(_document)-&gt;frame()-&gt;loader().documentLoader();
-        if (_textSizeMultiplier &lt;= 0.0)
-            _textSizeMultiplier = 1;
-        if (_defaultFontSize &lt;= 0.0)
-            _defaultFontSize = 12;
-        if (_minimumFontSize &lt; 1.0)
-            _minimumFontSize = 1;
-        if (_document &amp;&amp; _dataSource) {
-            _domRangeStartIndex = 0;
-            _errorCode = 0;
-            [self _traverseNode:commonAncestorContainer depth:0 embedded:NO];
-            if (_domRangeStartIndex &gt; 0 &amp;&amp; _domRangeStartIndex &lt;= [_attrStr length])
-                [_attrStr deleteCharactersInRange:NSMakeRange(0, _domRangeStartIndex)];
-        }
-    }
-}
-
-- (void)dealloc
-{
-    [_attrStr release];
-    [_documentAttrs release];
-    [_domRange release];
-    [_domStartAncestors release];
-    [_standardFontFamily release];
-    [_textLists release];
-    [_textBlocks release];
-    [_textTables release];
-    [_textTableFooters release];
-    [_textTableSpacings release];
-    [_textTablePaddings release];
-    [_textTableRows release];
-    [_textTableRowArrays release];
-    [_textTableRowBackgroundColors release];
-    [_attributesForElements release];
-    [_fontCache release];
-    [_writingDirectionArray release];
-    [super dealloc];
-}
-
-- (id)init
-{
-    self = [super init];
-    if (!self)
-        return nil;
-    
-    _attrStr = [[NSMutableAttributedString alloc] init];
-    _documentAttrs = [[NSMutableDictionary alloc] init];
-
-    _textLists = [[NSMutableArray alloc] init];
-    _textBlocks = [[NSMutableArray alloc] init];
-    _textTables = [[NSMutableArray alloc] init];
-    _textTableFooters = [[NSMutableDictionary alloc] init];
-    _textTableSpacings = [[NSMutableArray alloc] init];
-    _textTablePaddings = [[NSMutableArray alloc] init];
-    _textTableRows = [[NSMutableArray alloc] init];
-    _textTableRowArrays = [[NSMutableArray alloc] init];
-    _textTableRowBackgroundColors = [[NSMutableArray alloc] init];
-    _attributesForElements = [[NSMutableDictionary alloc] init];
-    _fontCache = [[NSMutableDictionary alloc] init];
-    _writingDirectionArray = [[NSMutableArray alloc] init];
-
-    _textSizeMultiplier = 1;
-    _webViewTextSizeMultiplier = 0;
-    _defaultTabInterval = 36;
-    _defaultFontSize = 12;
-    _minimumFontSize = 1;
-    _errorCode = -1;
-    _indexingLimit = 0;
-    _thumbnailLimit = 0;
-    
-    _caches = std::make_unique&lt;HTMLConverterCaches&gt;();
-
-    _flags.isIndexing = (_indexingLimit &gt; 0);
-    _flags.isTesting = 0;
-    
-    return self;
-}
-
-- (id)initWithDOMRange:(DOMRange *)domRange
-{
-    self = [self init];
-    if (!self)
-        return nil;
-    _domRange = [domRange retain];
-    return self;
-}
-
-- (NSAttributedString *)attributedString
-{
-    [self _loadFromDOMRange];
-    return (!_errorCode) ? [[_attrStr retain] autorelease] : nil;
-}
-
-
-// This function supports more HTML features than the editing variant below, such as tables.
-+ (NSAttributedString *)attributedStringFromRange:(Range*)range
-{
-    RetainPtr&lt;WebHTMLConverter&gt; converter = adoptNS([[WebHTMLConverter alloc] initWithDOMRange:kit(range)]);
-    return [converter attributedString];
-}
-
-#if !PLATFORM(IOS)
-
-// This function uses TextIterator, which makes offsets in its result compatible with HTML editing.
-+ (NSAttributedString *)editingAttributedStringFromRange:(Range*)range
-{
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
-    NSUInteger stringLength = 0;
-    RetainPtr&lt;NSMutableDictionary&gt; attrs = adoptNS([[NSMutableDictionary alloc] init]);
-
-    for (TextIterator it(range); !it.atEnd(); it.advance()) {
-        RefPtr&lt;Range&gt; currentTextRange = it.range();
-        Node* startContainer = currentTextRange-&gt;startContainer();
-        Node* endContainer = currentTextRange-&gt;endContainer();
-        int startOffset = currentTextRange-&gt;startOffset();
-        int endOffset = currentTextRange-&gt;endOffset();
-        
-        if (startContainer == endContainer &amp;&amp; (startOffset == endOffset - 1)) {
-            Node* node = startContainer-&gt;childNode(startOffset);
-            if (node &amp;&amp; node-&gt;hasTagName(imgTag)) {
-                NSFileWrapper* fileWrapper = fileWrapperForElement(toElement(node));
-                NSTextAttachment* attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
-                [string appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
-                [attachment release];
-            }
-        }
-
-        int currentTextLength = it.text().length();
-        if (!currentTextLength)
-            continue;
-
-        RenderObject* renderer = startContainer-&gt;renderer();
-        ASSERT(renderer);
-        if (!renderer)
-            continue;
-        const RenderStyle&amp; style = renderer-&gt;style();
-        if (style.textDecorationsInEffect() &amp; TextDecorationUnderline)
-            [attrs.get() setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
-        if (style.textDecorationsInEffect() &amp; TextDecorationLineThrough)
-            [attrs.get() setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
-        if (NSFont *font = style.font().primaryFont()-&gt;getNSFont())
-            [attrs.get() setObject:font forKey:NSFontAttributeName];
-        else
-            [attrs.get() setObject:[fontManager convertFont:WebDefaultFont() toSize:style.font().primaryFont()-&gt;platformData().size()] forKey:NSFontAttributeName];
-        if (style.visitedDependentColor(CSSPropertyColor).alpha())
-            [attrs.get() setObject:nsColor(style.visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
-        else
-            [attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
-        if (style.visitedDependentColor(CSSPropertyBackgroundColor).alpha())
-            [attrs.get() setObject:nsColor(style.visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
-        else
-            [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
-
-        [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:it.text().createNSStringWithoutCopying().get()];
-        [string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)];
-        stringLength += currentTextLength;
-    }
-
-    return [string autorelease];
-}
-
-#endif
-
-@end
-
-#if !PLATFORM(IOS)
-
-static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
-{
-    if ([URL isFileURL])
-        return [[[NSFileWrapper alloc] initWithURL:[URL URLByResolvingSymlinksInPath] options:0 error:nullptr] autorelease];
-
-    RefPtr&lt;ArchiveResource&gt; resource = dataSource-&gt;subresource(URL);
-    if (resource) {
-        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:resource-&gt;data()-&gt;createNSData().get()] autorelease];
-        NSString *filename = resource-&gt;response().suggestedFilename();
-        if (!filename || ![filename length])
-            filename = suggestedFilenameWithMIMEType(resource-&gt;url(), resource-&gt;mimeType());
-        [wrapper setPreferredFilename:filename];
-        return wrapper;
-    }
-    
-    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
-
-    NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
-    [request release];
-    
-    if (cachedResponse) {
-        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
-        [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
-        return wrapper;
-    }
-    
-    return nil;
-}
-
-static NSFileWrapper *fileWrapperForElement(Element* element)
-{
-    NSFileWrapper *wrapper = nil;
-    
-    const AtomicString&amp; attr = element-&gt;getAttribute(srcAttr);
-    if (!attr.isEmpty()) {
-        NSURL *URL = element-&gt;document().completeURL(attr);
-        if (DocumentLoader* loader = element-&gt;document().loader())
-            wrapper = fileWrapperForURL(loader, URL);
-    }
-    if (!wrapper) {
-        RenderImage* renderer = toRenderImage(element-&gt;renderer());
-        if (renderer-&gt;cachedImage() &amp;&amp; !renderer-&gt;cachedImage()-&gt;errorOccurred()) {
-            wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:(NSData *)(renderer-&gt;cachedImage()-&gt;imageForRenderer(renderer)-&gt;getTIFFRepresentation())];
-            [wrapper setPreferredFilename:@&quot;image.tiff&quot;];
-            [wrapper autorelease];
-        }
-    }
-
-    return wrapper;
-}
-
-#endif
-
-namespace WebCore {
-    
-NSAttributedString *attributedStringFromRange(Range&amp; range)
-{
-    return [WebHTMLConverter attributedStringFromRange:&amp;range];
-}
-    
-#if !PLATFORM(IOS)
-NSAttributedString *editingAttributedStringFromRange(Range&amp; range)
-{
-    return [WebHTMLConverter editingAttributedStringFromRange:&amp;range];
-}
-#endif
-    
-}
</del></span></pre>
</div>
</div>

</body>
</html>