// ========================================
        // method
        // ========================================
        public override void Execute()
        {
            _ensureInlineBreakCmd = null;
            _splitLineSegCmd      = null;
            _isExecuted           = false;

            int charIndexInLine, lineSegOffset;
            var line = _target.GetLineSegmentAt(_charIndex, out charIndexInLine, out lineSegOffset);

            if (charIndexInLine != 0)
            {
                _ensureInlineBreakCmd = new EnsureInlineBreakCommand(_target, _charIndex);
                _ensureInlineBreakCmd.Execute();

                int inlineIndex, charIndexInInline;
                line.GetInlineAtLocal(charIndexInLine, out inlineIndex, out charIndexInInline);

                _splitLineSegCmd = new SplitLineSegmentCommand(line, inlineIndex);
                _splitLineSegCmd.Execute();
                _isExecuted = true;
            }
        }
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            _command = null;

            int lineSegOffset, charIndexInLine;
            var lineSeg = _target.GetLineSegmentAt(_index, out charIndexInLine, out lineSegOffset);
            var block   = lineSeg.Parent as Block;

            if (charIndexInLine == 0)
            {
                /// lineSegの最初の文字を指している場合,lineSegの直前に空のLineを作成して挿入する
                var lineIndex = block._Lines.IndexOf(lineSeg);
                var newLine   = new LineSegment();
                block.Transfer(newLine);
                _command = new InsertLineSegmentToBlockCommand(block, newLine, lineIndex);
            }
            else
            {
                /// lineSegの途中の文字を指している場合,lineSegをそこで分割する
                _command = new EnsureLineSegmentBreakCommand(_target, _index);
            }

            _command.Execute();
        }
        private int InsertFlows(IEnumerable <Flow> flows)
        {
            _commands = new List <ICommand>();
            {
                var cmd = new EnsureInlineBreakCommand(_target, _index);
                cmd.Execute();
                _commands.Add(cmd);
            }

            var firstBlock = _target.GetBlockAt(_index);
            var bIndex     = _target._Blocks.IndexOf(firstBlock);
            var cIndex     = _index;

            foreach (var flow in flows)
            {
                if (flow is Block)
                {
                    var block = flow as Block;

                    int charIndexInLine, lineSegOffset;
                    _target.GetLineSegmentAt(cIndex, out charIndexInLine, out lineSegOffset);

                    if (charIndexInLine == 0)
                    {
                        /// Line中でなければそのまま挿入
                        var cmd = new InsertBlockToStyledTextCommand(_target, block, bIndex);
                        cmd.Execute();
                        _commands.Add(cmd);
                        cIndex += flow.Length;
                    }
                    else
                    {
                        /// Line中ならInlineだけ挿入
                        foreach (var line in block.LineSegments)
                        {
                            foreach (var inline in line.Inlines)
                            {
                                if (inline.IsLineEndCharacter)
                                {
                                    if (inline is BlockBreak)
                                    {
                                        var cmd = new InsertBlockBreakCommand(_target, cIndex);
                                        cmd.Execute();
                                        _commands.Add(cmd);
                                    }
                                    else if (inline is LineBreak)
                                    {
                                        var cmd = new InsertLineBreakCommand(_target, cIndex);
                                        cmd.Execute();
                                        _commands.Add(cmd);
                                    }
                                }
                                else
                                {
                                    var clone = inline.CloneDeeply() as Inline;
                                    var cmd   = new InsertInlineCommand(_target, cIndex, clone);
                                    cmd.Execute();
                                    _commands.Add(cmd);
                                }
                                cIndex += inline.Length;
                            }
                        }
                    }
                    ++bIndex;
                }
                else if (flow is Inline)
                {
                    var inline = flow as Inline;
                    if (inline.IsLineEndCharacter)
                    {
                        if (inline is BlockBreak)
                        {
                            var cmd = new InsertBlockBreakCommand(_target, cIndex);
                            cmd.Execute();
                            _commands.Add(cmd);
                            ++bIndex;
                        }
                        else if (inline is LineBreak)
                        {
                            var cmd = new InsertLineBreakCommand(_target, cIndex);
                            cmd.Execute();
                            _commands.Add(cmd);
                        }
                    }
                    else
                    {
                        var clone = inline.CloneDeeply() as Inline;
                        var cmd   = new InsertInlineCommand(_target, cIndex, clone);
                        cmd.Execute();
                        _commands.Add(cmd);
                    }
                    cIndex += flow.Length;
                }
            }

            /// 最初のinlineがmergeできるならmerge
            var firstInline = _target.GetInlineAt(_index);

            if (_target.HasPrevInline(firstInline))
            {
                var prev = _target.GetPrevInline(firstInline);
                if (prev.CanMerge(firstInline))
                {
                    var cmd = new MergeInlineCommand(prev, firstInline);
                    cmd.Execute();
                    _commands.Add(cmd);
                }
            }

            /// 最後のinlineがmergeできるならmerge
            var lastInline = _target.GetInlineAt(cIndex - 1);

            if (_target.HasNextInline(lastInline))
            {
                var next = _target.GetNextInline(lastInline);
                if (lastInline.CanMerge(next))
                {
                    var cmd = new MergeInlineCommand(lastInline, next);
                    cmd.Execute();
                    _commands.Add(cmd);
                }
            }

            return(cIndex);
        }