     }
 }
 
-extension UIView {
-
-    func inflateAddAndConstrainIfPossible() {
+public protocol ContextPreloadable {
+
+    func contextPreload()
+}
+
+extension UIViewController: ContextPreloadable {
+
+    public func contextPreload() {
+        guard let contextAware = self as? ContextAware where contextAware.contextToken == nil else { return }
+        self.loadViewIfNeeded()
+    }
+}
+
+extension UIView: ContextPreloadable {
+
+    public func contextPreload() {
+        guard let contextAware = self as? ContextAware where contextAware.contextToken == nil else { return }
         guard let inflatable = self as? UINibViewInflatable else { return }
         let view = inflatable.inflateView()
         self.addAndConstrainView(view)

    // MARK: Wrapping

    public func wrap<Object>(obj: Object) -> Object {
        if let contextAwareContainer = obj as? ContextAwareContainer {
            for child in contextAwareContainer.childObjects {
                self.wrap(child)
            }
        }
        if let viewController = obj as? UIViewController {
            viewController.loadViewIfNeeded()
            self.wrap(viewController.view)
            self.setupContextAwareIfNecessary(viewController)
        } else if let view = obj as? UIView {
            if view is ContextAware {
                view.inflateAddAndConstrainIfPossible()
            }
            self.setupContextAwareIfNecessary(view)
        } else {
            self.setupContextAwareIfNecessary(obj)
        }
        return obj
    }
}



public extension ContextAware {

    public var context: Context {
        return self.contextToken!.context
    }

    public func contextWrap<Object>(obj: Object) -> Object {
        return self.context.wrap(obj)
    }

    public func newViewController<ViewController: UIViewController>() -> ViewController {
        return self.context.newViewController()
    }

    public func newView<View: UIView>() -> View {
        return self.context.newView()
    }
}

