protected function getClonedWidget($replicator_id)
    {
        if (isset($this->clones[$replicator_id])) {
            return $this->clones[$replicator_id];
        }

        if ($this->widget === null) {
            return null;
        }

        $row = $this->getInputRow();
        if ($row === null) {
            throw new SwatException(
                'Cannot clone widgets until cell is ' .
                    'added to a table-view and an input-row is added to the ' .
                    'table-view.'
            );
        }

        $view = $this->getFirstAncestor('SwatTableView');
        $view_id = $view === null ? null : $view->id;
        $suffix =
            $view_id === null
                ? '_' . $row->id . '_' . $replicator_id
                : '_' . $view_id . '_' . $row->id . '_' . $replicator_id;

        $new_widget = $this->widget->copy($suffix);
        $new_widget->parent = $this;

        if ($new_widget->id !== null) {
            // lookup array uses original ids
            $old_id = mb_substr($new_widget->id, 0, -mb_strlen($suffix));
            $this->widgets[$replicator_id][$old_id] = $new_widget;
        }

        if ($new_widget instanceof SwatUIParent) {
            foreach ($new_widget->getDescendants() as $descendant) {
                if ($descendant->id !== null) {
                    // lookup array uses original ids
                    $old_id = mb_substr(
                        $descendant->id,
                        0,
                        -mb_strlen($suffix)
                    );
                    $this->widgets[$replicator_id][$old_id] = $descendant;
                }
            }
        }

        $this->clones[$replicator_id] = $new_widget;

        return $new_widget;
    }