         return str
     }
     
+    /// Creates an empty `SQLStatement`.
     public init() {
         segments = []
     }
     
+    /// Creates a `SQLStatement` consisting of a single segment of raw SQL.
     public init(raw sql: String) {
         segments = [.raw(sql)]
     }
     
+    /// Creates a `SQLStatement` consisting of a single parameter which must be 
+    /// passed by placeholder or escaped.
     public init(parameter value: SQLValue?) {
         segments = [.parameter(value)]
     }
     
+    /// Creates a `SQLStatement` from a `SQLStatementConvertible` instance.
     public init(_ convertible: SQLStatementConvertible) {
         self = convertible.sqlStatement
     }
     
+    /// Creates a `SQLStatement` from another `SQLStatement`. This can be used to 
+    /// force Swift to treat a context-free string literal as a `SQLStatement`:
+    /// 
+    ///     let sql = SQLStatement("SELECT * FROM users")
     public init(_ statement: SQLStatement) {
         self = statement
     }
     
+    /// Appends the segments in the other `SQLStatement` or convertible instance to 
+    /// this `SQLStatement`.
     public mutating func append(_ other: SQLStatementConvertible) {
         segments += SQLStatement(other).segments
     }
     
+    /// Converts the `SQLStatement` into raw SQL in a `String`, using the 
+    /// `mapping` function to convert parameters into raw SQL.
+    /// 
+    /// `rawSQLByReplacingParameters(with:)` is primarily a utility method for 
+    /// `SQLCient`s to use when implementing support for `execute(_:)`, 
+    /// `execute(_:returningID:as:)`, and `query(_:)`. The `mapping` function 
+    /// should be used to either escape parameters:
+    /// 
+    ///     let rawSQL = sql.rawSQLByReplacingParameters(with: myEscapingFunction)
+    ///
+    /// Or to bind them to the query and return appropriate placeholder syntax:
+    /// 
+    ///     var parameters: [String?] = []
+    ///     let rawSQL = sql.rawSQLByReplacingParameters { value in 
+    ///         parameters.append(value.sqlLiteral)
+    ///         return "$" + String(parameters.count)
+    ///     }
     public func rawSQLByReplacingParameters(with mapping: (_ value: SQLValue?) throws -> String) rethrows -> String {
         return try segments.map {
             try $0.replacingParameter(with: mapping)

}

extension Collection where Iterator.Element: SQLStatementConvertible, SubSequence.Iterator.Element: SQLStatementConvertible {
    func joined(separator: SQLStatementConvertible) -> SQLStatement {
        let sep = SQLStatement(separator)
        guard let first = self.first else {

}

extension SQLStatement: Hashable {
    /// Compares two `SQLStatement`s.
    /// 
    /// - Note: For the purpose of this comparison, all `SQLValue`s which are not 
    ///          `Hashable` are considered equal to each other.
    public static func == (lhs: SQLStatement, rhs: SQLStatement) -> Bool {
        guard lhs.segments.count == rhs.segments.count else {
            return false
