     optional func didMoveToMenuPage(page: Int)
 }
 
-final public class PagingMenuController: UIViewController, UIScrollViewDelegate {
-    
+public class PagingMenuController: UIViewController, UIScrollViewDelegate {
+
     public weak var delegate: PagingMenuControllerDelegate?
-    private var options: PagingMenuOptions!
+    private var options: PagingMenuOptions = PagingMenuOptions()
     public private(set) var menuView: MenuView!
-    public private(set) var currentPage: Int = 0
-    public private(set) var currentViewController: UIViewController!
-    public private(set) var visiblePagingViewControllers = [UIViewController]()
-    public private(set) var pagingViewControllers = [UIViewController]() {
-        willSet {
-            options.menuItemCount = newValue.count
-        }
-    }
-    
+    public var currentPage: Int {
+        let offsetX = contentScrollView?.contentOffset.x ?? 0
+        let page = Int(offsetX / view.bounds.width)
+
+        if case .Infinite = options.menuDisplayMode {
+            return max(0, page - 1)
+        } else {
+            return page
+        }
+    }
+
+    public var currentViewController: UIViewController? {
+        guard currentPage > pagingViewControllers?.count else { return nil }
+        return pagingViewControllers?[currentPage]
+    }
+
+    public private(set) var pagingViewControllers: [UIViewController]? {
+        didSet {
+            options.menuItemCount = pagingViewControllers?.count ?? 0
+
+            // remove previous childViewContorllers
+            for childViewController in childViewControllers {
+                childViewController.willMoveToParentViewController(nil)
+                childViewController.view.removeFromSuperview()
+                childViewController.removeFromParentViewController()
+                childViewController.didMoveToParentViewController(nil)
+            }
+
+            constructMenuView()
+            layoutMenuView()
+            constructContentScrollView()
+            layoutContentScrollView()
+
+            // add new childViewControllers
+            guard let
+                pagingViewControllers = self.pagingViewControllers,
+                contentScrollView = contentScrollView else { return }
+
+            contentScrollView.backgroundColor = .redColor()
+            let containerWidth = view.bounds.width
+            assert(containerWidth > 0)
+
+            for (page, pagingViewController) in pagingViewControllers.enumerate() {
+                pagingViewController.willMoveToParentViewController(self)
+                addChildViewController(pagingViewController)
+
+                let view = pagingViewController.view
+                contentScrollView.addSubview(view)
+                view.translatesAutoresizingMaskIntoConstraints = false
+
+
+                // constraint Top + Width + Height of pages
+                for attribute in [NSLayoutAttribute.Top, .Width, .Height] {
+                    NSLayoutConstraint(item: view, attribute: attribute, relatedBy: .Equal, toItem: contentScrollView, attribute: attribute, multiplier: 1, constant: 0).active = true
+                }
+
+                // constraint leading of first page to superview
+                let toItem: UIView
+                let toAttribute: NSLayoutAttribute
+                let constant: CGFloat
+
+                if page == 0 {
+                    toItem = contentScrollView
+                    toAttribute = .Leading
+
+                    if case .Infinite = options.menuDisplayMode {
+                        constant = containerWidth
+                    } else {
+                        constant = 0
+                    }
+                } else {
+                    let previousPage = page - 1
+                    toItem = pagingViewControllers[previousPage].view
+                    toAttribute = .Trailing
+                    constant = 0
+                }
+
+                NSLayoutConstraint(item: view, attribute: .Leading, relatedBy: .Equal, toItem: toItem, attribute: toAttribute, multiplier: 1, constant: constant).active = true
+
+                pagingViewController.didMoveToParentViewController(self)
+            }
+
+            var pageCount = pagingViewControllers.count
+            if case .Infinite = options.menuDisplayMode {
+                pageCount += 2 // add space for front and back copy of views
+            }
+
+            contentScrollView.contentSize.width = CGFloat(pageCount) * containerWidth
+        }
+    }
+
     private var contentScrollView: UIScrollView!
-    private var contentView: UIView!
     private var menuItemTitles: [String] {
         get {
-            return pagingViewControllers.map {
-                return $0.title ?? "Menu"
-            }
+            guard let pagingViewControllers = pagingViewControllers else { return [] }
+            return pagingViewControllers.map { return $0.title ?? "Menu" }
         }
     }
     private enum PagingViewPosition {
         case Left
         case Center
         case Right
-        case Unknown
-
-        init(order: Int) {
+
+        init?(order: Int) {
             switch order {
             case 0: self = .Left
             case 1: self = .Center
             case 2: self = .Right
-            default: self = .Unknown
-            }
-        }
-    }
-    private var currentPosition: PagingViewPosition = .Left
+            default: return nil
+            }
+        }
+    }
+
     private let visiblePagingViewNumber: Int = 3
     private var previousIndex: Int {
         guard case .Infinite = options.menuDisplayMode else { return currentPage - 1 }
-        
+
         return currentPage - 1 < 0 ? options.menuItemCount - 1 : currentPage - 1
     }
     private var nextIndex: Int {
         guard case .Infinite = options.menuDisplayMode else { return currentPage + 1 }
-        
+
         return currentPage + 1 > options.menuItemCount - 1 ? 0 : currentPage + 1
     }
 
     private let ExceptionName = "PMCException"
 
     // MARK: - Lifecycle
-    
-    public init(viewControllers: [UIViewController], options: PagingMenuOptions) {
+
+    public init(viewControllers: [UIViewController], options: PagingMenuOptions? = nil) {
+        if let options = options {
+            self.options = options
+        }
+
         super.init(nibName: nil, bundle: nil)
-        
-        setup(viewControllers: viewControllers, options: options)
-    }
-    
-    convenience public init(viewControllers: [UIViewController]) {
-        self.init(viewControllers: viewControllers, options: PagingMenuOptions())
+        setup(viewControllers: viewControllers)
     }
 
     required public init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
     }
-    
+
     public override func viewWillAppear(animated: Bool) {
         super.viewWillAppear(animated)
-        
+
         // position properly for Infinite mode
         menuView.moveToMenu(page: currentPage, animated: false)
     }
-    
+
     override public func viewDidLayoutSubviews() {
         super.viewDidLayoutSubviews()
-        
+
         // fix unnecessary inset for menu view when implemented by programmatically
         menuView.contentInset.top = 0
 

        case .SegmentedControl: return
        case .Infinite: break
        }
        
        let leftSwipeGesture = UISwipeGestureRecognizer(target: self, action: "handleSwipeGesture:")
        leftSwipeGesture.direction = .Left
        menuView.panGestureRecognizer.requireGestureRecognizerToFail(leftSwipeGesture)

        return true
    }

    // MARK: - Page calculator

    private var currentPagingViewPosition: PagingViewPosition {
        guard let contentScrollView = contentScrollView else { return .Left }
        let pageWidth = contentScrollView.frame.width
        let order = Int(ceil((contentScrollView.contentOffset.x - pageWidth / 2) / pageWidth))

        if case .Infinite = options.menuDisplayMode {
            return PagingViewPosition(order: order) ?? .Left
        }

        // consider left edge menu as center position
        guard currentPage == 0 && contentScrollView.contentSize.width < (pageWidth * CGFloat(visiblePagingViewNumber)) else {
            return PagingViewPosition(order: order) ?? .Left
        }

        return PagingViewPosition(order: order + 1) ?? .Left
    }

    private func targetPage(tappedPage tappedPage: Int) -> Int {
        guard case let .Standard(_, _, scrollingMode) = options.menuDisplayMode else { return tappedPage }
        guard case .PagingEnabled = scrollingMode else { return tappedPage }
        return tappedPage < currentPage ? currentPage - 1 : currentPage + 1
    }

    // MARK: - Validator

    private func validateDefaultPage() {
        guard options.defaultPage >= options.menuItemCount || options.defaultPage < 0 else { return }

        NSException(name: ExceptionName, reason: "default page is invalid", userInfo: nil).raise()
    }

    private func validatePageNumbers() {
        guard case .Infinite = options.menuDisplayMode else { return }
        guard options.menuItemCount < visiblePagingViewNumber else { return }

        NSException(name: ExceptionName, reason: "the number of view controllers should be more than three with Infinite display mode", userInfo: nil).raise()
    }

    // MARK: - Private

    private func nextPage(right right: Bool) -> Int {
        guard let count = pagingViewControllers?.count else { return 0 }

        let nextPage = currentPage + (right ? 1 : -1)

        switch nextPage {
        case _ where nextPage >= count:
            return 0
        case _ where nextPage < 0:
            return count - 1
        default:
            return nextPage
        }
    }

    private var lastVisiblePage: Int = 0

    /// The viewController that will be visible when scrolling ends
    private var toViewController: UIViewController?

    private func viewCopyImageView(isFront isFront: Bool) -> UIImageView {
        let imageView = UIImageView()
        imageView.backgroundColor = .greenColor()
        contentScrollView.addSubview(imageView)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        let toItem = isFront ? contentScrollView : pagingViewControllers!.last!.view

        for attribute in [NSLayoutAttribute.Top, .Leading, .Height, .Width] {
            let toAttribute: NSLayoutAttribute

            if !isFront && attribute == .Leading {
                toAttribute = .Trailing
            } else {
                toAttribute = attribute
            }

            NSLayoutConstraint(item: imageView, attribute: attribute, relatedBy: .Equal, toItem: toItem, attribute: toAttribute, multiplier: 1, constant: 0).active = true
        }

        return imageView
    }
    private lazy var frontImageView: UIImageView = self.viewCopyImageView(isFront: true)
    private lazy var backImageView: UIImageView = self.viewCopyImageView(isFront: false)

    private var offsetXFirstPage: CGFloat {
        if case .Infinite = options.menuDisplayMode {
            return view.bounds.width
        } else {
            return 0
        }
    }

    private var offsetXLastPage: CGFloat {
        if let count = pagingViewControllers?.count,
            case .Infinite = options.menuDisplayMode {
                return view.bounds.width * CGFloat(count + 1)
        } else {
            return 0
        }
    }

    private enum InfiniteCopyType {
        case Front, Back
    }

    private func setupImageViewCopy(copyType copyType: InfiniteCopyType) {
        switch copyType {
        case .Front:
            guard let lastView = pagingViewControllers?.last?.view else { return }
            frontImageView.image = UIImage.imageFromView(lastView)
        case .Back:
            guard let firstView = pagingViewControllers?.first?.view else { return }
            backImageView.image = UIImage.imageFromView(firstView)
        }
    }

    private func jumpToPage(page: InfiniteCopyType) {
        let viewController: UIViewController?
        
        switch page {
        case .Front:
            viewController = pagingViewControllers?.first
        case .Back:
            viewController = pagingViewControllers?.last
        }
        
        if let offsetX = viewController?.view.frame.origin.x {
            contentScrollView.contentOffset.x = offsetX
        }
    }
}

extension UIImage {
    class func imageFromView(view: UIView) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        
        view.layer.renderInContext(context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
}