function merge_ContentActionHandler(&$module, &$http, &$objectID)
{
    $selected_array = array();
    $merge_node_master = 0;
    $translation_map = array();
    if ($http->hasSessionVariable('MergeNodeSelectionList')) {
        $selected_array = $http->sessionVariable('MergeNodeSelectionList');
    }
    if ($http->hasSessionVariable('MergeNodeMaster')) {
        $merge_node_master = $http->sessionVariable('MergeNodeMaster');
    }
    if ($http->hasSessionVariable('MergeObjectTranslationMap')) {
        $translation_map = $http->sessionVariable('MergeObjectTranslationMap');
    }
    // Update master node
    if ($http->hasPostVariable('MergeNodeMaster')) {
        if ($merge_node_master != $http->postVariable('MergeNodeMaster')) {
            $merge_node_master = $http->postVariable('MergeNodeMaster');
            $http->setSessionVariable('MergeNodeMaster', $merge_node_master);
        }
        // Update translation map
        $count = 0;
        while ($http->hasPostVariable('MergeTranslation_' . $count)) {
            $values = explode('_', $http->postVariable('MergeTranslation_' . $count));
            $translation_map[$values[0]] = $values[1];
            $count++;
        }
        $http->setSessionVariable('MergeObjectTranslationMap', $translation_map);
    }
    // Remove selected nodes
    if ($http->hasPostVariable('RemoveObjects')) {
        $remove_list = array();
        if ($http->hasPostVariable('RemoveNode')) {
            $remove_list = $http->postVariable('RemoveNode');
            $selected_array = array_values(array_diff($selected_array, $remove_list));
            $http->setSessionVariable('MergeNodeSelectionList', $selected_array);
            // Check master node
            if (!in_array($merge_node_master, $selected_array)) {
                $merge_node_master = 0;
                $http->setSessionVariable('MergeNodeMaster', 0);
            }
            // Remove any related selected translations
            $update_translation_map = false;
            foreach ($translation_map as $language => $node_id) {
                if (in_array($node_id, $remove_list)) {
                    unset($translation_map[$language]);
                    $update_translation_map = true;
                }
            }
            if ($update_translation_map) {
                $http->setSessionVariable('MergeObjectTranslationMap', $translation_map);
            }
        }
        $module->redirectTo('/merge/select');
    }
    // Go to browse module to choose nodes to merge
    if ($http->hasPostVariable('MergeBrowse')) {
        $ini = eZINI::instance('merge.ini');
        $class_list = $ini->variable('MergeSettings', 'ClassList');
        $start_node_id = $ini->variable('MergeSettings', 'BrowseNodeID');
        eZContentBrowse::browse(array('action_name' => 'MergeObjects', 'description_template' => 'design:content/browse_placement.tpl', 'ignore_nodes_select' => $selected_array, 'ignore_nodes_click' => array(), 'selection' => 'radio', 'class_array' => $class_list, 'start_node' => $start_node_id, 'from_page' => '/merge/select'), $module);
    }
    // Actual merge operation
    if ($http->hasPostVariable('MergeAction')) {
        if (count($selected_array) != 2) {
            $module->redirectTo('/merge/select');
        }
        // Set up correct order according to selected master
        if ($selected_array[1] == $merge_node_master) {
            $selected_array = array_reverse($selected_array);
        }
        // Fetch objects to merge
        $mnode1 = eZFunctionHandler::execute('content', 'node', array('node_id' => $selected_array[0]));
        $mnode2 = eZFunctionHandler::execute('content', 'node', array('node_id' => $selected_array[1]));
        $mobject1 = $mnode1->attribute('object');
        $mobject2 = $mnode2->attribute('object');
        // Do sanity check
        if ($mobject1->attribute('contentclass_id') != $mobject2->attribute('contentclass_id')) {
            $module->redirectTo('/merge/select');
        }
        // Make sure merge process does not get a PHP timeout
        set_time_limit(0);
        $db = eZDB::instance();
        $db->begin();
        foreach ($translation_map as $language => $node_id) {
            $object1 = $object2 = null;
            $node1 = eZFunctionHandler::execute('content', 'node', array('node_id' => $selected_array[0], 'language_code' => $language));
            $node2 = eZFunctionHandler::execute('content', 'node', array('node_id' => $selected_array[1], 'language_code' => $language));
            // Make sure we get correct language
            if ($node1) {
                $object1 = $node1->attribute('object');
                if (!in_array($language, $object1->attribute('available_languages'))) {
                    $object1 = $mobject1;
                }
            } else {
                $object1 = $mobject1;
            }
            if ($node2) {
                $object2 = $node2->attribute('object');
                if (!in_array($language, $object2->attribute('available_languages'))) {
                    $object2 = null;
                }
            }
            // Copy language in specified direction, if it exist in both objects
            $use_object1_values = $node_id == $selected_array[0];
            if ($object1 and $object2) {
                // Need to redirect node 2 current url alias to avoid added "2" in the new url alias of merged object
                $urlalias_array = eZURLAliasML::fetchByPath($node2->attribute('url_alias'));
                foreach ($urlalias_array as $urlalias) {
                    $urlalias = eZURLAliasML::fetchObject(eZURLAliasML::definition(), null, array('id' => $urlalias->attribute('id'), 'lang_mask' => $urlalias->attribute('lang_mask')));
                    $urlalias->setAttribute('action', 'eznode:' . $mnode1->attribute('node_id'));
                    $urlalias->store();
                }
                doContentObjectMerge($object1, $object2, $language, $use_object1_values);
            }
        }
        $main_node_id1 = $mobject1->attribute('main_node_id');
        foreach ($mobject2->attribute('assigned_nodes') as $node2) {
            // Move any children of object2 nodes to object1 main node
            $children2 = eZFunctionHandler::execute('content', 'list', array('parent_node_id' => $node2->attribute('node_id')));
            foreach ($children2 as $child2) {
                eZContentObjectTreeNodeOperations::move($child2->attribute('node_id'), $main_node_id1);
            }
        }
        // Delete object2
        $mobject2->purge();
        $db->commit();
        //        $db->rollback(); // For debugging
        // Clean up session variables
        $http->removeSessionVariable('MergeNodeSelectionList');
        $http->removeSessionVariable('MergeNodeMaster');
        $http->removeSessionVariable('MergeObjectTranslationMap');
        $module->redirectTo($mnode1->attribute('url_alias'));
    }
}