     return ", ".join(contents.map {"".join($0.map { String(reflecting: $0) })})
   }
 }
+
+public func ==<T>(lhs: Trie<T>, rhs: Trie<T>) -> Bool {
+  return lhs.endHere == rhs.endHere && lhs.children == rhs.children
+}
+
+extension Trie : Equatable {}
 
 // MARK: Init
 

    (seq: S) {
      remove(seq.generate())
  }

  public mutating func unionInPlace(with: Trie<Element>) {
    for (head, child) in with.children {
      children[head]?.unionInPlace(child) ?? {children[head] = child}()
    }
  }

  public mutating func exclusiveOrInPlace<
    S : SequenceType where
    S.Generator.Element : SequenceType,
    S.Generator.Element.Generator.Element == Element
    >(sequence: S) {
      for toRemove in sequence { remove(toRemove) }
  }

  public func intersect<
    S : SequenceType where
    S.Generator.Element : SequenceType,
    S.Generator.Element.Generator.Element == Element
    >(sequence: S) -> Trie<Element> {
      var ret = Trie()
      for element in sequence where contains(element) { ret.insert(element) }
      return ret
  }

  public func isDisjointWith<
    S : SequenceType where
    S.Generator.Element : SequenceType,
    S.Generator.Element.Generator.Element == Element
    >(sequence: S) -> Bool { return !sequence.contains(self.contains) }
}

// MARK: More effecient implementations

  }
}

extension Trie {
  private mutating func remove
    <G : GeneratorType where G.Element == Element>
    (var gen: G) {
