 class ProjectDetailController: UIViewController {
 
   let project: Project
+
+  lazy var scrollView: UIScrollView = {
+    let scrollView = UIScrollView(frame: CGRectZero)
+    scrollView.alwaysBounceVertical = true
+
+    return scrollView
+    }()
 
   lazy var imageView: UIImageView = {
     let imageView = UIImageView()

  func setupConstrains() {
    infoLabel.sizeToFit()

    constrain(imageView, infoLabel, button) { imageView, infoLabel, button in
      let superview = imageView.superview!

      imageView.top == superview.top + 79
      imageView.leading == superview.leading + 30
      imageView.trailing == superview.trailing - 30
      imageView.height == 150

      infoLabel.top == imageView.bottom + 30
      infoLabel.leading == imageView.leading
      infoLabel.trailing == imageView.trailing

      button.top == infoLabel.bottom + 50
      button.centerX == superview.centerX
      button.width == 200
      button.height == 50
    }
  }

  // MARK: - KVO

  override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    guard let imageView = object as? UIImageView,
      image = imageView.image
      where keyPath == "image"
      else { return }

    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) {
      let (textColor, _, backgroundColor, _) = image.colors(imageView.frame.size)
      dispatch_async(dispatch_get_main_queue()) { [weak self] in
        guard let backgroundColor = backgroundColor,
          textColor = textColor
          else { return }

        self?.view.backgroundColor = backgroundColor
        self?.infoLabel.textColor = textColor
      }
    }
  }

  // MARK: - Actions

    title = project.name
    view.backgroundColor = UIColor.whiteColor()

    view.addSubview(scrollView)
    [imageView, infoLabel, button].forEach {
      scrollView.addSubview($0)
    }

    imageView.setImage(project.imageURL)
    infoLabel.text = project.info
