code: def _restore_dropped_levels_multijoin(
      left, right, dropped_level_names, join_index, lindexer, rindexer
  ):
      """
      *this is an internal non-public method*
  
      Returns the levels, labels and names of a multi-index to multi-index join.
      Depending on the type of join, this method restores the appropriate
      dropped levels of the joined multi-index.
      The method relies on lidx, rindexer which hold the index positions of
      left and right, where a join was feasible
  
      Parameters
      ----------
      left : MultiIndex
          left index
      right : MultiIndex
          right index
      dropped_level_names : str array
          list of non-common level names
      join_index : MultiIndex
          the index of the join between the
          common levels of left and right
      lindexer : intp array
          left indexer
      rindexer : intp array
          right indexer
  
      Returns
      -------
      levels : list of Index
          levels of combined multiindexes
      labels : intp array
          labels of combined multiindexes
      names : str array
          names of combined multiindexes
  
      """
  
      def _convert_to_mulitindex(index):
          if isinstance(index, MultiIndex):
              return index
          else:
              return MultiIndex.from_arrays(
                  [index.values], names=[index.name]
              )
  
      # For multi-multi joins with one overlapping level,
      # the returned index if of type Index
      # Assure that join_index is of type MultiIndex
      # so that dropped levels can be appended
      join_index = _convert_to_mulitindex(join_index)
  
      join_levels = join_index.levels
      join_codes = join_index.codes
      join_names = join_index.names
  
      # lindexer and rindexer hold the indexes where the join occurred
      # for left and right respectively. If left/right is None then
      # the join occurred on all indices of left/right
      if lindexer is None:
          lindexer = range(left.size)
  
      if rindexer is None:
          rindexer = range(right.size)
  
      # Iterate through the levels that must be restored
      for dropped_level_name in dropped_level_names:
          if dropped_level_name in left.names:
              idx = left
              indexer = lindexer
          else:
              idx = right
              indexer = rindexer
  
          # The index of the level name to be restored
          name_idx = idx.names.index(dropped_level_name)
  
          restore_levels = idx.levels[name_idx]
          # Inject -1 in the codes list where a join was not possible
          # IOW indexer[i]=-1
          codes = idx.codes[name_idx]
          restore_codes = algos.take_nd(codes, indexer, fill_value=-1)
  
          join_levels = join_levels + [restore_levels]
          join_codes = join_codes + [restore_codes]
          join_names = join_names + [dropped_level_name]
  
      return join_levels, join_codes, join_names
  
imports: import copy
  import string
  import warnings
  import numpy
  from pandas._libs import hashtable, join, lib
  import pandas.compat
  from pandas.compat import filter, lzip, map, range, zip
  from pandas.errors import MergeError
  from pandas.util._decorators import Appender, Substitution
  from pandas.core.dtypes.common import ensure_float64, ensure_int64, ensure_object, is_array_like, is_bool, is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetimelike, is_dtype_equal, is_extension_array_dtype, is_float_dtype, is_int64_dtype, is_integer, is_integer_dtype, is_list_like, is_number, is_numeric_dtype, is_object_dtype, needs_i8_conversion
  from pandas.core.dtypes.missing import isnull, na_value_for_dtype
  from pandas import Categorical, DataFrame, Index, MultiIndex, Series, Timedelta
  import pandas.core.algorithms
  from pandas.core.arrays.categorical import _recode_for_categories
  import pandas.core.common
  from pandas.core.frame import _merge_doc
  from pandas.core.internals import concatenate_block_managers, items_overlap_with_suffix
  import pandas.core.sorting
  from pandas.core.sorting import is_int64_overflow_possible
label_desc: Use image node_id 6 for calling a global function with example usage: _restore_dropped_levels_multijoin(left, right, dropped_level_names, join_index, lindexer, rindexer) and returns: join_levels,  join_codes,  join_names, index, MultiIndex