whole_func_string: function GatherCompileInfo(source, script) {
      // Get function info, elements are partially sorted (it is a tree of
      // nested functions serialized as parent followed by serialized children.
      var raw_compile_info = %LiveEditGatherCompileInfo(script, source);
  
      // Sort function infos by start position field.
      var compile_info = new GlobalArray();
      var old_index_map = new GlobalArray();
      for (var i = 0; i < raw_compile_info.length; i++) {
        var info = new FunctionCompileInfo(raw_compile_info[i]);
        // Remove all links to the actual script. Breakpoints system and
        // LiveEdit itself believe that any function in heap that points to a
        // particular script is a regular function.
        // For some functions we will restore this link later.
        %LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED);
        compile_info.push(info);
        old_index_map.push(i);
      }
  
      for (var i = 0; i < compile_info.length; i++) {
        var k = i;
        for (var j = i + 1; j < compile_info.length; j++) {
          if (compile_info[k].start_position > compile_info[j].start_position) {
            k = j;
          }
        }
        if (k != i) {
          var temp_info = compile_info[k];
          var temp_index = old_index_map[k];
          compile_info[k] = compile_info[i];
          old_index_map[k] = old_index_map[i];
          compile_info[i] = temp_info;
          old_index_map[i] = temp_index;
        }
      }
  
      // After sorting update outer_index field using old_index_map. Also
      // set next_sibling_index field.
      var current_index = 0;
  
      // The recursive function, that goes over all children of a particular
      // node (i.e. function info).
      function ResetIndexes(new_parent_index, old_parent_index) {
        var previous_sibling = -1;
        while (current_index < compile_info.length &&
            compile_info[current_index].outer_index == old_parent_index) {
          var saved_index = current_index;
          compile_info[saved_index].outer_index = new_parent_index;
          if (previous_sibling != -1) {
            compile_info[previous_sibling].next_sibling_index = saved_index;
          }
          previous_sibling = saved_index;
          current_index++;
          ResetIndexes(saved_index, old_index_map[saved_index]);
        }
        if (previous_sibling != -1) {
          compile_info[previous_sibling].next_sibling_index = -1;
        }
      }
  
      ResetIndexes(-1, -1);
      Assert(current_index == compile_info.length);
  
      return compile_info;
    }
func_code_string: function GatherCompileInfo(source, script) {
      // Get function info, elements are partially sorted (it is a tree of
      // nested functions serialized as parent followed by serialized children.
      var raw_compile_info = %LiveEditGatherCompileInfo(script, source);
  
      // Sort function infos by start position field.
      var compile_info = new GlobalArray();
      var old_index_map = new GlobalArray();
      for (var i = 0; i < raw_compile_info.length; i++) {
        var info = new FunctionCompileInfo(raw_compile_info[i]);
        // Remove all links to the actual script. Breakpoints system and
        // LiveEdit itself believe that any function in heap that points to a
        // particular script is a regular function.
        // For some functions we will restore this link later.
        %LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED);
        compile_info.push(info);
        old_index_map.push(i);
      }
  
      for (var i = 0; i < compile_info.length; i++) {
        var k = i;
        for (var j = i + 1; j < compile_info.length; j++) {
          if (compile_info[k].start_position > compile_info[j].start_position) {
            k = j;
          }
        }
        if (k != i) {
          var temp_info = compile_info[k];
          var temp_index = old_index_map[k];
          compile_info[k] = compile_info[i];
          old_index_map[k] = old_index_map[i];
          compile_info[i] = temp_info;
          old_index_map[i] = temp_index;
        }
      }
  
      // After sorting update outer_index field using old_index_map. Also
      // set next_sibling_index field.
      var current_index = 0;
  
      // The recursive function, that goes over all children of a particular
      // node (i.e. function info).
      function ResetIndexes(new_parent_index, old_parent_index) {
        var previous_sibling = -1;
        while (current_index < compile_info.length &&
            compile_info[current_index].outer_index == old_parent_index) {
          var saved_index = current_index;
          compile_info[saved_index].outer_index = new_parent_index;
          if (previous_sibling != -1) {
            compile_info[previous_sibling].next_sibling_index = saved_index;
          }
          previous_sibling = saved_index;
          current_index++;
          ResetIndexes(saved_index, old_index_map[saved_index]);
        }
        if (previous_sibling != -1) {
          compile_info[previous_sibling].next_sibling_index = -1;
        }
      }
  
      ResetIndexes(-1, -1);
      Assert(current_index == compile_info.length);
  
      return compile_info;
    }
func_documentation_string: Fully compiles source string as a script. Returns Array of FunctionCompileInfo -- a descriptions of all functions of the script. Elements of array are ordered by start positions of functions (from top to bottom) in the source. Fields outer_index and next_sibling_index help to navigate the nesting structure of functions.  All functions get compiled linked to script provided as parameter script. TODO(LiveEdit): consider not using actual scripts as script, because we have to manually erase all links right after compile.