diff --git a/src/Data/HTML2CSS.hs b/src/Data/HTML2CSS.hs
--- a/src/Data/HTML2CSS.hs
+++ b/src/Data/HTML2CSS.hs
@@ -1,21 +1,21 @@
 {-# LANGUAGE OverloadedStrings #-}
 -- | Bindings from `xml-conduit` to `haskell-stylist`.
 module Data.HTML2CSS(
-        externalStyles, externalStylesForURL, internalStyles, internalStylesForURL, -- legacy
         html2css, cssPriorityAgent, cssPriorityUser, cssPriorityAuthor, -- parsing
-        traverseStyles, traversePrepopulatedStyles, traverseStyles', elToStylish -- application
+        preorder, el2styletree, els2stylist, el2stylist, stylize, stylize', stylizeEl -- application
     ) where
 
 import qualified Data.List as L
 import qualified Data.Map as M
 import qualified Data.HashMap.Strict as HM
 import qualified Data.Text as Txt
-import Data.Maybe (fromMaybe)
+import Data.Maybe
 
 import qualified Text.XML as XML
 import Data.CSS.Syntax.StyleSheet
 import Data.CSS.Style
-import Data.CSS.Syntax.Tokens (tokenize)
+import Data.CSS.StyleTree
+import Data.CSS.Syntax.Tokens
 import Data.CSS.Preprocessor.Conditions
 import qualified Data.CSS.Preprocessor.Conditions.Expr as Query
 import Network.URI
@@ -53,43 +53,7 @@
     | Just text <- "media" `M.lookup` attrs = Query.parse' (tokenize text) []
     | otherwise = []
 
----- Parsing (legacy)
--- | LEGACY: Extract relative links to external stylesheets.
-externalStyles :: StyleSheet s => s -> (M.Map XML.Name Txt.Text -> Bool) ->
-        XML.Element -> (URI -> IO Txt.Text) -> IO s
-externalStyles a b c d = externalStylesForURL a b c nullURI d
--- | LEGACY: Extract absolutized links to external stylesheets.
-externalStylesForURL stylesheet testMedia html base loadURL = do
-    css <- externalStyles' testMedia html base loadURL
-    return $ foldl (\a (b, c) -> parseForURL a b c) (cssPriorityAuthor stylesheet) css
-externalStyles' testMedia html base loadURL = go $ linkedStyles' testMedia html
-    where -- TODO parallelise loads
-        go (link:links) = do
-            response <- loadURL $ relativeTo link base
-            rest <- go links
-            return $ (relativeTo link base, response) : rest
-        go [] = return []
 
-linkedStyles' testMedia (XML.Element (XML.Name "link" _ _) attrs _)
-    | Just link <- "href" `M.lookup` attrs,
-        Just "stylesheet" <- "rel" `M.lookup` attrs,
-        testMedia attrs,
-        Just uri <- parseURIReference $ Txt.unpack link = [uri]
-linkedStyles' testMedia (XML.Element _ _ children) =
-    concat [linkedStyles' testMedia el | XML.NodeElement el <- children]
-
--- | LEGACY: Extract internally embedded CSS stylesheets.
-internalStyles a b c = internalStylesForURL a b nullURI c
--- | LEGACY: Extract internally embedded CSS stylesheets, with absolutized URLs.
-internalStylesForURL testMedia stylesheet base html =
-    foldl (\s -> parseForURL s base) (cssPriorityAuthor stylesheet) $
-        internalStyles' testMedia html
-internalStyles' testMedia (XML.Element (XML.Name "style"_ _) attrs children)
-    | testMedia attrs = [strContent children]
-internalStyles' testMedia (XML.Element _ _ children) =
-    concat [internalStyles' testMedia el | XML.NodeElement el <- children]
-
-
 strContent :: [XML.Node] -> Txt.Text
 strContent (XML.NodeContent text : rest) = text `Txt.append` strContent rest
 -- We do want to read in comments for CSS, just not for display.
@@ -100,62 +64,50 @@
 strContent [] = ""
 
 ---- Styling
--- | Converts a parsed XML or HTML document to a specified style tree type.
-traverseStyles :: PropertyParser s => (s -> [o] -> o) -> (s -> Txt.Text -> o) ->
-        QueryableStyleSheet s -> XML.Element -> o
-traverseStyles = traverseStyles' Nothing temp Nothing (\x y -> Nothing)
--- | Converts a parsed XML or HTML document to a specified style tree type,
--- with a routine to compute alternative contents based on the raw element or computed styles.
-traversePrepopulatedStyles :: PropertyParser s => (s -> XML.Element -> Maybe [o]) ->
-        (s -> [o] -> o) -> (s -> Txt.Text -> o) -> QueryableStyleSheet s -> XML.Element -> o
-traversePrepopulatedStyles = traverseStyles' Nothing temp Nothing
--- | Full routine for converting a parsed XML or HTML document to a specified style tree type.
-traverseStyles' :: PropertyParser s => Maybe Element -> s -> Maybe Element ->
-        (s -> XML.Element -> Maybe [o]) -> (s -> [o] -> o) -> (s -> Txt.Text -> o) ->
-        QueryableStyleSheet s -> XML.Element -> o
-traverseStyles' parent parentStyle previous prepopulate builder textBuilder stylesheet el@(
-        XML.Element _ attrs children
-    ) = builder style traverseChildren
-    where
-        stylishEl = elToStylish el parent previous
-        maybeEl = Just stylishEl
-        rules = queryRules stylesheet stylishEl
-        style = cascade' (HM.lookupDefault [] "" rules) overrides parentStyle
-        overrides | Just styleAttr <- "style" `M.lookup` attrs =
-                fst $ parseProperties' $ tokenize styleAttr
-            | otherwise = []
 
-        traverseChildren = traversePsuedo' "before" ++
-                fromMaybe (traverseChildren' Nothing children) (prepopulate style el) ++
-                traversePsuedo' "after"
-        traversePsuedo' psuedo = traversePsuedo rules psuedo style builder
-        traverseChildren' prev (XML.NodeContent txt:nodes) =
-            textBuilder style txt : traverseChildren' prev nodes
-        traverseChildren' prev (XML.NodeElement el:nodes) =
-            traverseStyles' maybeEl style prev prepopulate builder textBuilder stylesheet el :
-                traverseChildren' (Just $ elToStylish el maybeEl prev) nodes
-        traverseChildren' prev (_:nodes) = traverseChildren' prev nodes
-        traverseChildren' _ [] = []
-traversePsuedo rules psuedo parentStyle builder
-    | Just rules' <- HM.lookup psuedo rules = [builder (cascade' rules' [] parentStyle) []]
-    | otherwise = []
+preorder :: (Maybe b -> Maybe b -> a -> b) -> StyleTree a -> StyleTree b
+preorder cb self = head $ preorder' cb Nothing Nothing [self]
+preorder' :: (Maybe b -> Maybe b -> a -> b) ->
+        Maybe b -> Maybe b -> [StyleTree a] -> [StyleTree b]
+preorder' cb parent previous (self:sibs) = let self' = cb parent previous $ style self
+        in StyleTree self' (preorder' cb (Just self') Nothing $ children self) :
+            preorder' cb parent (Just self') sibs
+preorder' _ _ _ [] = []
 
--- | Converts a xml-conduit Element to a stylist Element.
-elToStylish (XML.Element (XML.Name name ns _) attrs _) parent previous =
+el2styletree el = StyleTree (Left el) $ mapMaybe node2styletree $ XML.elementNodes el
+node2styletree (XML.NodeElement el) = Just $ el2styletree el
+node2styletree (XML.NodeContent txt) = Just $ StyleTree (Right [("content", [String txt])]) []
+node2styletree _ = Nothing
+
+previous' (Just ElementNode {name = "", previous = prev'}) = previous' prev'
+previous' prev' = prev'
+
+els2stylist = preorder els2stylist'
+els2stylist' parent previous (Left (XML.Element (XML.Name name ns _) attrs _)) =
     ElementNode {
-        name = name,
-        namespace = fromMaybe "" ns,
+        name = name, namespace = fromMaybe "" ns,
         attributes = L.sort [
-            Attribute name (fromMaybe "" ns) (Txt.unpack value)
-            | (XML.Name name ns _, value) <- M.toList attrs
+            Attribute n (fromMaybe "" ns) $ Txt.unpack v | (XML.Name n ns _, v) <- M.toList attrs
         ],
-        parent = parent,
-        previous = previous
+        parent = parent, previous = previous' previous
     }
-addPsuedoclasses el psuedoclasses
-    | (Attribute "" "" value : attrs) <- attributes el = el {
-            attributes = Attribute "" "" (psuedoclasses ++ value) : attrs
-        }
-    | otherwise = el {
-            attributes = Attribute "" "" psuedoclasses : attributes el
-        }
+els2stylist' parent previous (Right attrs) = ElementNode {
+        name = "", namespace = "",
+        attributes = [Attribute "style" "" $ Txt.unpack $ Txt.concat style],
+        parent = parent, previous = previous' previous
+    } where style = concat [[prop, ": ", serialize v, "; "] | (prop, v) <- attrs]
+
+el2stylist = els2stylist . el2styletree
+
+stylize :: PropertyParser s => QueryableStyleSheet s -> StyleTree Element -> StyleTree [(Txt.Text, s)]
+stylize = preorder . stylize'
+stylize' :: PropertyParser s => QueryableStyleSheet s -> Maybe [(Txt.Text, s)] -> Maybe [(Txt.Text, s)] ->
+        Element -> [(Txt.Text, s)]
+stylize' stylesheet parent _ el = [
+        (k, if Txt.null k then base else cascade' v [] base)
+        | (k, v) <- HM.toList $ queryRules stylesheet el
+    ] where
+        base = cascade stylesheet el overrides $ fromMaybe temp $ lookup "" =<< parent
+        overrides = concat [fst $ parseProperties' $ tokenize $ Txt.pack val
+            | Attribute "style" _ val <- attributes el]
+stylizeEl stylesheet = stylize stylesheet . el2stylist
diff --git a/xml-conduit-stylist.cabal b/xml-conduit-stylist.cabal
--- a/xml-conduit-stylist.cabal
+++ b/xml-conduit-stylist.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             1.2.0.0
+version:             2.0.0.0
 
 -- A short (one-line) description of the package.
 synopsis:            Bridge between xml-conduit/html-conduit and stylist
