public function relateContentNodes($contentNodeList, $chapterId) {
        // Reverse node list because the Weighable behavior sorts different from the way
        // the CMS sends us the nodes.
        $contentNodeList = array_reverse($contentNodeList);
        foreach ($contentNodeList as $contentNode) {
            $node = $this->_getValidContentNodeData($contentNode);

            // Save ContentNode
            $node['chapter_id'] = $chapterId;
            $contentNodeId = $this->_insertContentNode($node);

            // @todo Move everything below here to Model_ContentNode::afterInsert()

            // Determine content type
            $contentTypeModelName = 'Model_'.$node['model'];
            $contentTypeModel = new $contentTypeModelName();

            // Check for existing id
            $data = $node['data'];
            if (empty($data['id'])) {
                // If no id is present, create a new subtype record
                $contentTypeId = $contentTypeModel->insert($data);
            } else {
                // Update the chapter subtype's content
                $contentTypeModel->update($data, 'id = '.$contentTypeModel->getAdapter()->quote($data['id']));
                $contentTypeId = $data['id'];
            }

            // Relate the ContentNode to the subtype record
            Garp_Content_Relation_Manager::relate(array(
                'modelA' => 'Model_ContentNode',
                'modelB' => $contentTypeModel,
                'keyA'   => $contentNodeId,
                'keyB'   => $contentTypeId,
            ));
        }
    }