function(input, output, session) {
  
  # CREATE REACTIVE FOR CONSOLE TEXT PROGRESS BAR
  rout <- tempfile("consoleText", fileext = ".txt")
  file.create(rout)
  console.text <- reactiveFileReader(200, session, rout, readLines, warn=F)
  
  # ERRORS MESSAGES
  output$errorsGsva <- renderText({
    req(argInp$varMinsz(), argInp$varMaxsz(), argInp$selectedTau())
    rv$errors.gsva
  })

  # ENABLING 'RUN' BTN
  observe({
    if(!is.null(matrix()) && !is.null(genesets())){
      enable("button")
    } else {
      disable("button")
    }
  })
  
  ### INPUTS ###
  
  # DATA MATRIX
  matrix <- matrixServer("matrix1")
  
  # GENES
  genesets <- geneSetsServer("genes1")
  
  # ARGUMENTS
  argInp <- argumentsDataServer("argumentsInput")
  

  #### GSVA RESULTS ####
  
  ## REACTIVE VALUES
  rv <- reactiveValues(gs=NULL, dat.t=NULL, n=NULL, dd.col=NULL, p=NULL, 
                       p2=NULL, p3=NULL, errors.gsva = NULL, sample.c = NULL)
  gsva.cancel <- reactiveVal(FALSE)
  
  ## GSVA RESULT
  observeEvent( input$button, {
    
    ## This js is in order to reset the event_data from the plotlys,
    ## so every time the .user hits the 'run' button, plotlys get back to null
    runjs("Shiny.setInputValue('plotly_click-click1', null);")
    runjs("Shiny.setInputValue('plotly_click-click2', null);")
    
    ## here we reset all the reactiveValues to NULL
    rv$gs <- NULL
    rv$dat.t <- NULL
    rv$p <- NULL
    rv$p2 <- NULL
    rv$p3 <- NULL
    rv$sample.c <- NULL
    rv$errors.gsva <- NULL
    
    ## this is a flag for the future. Futures cannot be canceled or
    ## terminated in a strict way, so when they get interrupted they
    ## throw an error that is not related to gsva(). When future is 
    ## interrupted, the flag goes TRUE in order to make the errors
    ## message print NULL
    gsva.cancel(FALSE)
    
    modalGSVAUI("modal.text")
    
    ## future() cannot take reactive values, so we must isolate() them
    future({
      ## sink() will redirect all console cats and prints to a
      ## text file that the main session will be reading in order
      ## to print the progress bar from bplaply()
      sink(rout)
      result <- gsva(isolate(matrix()),
                     isolate(genesets()), 
                     method=isolate(argInp$method()),
                     kcdf=isolate(argInp$kcdf()),
                     abs.ranking=isolate(argInp$absRanking()),
                     min.sz= isolate(argInp$varMinsz()),
                     max.sz=isolate(argInp$varMaxsz()),
                     parallel.sz=1L, ## by now, disable parallelism
                     mx.diff=isolate(argInp$mxDiff()),
                     tau=isolate(argInp$selectedTau()),
                     ssgsea.norm=isolate(argInp$ssgseaNorm()),
                     verbose=TRUE)
      sink()
      ## when gsva() ends, we reset the console text file to empty
      write("", file=rout)
      return(result)
    }, seed = TRUE) %...>%
      (function(result){
        ## the future's result will be the gsva() result, and we save it
        ## and transform it in reactiveValues(). In order to make the future
        ## not block the app at an inner-session level, we save the results in
        ## reactiveValues() and then at the end of the observeEvent() we return NULL
        ## in order to make the plots.
        ## https://github.com/rstudio/promises/issues/23#issuecomment-386687705
        rv$gs <- result
        rv$dat.t <- melt(as.data.table(rv$gs, keep.rownames = "gene.sets"),
                         variable.name = "Sample", id.vars="gene.sets")
        rv$n <- length(levels(rv$dat.t$Sample))
        rv$dd.col <- hcl(h = seq(15, 375, length=rv$n), l = 65, c = 100)[1:rv$n]
        names(rv$dd.col)  <- levels(rv$dat.t$Sample)
        
        ## finally, we leave the console.text file empty again and
        ## remove the modal
        write("", file=rout)
        removeModal()
      }) %...!%
      (function(error){
        ## there can be two ways to get an error here: 
        ## 1. gsva() fails, which is an ok error and should be returnet to user
        ## 2. User interrupts the future, which shouldn't be printed, that's
        ## why I use a flag to identify if error comes from pressing "Cancel" btn
        ## on the modal
        removeModal()
        write("", file=rout)
        if(gsva.cancel()){
          rv$errors.gsva <- NULL
        } else {
          rv$errors.gsva <- as.character(error)
        }
        
      })
    NULL
  })
  
  # PRINTING CONSOLE.TEXT
  modalGSVAServer("modal.text", console.text, gsva.cancel, rout)
  
  # PLOT1 RENDER
  plot1_Server("plot1", rv)

  # PLOT2 RENDER
  eventData1 <- reactive({
    req(rv$dat.t)
    ind <- event_data("plotly_click", source = "click1")
    ind <- ind$curveNumber+1
  })
  plot2_Server("plot2", eventData1, rv)
  
  
  # PLOT3 RENDER
  eventData2 <- reactive({
    req(rv$p2)
    ind <- event_data("plotly_click", source = "click2")
    ind <- ind$pointNumber+1
  })
  plot3_Server("plot3", eventData2, rv, matrix, genesets)
  
  # DWN BTN
  downloadServer("download", reactive(rv$gs))
  
  # CLOSE BTN
  closeBtnServer("close", reactive(rv$gs))

  
  # TEXT1
  output$text1 <- renderUI({
    req(rv$gs)
    HTML(paste("<br/>", "\t To see the Empirical Cumulative Distribution Function 
    of a Sample, click on its line in this plot and go
      to the 'Gene.Set' Panel", "<br/>", sep="<br/>"))
  })
  
  # TABLE
  output$result <- renderTable({
    req(rv$gs)
    resultInformation <- data.frame("Nr of gene sets" = nrow(rv$gs),
                                    "Nr of samples" = ncol(rv$gs))
    resultInformation
  })
  
  # TEXT2
  output$text2 <- renderUI({
    title1 <- rv$sample.c
    h2(tags$b(title1), align ="center")
  })
  
  # TEXT3
  output$text3 <- renderUI({
    HTML(paste("<br/>", "\t To see the Kernel Density Estimation of genes of 
    any given Gene Set in this Sample,  click on any point in this plot and a
    second plot will appear bellow it", "<br/>", sep="<br/>"))
  })
  
  # SESSION INFO
  output$sessionInfo <- renderPrint({
    sessionInfo()
  })

}