 }
 
 /**
-Assign a property of a view equal to that property on another view. Useful for things such as settings the top of a view equal to the top of another view.
+Assign a property of a `Swiftlyable` equal to that property on another `Swiftlyable`. Useful for things such as settings the top of a view equal to the top of another view.
 
 - parameter left:  Layout property to assign
 - parameter right: View to equal
 
 - returns: A Swiftly object representing the desired constraint
 */
-public func ==(left: Swiftly, right: AnyObject) -> Swiftly {
+public func ==(left: Swiftly, right: Swiftlyable) -> Swiftly {
     var result = left
     result.toItem = right
     return result
 }
 
 /**
-Assign a property of a view equal to a constant. Useful for things such as settings the top of a view equal to the top of another view.
+Assign a property of a `Swiftlyable` equal to a constant. Useful for things such as settings the top of a view equal to the top of another view.
 
 - parameter left:  Layout property to assign
 - parameter right: Constant to assign


import UIKit

public extension Array where Element : UIView {

    /**
    Apply an array of Swiftly objects to an array of views. This is appended to any existing constraints.

    - parameter layoutArray: The layout(s) to apply.

    - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
    */
    internal func applyLayout(layoutArray: [Swiftly]) -> [NSLayoutConstraint] {
        var constraints = [NSLayoutConstraint]()

        for view in self {
            constraints += view.applyLayout(layoutArray: layoutArray)
        }

        return constraints
    }

    /**
    Apply an array of Swiftly objects to an array of views. The constraints are not applied to the first view in the array (since it has no previous item). This is appended to any existing constraints.

    - parameter callback: A closure used to define the constraints. A previousView argument is passed to allow for distributing views.

    - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
    */
    func applyLayoutWithPreviousView(_ callback: @noescape (_ previousView: UIView) -> [Swiftly]) -> [NSLayoutConstraint] {
        var constraints = [NSLayoutConstraint]()

        var previousView: UIView?
        for view in self {
            if let previousView = previousView {
                let swiftly = callback(previousView)
                constraints += view.applyLayout(layoutArray: swiftly)
            }

            previousView = view
        }

        return constraints
    }

    /**
    Apply a variadic list of Swiftly objects to an array of views. This is appended to any existing constraints.

    - parameter layout: The layout(s) to apply.

    - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
    */
    func applyLayout(_ layout: Swiftly...) -> [NSLayoutConstraint] {
        return applyLayout(layoutArray: layout)
    }

}

@available(iOS, introduced: 9.0)
public extension Array where Element : UILayoutGuide {

    /**
     Apply an array of Swiftly objects to an array of layout guides. This is appended to any existing constraints.

     - parameter layoutArray: The layout(s) to apply.

     - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
     */
    internal func applyLayout(layoutArray: [Swiftly]) -> [NSLayoutConstraint] {
        var constraints = [NSLayoutConstraint]()

        for view in self {
            constraints += view.applyLayout(layoutArray: layoutArray)
        }

        return constraints
    }

    /**
     Apply a variadic list of Swiftly objects to an array of layout guides. This is appended to any existing constraints.

     - parameter layout: The layout(s) to apply.

     - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
     */
    func applyLayout(_ layout: Swiftly...) -> [NSLayoutConstraint] {
        return applyLayout(layoutArray: layout)
    }
    
}

public extension UIView {

    /**
    Apply an array of Swiftly objects to a view. This is appended to any existing constraints.

    - parameter layoutArray: The layout(s) to apply.

    - returns: An array of constraints that represent the applied layout. This can be used to dynamically enable / disable a given layout.
    */
    internal func applyLayout(layoutArray: [Swiftly]) -> [NSLayoutConstraint] {
        guard let superview = superview else {
            fatalError("You must assign a superview before applying a layout")
        }

        translatesAutoresizingMaskIntoConstraints = false

        var constraints = [NSLayoutConstraint]()

        for l in layoutArray {
            let attributes: [NSLayoutAttribute]
            if let attrs = l.attributes {
                attributes = attrs

    var otherAttributes: [NSLayoutAttribute]?
    var multiplier: CGFloat
    var constant: CGFloat
    var toItem: Swiftlyable?
    var priority: UILayoutPriority?

    init(_ a: NSLayoutAttribute? = nil, attributes atts: [NSLayoutAttribute]? = nil, relatedBy r: NSLayoutRelation? = .equal, toItem ti: Swiftlyable? = nil, otherAttribute oa: NSLayoutAttribute? = nil, otherAttributes otherAtts: [NSLayoutAttribute]? = nil, multiplier m: CGFloat = 1, constant c: CGFloat = 0) {
        attribute = a
        attributes = atts
        relatedBy = r
