def build_plot_pipeline_action(controller, version, var_modules, plots,row, col, template=None):
        #// @todo: want to make sure that nothing changes if var_module
        #// or plot_module do not change

        # Get controller
        if controller is None:
            controller = api.get_current_controller()
            version = 0L

        # Get module registry
        reg = get_module_registry()
        ops = []
        cell_module = None

        #// First get the pipeline
        pipeline = controller.vistrail.getPipeline(version)

        #// @todo: Add support for multiple variables per plot
        #// Use only the first var module for now
        var_module = var_modules[0]

        #// @Aashish: As of now, very first time var module is being added to the pipeline by the project controller
        #// but second time on the same cell, it gets removed and hence we needed to add var module again to pipeline.
        #// I need to put this code under try catch because as of now looking for an id that does not exists
        #// results in exception.
        try:
            temp_var_module = pipeline.get_module_by_id(var_module.id)
        except KeyError:
            temp_var_module = None

        if temp_var_module is not None:
            var_module = temp_var_module
        else:
            # This time we need to add var module to the pipeline
            ops.append(('add', var_module))

        for plot in plots:
            plot_gm = plot.name

            #// Create plot module from the descriptor
            #// Is there a better way? I looked around and found none
            import re
            plotUsableName = re.sub(r'\s', '', plot_gm)
            plot_module = PlotPipelineHelper.find_module_by_name(pipeline, plotUsableName)
            if plot_module is not None:
                continue

            plot_descriptor = reg.get_descriptor_by_name('com.kitware.pvclimate', plotUsableName)

            #// @Aashish: Looks like the pipeline is using the cached representation
            plot_module = controller.create_module_from_descriptor(plot_descriptor)
            ops.append(('add', plot_module))

            #// @Aashish: This is no longer required as of this commit
            #// e13bb034ceb302afe3aad3caf20153e1525586db
            #// I am not sure though why we still need to add plot module
            #ops.append(('add', var_modules[0]))

            #// Create cell - representation linkage
            #// Check to see if a cell already exits, if yes then set the input (representation on it) or else
            #// create a new one and then set the representation on it.
            if cell_module is None:
                cell_module = PlotPipelineHelper.find_module_by_name(pipeline, "PVGenericCell")

            #// If cell module is None, then create a new one
            if cell_module is None:
                cell_desc = reg.get_descriptor_by_name('com.kitware.pvclimate', "PVGenericCell")
                cell_module = controller.create_module_from_descriptor(cell_desc)
                ops.append(('add', cell_module))

                #// Create a connection between the cell and the variable
                #// @Aashish: I am expecting that every time we drop a variable, we will get a
                #// pipeline that does not have modules from the previous execution. I need to verify
                #// this but for now this assumption seems to hold.
                
                oport = CDMSPipelineHelper.get_output_port_name(
                        var_module.module_descriptor.module)
                conn = controller.create_connection(var_module, oport,
                                                    plot_module, 'cdms_variable')
                ops.append(('add', conn))

                loc_module = controller.create_module_from_descriptor(
                    reg.get_descriptor_by_name('edu.utah.sci.vistrails.spreadsheet',
                                               'CellLocation'))
                functions = controller.create_functions(loc_module,
                    [('Row', [str(row+1)]), ('Column', [str(col+1)])])
                for f in functions:
                    loc_module.add_function(f)
                loc_conn = controller.create_connection(loc_module, 'self',
                                                        cell_module, 'Location')
                ops.extend([('add', loc_module),
                            ('add', loc_conn)])

            #// Create connection between the cell and the representation
            conn = controller.create_connection(plot_module, 'self',
                                                cell_module, 'representation')

            #// Add the connection to the pipeline operations
            ops.append(('add', conn))

        action = core.db.action.create_action(ops)
        controller.change_selected_version(version)
        controller.add_new_action(action)
        controller.perform_action(action)
        return action