function(                                                      # MERGE TWO DATAFRAMES
         df=factor(levels=dataframes(eN))[[1]],                        # First Dataframe               # Dataframe
         df_key=factor(eN_dollar_set(df),levels=colnames(df)),         # First Dataframe               # Columns to be used as merge keys
         all.x=factor("TRUE",levels=c("TRUE","FALSE"))[[1]],           # First Dataframe               # Include all rows of this dataframe in merged table?
         y=factor(eN[eN_stimulus_set(df)],levels=dataframes(eN))[[1]], # Second Dataframe              # Dataframe
         y_key=factor(eN_dollar_arg(df),levels=colnames(y)),           # Second Dataframe              # Columns to be used as merge keys
         all.y=factor("TRUE",levels=c("TRUE","FALSE"))[[1]],           # Second Dataframe              # Include all rows of this dataframe in merged table?
         drop.NAs=factor("FALSE",levels=c("TRUE","FALSE"))[[1]]        # Second Dataframe              # Drop any rows containing NA?
) 
{
  tryCatch(
    {   
        if(length(df_key)!=length(y_key))
        {
          return(df)
        }
        xdup<-duplicated(df_key)
        if(any(xdup))
        {
          df_key<-df_key[!xdup]
          y_key<-y_key[!xdup]
        }
        ydup<-duplicated(y_key)
        if(any(ydup))
        {
          df_key<-df_key[!ydup]
          y_key<-y_key[!ydup]
        }
        m<-merge(df,y,by.x=df_key,by.y=y_key,all.x=all.x,all.y=all.y,sort=F,suffixes=paste(".",sep="",c(deparse(substitute(df)),deparse(substitute(y)))) )
        if (drop.NAs) m<-na.omit(m)
        return(m)
    }, warning = function(w) { print(w); return
      
    }, error = function(e) { print(e); err<-data.frame(error=as.character(e$message));err$error=as.character(err$error); return(err)
      
    }, finally = { 
      
    }
  )  
}
