public BroadcastControlViewModel(MainPanelViewModel parent,
            BroadcastModel broadcastModel, Configuration configuration)
        {
            this.configuration = configuration;

            var externalSourceViewModel = parent.ExternalSourceViewModel;
            BroadcastCommand = new DelegateCommand(() =>
            {
                // 画面ロック
                IsProcessing = true;
                // ヒストリ更新
                externalSourceViewModel.UpdateHistory();
                // YP規約チェック
                var yp = parent.YellowPagesListViewModel.SelectedYellowPages;
                if (!yp.IsAccepted)
                {
                    parent.OnException(new ApplicationException("YPの規約に同意していません。" + Environment.NewLine
                        + "配信を開始するにはYPの規約を確認し、同意する必要があります。"));
                    parent.SelectedIndex = MainPanelViewModel.YellowPagesTabIndex;
                    IsProcessing = false;
                    return;
                }
                var parameter = ViewModelDxo.ToBroadcastParameter(externalSourceViewModel);
                var id = broadcastModel.BroadcastAsync(
                    yp.Model, yp.AcceptedHash, yp.Parameters.Dictionary, parameter,
                    new Progress<string>(x => parent.Feedback = x)).ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        parent.OnException(t.Exception);
                        IsProcessing = false;
                        return;
                    }
                    BroadcastingChannel = new BroadcastingChannel(parameter.Name, t.Result.Id);
                    IsProcessing = false;
                }, TaskScheduler.FromCurrentSynchronizationContext());
            }, () =>
            {
                if (IsProcessing)
                    return false;
                if (IsBroadcasting)
                    return false;
                if (parent.SettingsViewModel.HasError)
                    return false;
                if (parent.YellowPagesListViewModel.SelectedYellowPages == null)
                    return false;
                if (externalSourceViewModel.HasError)
                    return false;
                return true;
            });

            UpdateCommand = new DelegateCommand(() =>
            {
                IsProcessing = true;
                parent.ExternalSourceViewModel.UpdateHistory();
                var yp = parent.YellowPagesListViewModel.SelectedYellowPages;
                broadcastModel.UpdateAsync(
                    yp.Model, yp.Parameters.Dictionary,
                    ViewModelDxo.ToUpdateParameter(BroadcastingChannel.Id, parent.ExternalSourceViewModel),
                    new Progress<string>(x => parent.Feedback = x))
                    .ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            parent.OnException(t.Exception);
                        }
                        IsProcessing = false;
                    }, TaskScheduler.FromCurrentSynchronizationContext());
            }, () =>
            {
                if (IsProcessing)
                    return false;
                if (!IsBroadcasting)
                    return false;
                if (parent.SettingsViewModel.HasError)
                    return false;
                if (externalSourceViewModel.HasError)
                    return false;
                return true;
            });

            StopCommand = new DelegateCommand(() =>
            {
                IsProcessing = true;
                var yp = parent.YellowPagesListViewModel.SelectedYellowPages;
                broadcastModel.StopAsync(yp.Model, yp.Parameters.Dictionary,
                    BroadcastingChannel.Name, BroadcastingChannel.Id,
                    new Progress<string>(x => parent.Feedback = x))
                    .ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            parent.OnException(t.Exception);
                            IsProcessing = false;
                            return;
                        }
                        BroadcastingChannel = null;
                        IsProcessing = false;
                    }, TaskScheduler.FromCurrentSynchronizationContext());
            }, () =>
            {
                if (IsProcessing)
                    return false;
                if (!IsBroadcasting)
                    return false;
                if (parent.SettingsViewModel.HasError)
                    return false;
                return true;
            });
        }