public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var commitsElement     = new ButtonElement("Commits", Octicon.GitCommit.ToImage());
            var filesElement       = new ButtonElement("Files Changed", Octicon.Diff.ToImage());
            var mergeButton        = new StringElement("Merge", Octicon.GitMerge.ToImage());
            var pullRequestSection = new Section {
                commitsElement, filesElement, mergeButton
            };

            OnActivation(d => {
                var commitsObs = this.WhenAnyValue(x => x.ViewModel.PullRequest.Commits);
                d(commitsElement.BindValue(commitsObs));
                d(commitsElement.BindCommand(ViewModel.GoToCommitsCommand));
                d(commitsElement.BindDisclosure(commitsObs.Select(x => x > 0)));

                var filesObs = this.WhenAnyValue(x => x.ViewModel.PullRequest.ChangedFiles);
                d(filesElement.BindValue(filesObs));
                d(filesElement.BindCommand(ViewModel.GoToFilesCommand));
                d(filesElement.BindDisclosure(filesObs.Select(x => x > 0)));

                d(mergeButton.Clicked.SubscribeSafe(_ => {
                    if (!ViewModel.PullRequest.Merged && ViewModel.CanMerge && ViewModel.PullRequest.State == Octokit.ItemState.Open)
                    {
                        PromptForCommitMessage();
                    }
                }));

                d(this.WhenAnyValue(x => x.ViewModel.PullRequest.Merged, x => x.ViewModel.CanMerge, x => x.ViewModel.PullRequest.State)
                  .Subscribe(x => {
                    if (x.Item1)
                    {
                        mergeButton.Caption        = "Merged";
                        mergeButton.SelectionStyle = UITableViewCellSelectionStyle.None;
                        mergeButton.Accessory      = UITableViewCellAccessory.Checkmark;
                    }
                    else if (!x.Item1 && x.Item2 && x.Item3 == Octokit.ItemState.Open)
                    {
                        mergeButton.Caption        = "Merge";
                        mergeButton.SelectionStyle = UITableViewCellSelectionStyle.Blue;
                        mergeButton.Accessory      = UITableViewCellAccessory.DisclosureIndicator;
                    }
                    else
                    {
                        mergeButton.Caption        = "Not Merged";
                        mergeButton.SelectionStyle = UITableViewCellSelectionStyle.None;
                        mergeButton.Accessory      = UITableViewCellAccessory.None;
                    }
                }));
            });

            Root.Insert(Root.Count - 1, pullRequestSection);
        }
        protected BaseIssueViewController()
        {
            CommentsElement    = new HtmlElement("comments");
            DescriptionElement = new HtmlElement("description");

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.2f)))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsClosed))
            .Switch()
            .Subscribe(x =>
            {
                HeaderView.SubImageView.TintColor = x ? UIColor.FromRGB(0xbd, 0x2c, 0) : UIColor.FromRGB(0x6c, 0xc6, 0x44);
                HeaderView.SetSubImage((x ? Octicon.IssueClosed :Octicon.IssueOpened).ToImage());
            });

            MilestoneElement = new ButtonElement("Milestone", Octicon.Milestone.ToImage());
            this.WhenAnyValue(x => x.ViewModel.AssignedMilestone)
            .Select(x => x == null ? "No Milestone" : x.Title)
            .Subscribe(x => MilestoneElement.Value = x);

            AssigneeElement = new ButtonElement("Assigned", Octicon.Person.ToImage());
            this.WhenAnyValue(x => x.ViewModel.AssignedUser)
            .Select(x => x == null ? "Unassigned" : x.Login)
            .Subscribe(x => AssigneeElement.Value = x);

            LabelsElement = new ButtonElement("Labels", Octicon.Tag.ToImage());
            this.WhenAnyValue(x => x.ViewModel.AssignedLabels)
            .Select(x => (x == null || x.Count == 0) ? "None" : string.Join(",", x.Select(y => y.Name)))
            .Subscribe(x => LabelsElement.Value = x);

            DetailsSection.Add(MilestoneElement);
            DetailsSection.Add(AssigneeElement);
            DetailsSection.Add(LabelsElement);

            this.WhenAnyValue(x => x.ViewModel.Avatar)
            .SubscribeSafe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown));

            this.WhenAnyValue(x => x.ViewModel.Issue)
            .IsNotNull()
            .Subscribe(x => {
                HeaderView.Text    = x.Title;
                HeaderView.SubText = x.UpdatedAt.HasValue ?
                                     ("Updated " + x.UpdatedAt.Value.UtcDateTime.Humanize()) :
                                     ("Created " + x.CreatedAt.UtcDateTime.Humanize());
                RefreshHeaderView();
            });

            this.WhenAnyValue(x => x.ViewModel.MarkdownDescription)
            .Subscribe(x =>
            {
                if (string.IsNullOrEmpty(x))
                {
                    DetailsSection.Remove(DescriptionElement);
                }
                else
                {
                    var model    = new DescriptionModel(x, (int)UIFont.PreferredSubheadline.PointSize);
                    var markdown = new MarkdownView {
                        Model = model
                    };
                    var html = markdown.GenerateString();
                    DescriptionElement.Value = html;

                    if (!DetailsSection.Contains(DescriptionElement))
                    {
                        DetailsSection.Insert(0, UITableViewRowAnimation.Fade, DescriptionElement);
                    }
                }
            });

            var footerButton = new TableFooterButton("Add Comment");

            CommentsSection.FooterView = footerButton;

            this.WhenAnyValue(x => x.ViewModel.Events)
            .Select(x => x.Changed)
            .Switch()
            .Select(x => ViewModel.Events)
            .Subscribe(events =>
            {
                var comments = events.Select(x =>
                {
                    var body    = string.Empty;
                    var comment = x as IssueCommentItemViewModel;
                    var @event  = x as IssueEventItemViewModel;

                    if (comment != null)
                    {
                        body = comment.Comment;
                    }
                    else if (@event != null)
                    {
                        body = CreateEventBody(@event.EventInfo, @event.Commit);
                    }

                    return(new Comment(x.AvatarUrl.ToUri(), x.Actor, body, x.CreatedAt.Humanize()));
                })
                               .Where(x => !string.IsNullOrEmpty(x.Body))
                               .ToList();

                if (comments.Count > 0)
                {
                    var commentModel = new CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                    var razorView    = new CommentsView {
                        Model = commentModel
                    };
                    var html = razorView.GenerateString();
                    CommentsElement.Value = html;

                    if (!CommentsSection.Contains(CommentsElement))
                    {
                        CommentsSection.Insert(0, UITableViewRowAnimation.Fade, CommentsElement);
                    }
                }
                else
                {
                    CommentsSection.Remove(CommentsElement);
                }
            });

            var commentsButton     = SplitButton.AddButton("Comments", "-");
            var participantsButton = SplitButton.AddButton("Participants", "-");

            this.WhenAnyValue(x => x.ViewModel.CommentCount)
            .Subscribe(x => commentsButton.Text = x.ToString());

            this.WhenAnyValue(x => x.ViewModel.Participants)
            .Subscribe(x => participantsButton.Text = x.ToString());

            this.WhenAnyObservable(x => x.ViewModel.CommentAdded)
            .Select(_ => Appeared.Take(1))
            .Switch()
            .Delay(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler)
            .SubscribeSafe(_ => TableView.SetContentOffset(new CoreGraphics.CGPoint(0, TableView.ContentSize.Height - TableView.Bounds.Height), true));

            OnActivation(d => {
                d(MilestoneElement.BindCommand(ViewModel.GoToMilestonesCommand));
                d(AssigneeElement.BindCommand(ViewModel.GoToAssigneesCommand));
                d(LabelsElement.BindCommand(ViewModel.GoToLabelsCommand));

                var canModify = this.WhenAnyValue(x => x.ViewModel.CanModify);
                d(MilestoneElement.BindDisclosure(canModify));
                d(AssigneeElement.BindDisclosure(canModify));
                d(LabelsElement.BindDisclosure(canModify));

                d(footerButton.Clicked.InvokeCommand(ViewModel.AddCommentCommand));
                d(HeaderView.Clicked.InvokeCommand(ViewModel.GoToOwnerCommand));

                d(this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
                  .ToBarButtonItem(UIBarButtonSystemItem.Action, x => NavigationItem.RightBarButtonItem = x));

                d(CommentsElement.UrlRequested.InvokeCommand(ViewModel.GoToUrlCommand));
                d(DescriptionElement.UrlRequested.InvokeCommand(ViewModel.GoToUrlCommand));

                d(this.WhenAnyObservable(x => x.ViewModel.GoToAssigneesCommand)
                  .Subscribe(_ => IssueAssigneeViewController.Show(this, ViewModel.CreateAssigneeViewModel())));

                d(this.WhenAnyObservable(x => x.ViewModel.GoToMilestonesCommand)
                  .Subscribe(_ => IssueMilestonesViewController.Show(this, ViewModel.CreateMilestonesViewModel())));

                d(this.WhenAnyObservable(x => x.ViewModel.GoToLabelsCommand)
                  .Subscribe(_ => IssueLabelsViewController.Show(this, ViewModel.CreateLabelsViewModel())));
            });
        }