 //        
 //    }
 
+    // TODO: how to handle clean up for reuse
     final func cleanUpForReuse() {
 
         // do clean up

                self.addConstraint(constraint)
            }
        }
        return subcomponents
    }
}



import Foundation

protocol Composable {
    func compositeSubcomponents(components: [ComponentTarget], layout: Layout)
}

extension Composable where Self: UIView {
    func compositeSubcomponents(components: [ComponentTarget], layout: Layout) {

        // remove components which do not exist anymore
        for subview in self.subviews {
            if let oldComponent = subview.configuration where !components.contains(oldComponent) {
                subview.cleanUpForReuse() // TODO: clean layout maybe
                subview.removeFromSuperview()
            }
        }

        // filter components already exist
        let filteredComponents = components.filter { (component) -> Bool in
            if let subcomponents = self.configuration?.components where !subcomponents.contains(component) {
                return true
            }
            return false
        }

        let views = filteredComponents.flatMap { (component) -> UIView? in
            var view: UIView? = nil;

            if let nibName = component.nibName,
                let componentView = NSBundle.mainBundle().loadNibNamed(nibName, owner: nil, options: nil).first as? UIView {
                    view = componentView
            } else if let componentView = ComponentFactory.componentViewFromClass(component.targetClass) {
                view = componentView
            }

            if let view = view {
                view.isRoot = false
                view.configuration = component
                self.addSubview(view)
            }

            return view
        }

        var viewsDictionary = [String: UIView]()
        for subview in self.subviews {
            if let name = subview.name() {
                viewsDictionary[name] = subview
            }
        }

        // TODO: apply diff of layout
        var shouldApplyLayout = false

        // Layout each component view with auto layout visual format language from configuration.
        for format in layout.formats {
