<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fillna(self, **kwargs):
 """Replaces NaN values with the method provided. Returns: A new QueryCompiler with null values filled. """

        axis = kwargs.get("axis", 0)
        value = kwargs.get("value")
        if isinstance(value, dict):
            value = kwargs.pop("value")

            if axis == 0:
                index = self.columns
            else:
                index = self.index
            value = {
                idx: value[key] for key in value for idx in index.get_indexer_for([key])
            }

            def fillna_dict_builder(df, func_dict={}):
                # We do this to ensure that no matter the state of the columns we get
                # the correct ones.
                func_dict = {df.columns[idx]: func_dict[idx] for idx in func_dict}
                return df.fillna(value=func_dict, **kwargs)

            new_data = self.data.apply_func_to_select_indices(
                axis, fillna_dict_builder, value, keep_remaining=True
            )
            return self.__constructor__(new_data, self.index, self.columns)
        else:
            func = self._prepare_method(pandas.DataFrame.fillna, **kwargs)
            new_data = self._map_across_full_axis(axis, func)
            return self.__constructor__(new_data, self.index, self.columns)