 prefix public func !(left: NSPredicate) -> NSCompoundPredicate {
     return NSCompoundPredicate(type: NSCompoundPredicateType.NotPredicateType, subpredicates: [left])
 }
-
-// MARK: - NSExpression - private extensions
-
-private func ==(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.EqualToPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func !=(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.NotEqualToPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func >(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.GreaterThanPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func >=(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.GreaterThanOrEqualToPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func <(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.LessThanPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func <=(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.LessThanOrEqualToPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func ~=(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.LikePredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}
-
-private func <<(left: NSExpression, right: NSExpression) -> NSComparisonPredicate {
-    return NSComparisonPredicate(leftExpression: left, rightExpression: right, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.InPredicateOperatorType, options: NSComparisonPredicateOptions(0))
-}

    
    private func expressionForValue(value: T) -> NSExpression {
        // TODO: Find a cleaner implementation
        if let value = value as? NSObject {
            return NSExpression(forConstantValue: value as NSObject)
        }
        
        if sizeof(value.dynamicType) == sizeof(uintptr_t) {
            let value = unsafeBitCast(value, Optional<NSObject>.self)
            if let value = value {
                return NSExpression(forConstantValue: value)
            }
        }
        
        let value = unsafeBitCast(value, Optional<String>.self)
        if let value = value {
            return NSExpression(forConstantValue: value)
        }
        
        return NSExpression(forConstantValue: NSNull())
    }
    
}

// MARK: - Equatable protocol

    
}

// MARK: - Attribute methods

extension Attribute {

    public func matches(regularExpressionString: String) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: NSExpression(forConstantValue: regularExpressionString),
            modifier: .DirectPredicateModifier,
            type: .MatchesPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

    public func contains(value: T) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: self.expressionForValue(value),
            modifier: .DirectPredicateModifier,
            type: .ContainsPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }
    
    public func contains(otherAttribute: Attribute<T>) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: otherAttribute.expression,
            modifier: .DirectPredicateModifier,
            type: .ContainsPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

    public func beginsWith(value: T) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: self.expressionForValue(value),
            modifier: .DirectPredicateModifier,
            type: .BeginsWithPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

    public func beginsWith(otherAttribute: Attribute<T>) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: otherAttribute.expression,
            modifier: .DirectPredicateModifier,
            type: .BeginsWithPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

    public func endsWith(value: T) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: self.expressionForValue(value),
            modifier: .DirectPredicateModifier,
            type: .EndsWithPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

    public func endsWith(otherAttribute: Attribute<T>) -> NSComparisonPredicate {
        return NSComparisonPredicate(
            leftExpression: self.expression,
            rightExpression: otherAttribute.expression,
            modifier: .DirectPredicateModifier,
            type: .EndsWithPredicateOperatorType,
            options: self.comparisonPredicateOptions()
        )
    }

}


// MARK: - Attribute operators

public func ==<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .EqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func ==<T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .EqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func !=<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .NotEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func !=<T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .NotEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func ><T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .GreaterThanPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func ><T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .GreaterThanPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func >=<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .GreaterThanOrEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func >=<T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .GreaterThanOrEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .LessThanPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <<T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .LessThanPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <=<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .LessThanOrEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <=<T>(left: Attribute<T>, right: Attribute<T>) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: right.expression,
        modifier: .DirectPredicateModifier,
        type: .LessThanOrEqualToPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func ~=<T>(left: Attribute<T>, right: T) -> NSComparisonPredicate {
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: left.expressionForValue(right),
        modifier: .DirectPredicateModifier,
        type: .LikePredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <<<T>(left: Attribute<T>, right: [T]) -> NSComparisonPredicate {
    let rightValue = map(right) { $0 as! AnyObject }
    let rightExpression = NSExpression(forConstantValue: rightValue)
    
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: rightExpression,
        modifier: .DirectPredicateModifier,
        type: .InPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

public func <<<T>(left: Attribute<T>, right: Range<T>) -> NSComparisonPredicate {
    let rightValue = [right.startIndex as! AnyObject, right.endIndex as! AnyObject] as NSArray
    let rightExpression = NSExpression(forConstantValue: rightValue)
    
    return NSComparisonPredicate(
        leftExpression: left.expression,
        rightExpression: rightExpression,
        modifier: .DirectPredicateModifier,
        type: .BetweenPredicateOperatorType,
        options: left.comparisonPredicateOptions()
    )
}

prefix public func !(left: Attribute<Bool>) -> NSComparisonPredicate {
    return left == false
}

// MARK: - NSPredicate extensions

public func &&(left: NSPredicate, right: NSPredicate) -> NSCompoundPredicate {
    return NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: [left, right])
