/**
  * Formats a logging message and sends it asynchronously to local-logger
+ * (the connection is through GSS)
  * \brief generic asynchronous logging function
  * \param[in,out] context      context to work with,
  * \param[in] event            type of the event,
 
 /**
  * Formats a logging message and sends it synchronously to local-logger
+ * (the connection is through GSS)
  * \brief generic synchronous logging function
  * \param[in,out] context      context to work with,
  * \param[in] event            type of the event,
 
 /**
  * Formats a logging message and sends it synchronously to L&B Proxy
+ * (the connection is through UNIX socket)
  * \brief generic synchronous logging function
  * \param[in,out] context      context to work with,
  * \param[in] event            type of the event,
 
 /**
  * Register job with L&B service.
- * Done via logging REGJOB event, may generate subjob id's and create
- * the parent-children associations.
- * Set the job as current for the context and initialize sequence code.
- *
- * Partitionable jobs should set num_subjobs=0 initially,
- * and re-register when number of subjobs becomes known.
+ * Done via logging REGJOB event directly to LB server (the connection is asynchronous through GSS)
+ * - may generate subjob id's and create the parent-children associations,
+ * - set the job as current for the context and initialize sequence code,
+ * - partitionable jobs should set num_subjobs=0 initially, 
+ *   and re-register when the number of subjobs becomes known.
  *
+ * \brief asynchronous job registration
  * \param[in,out] context      context to work with
  * \param[in] job              jobId
  * \param[in] type             EDG_WLL_JOB_SIMPLE,  EDG_WLL_JOB_DAG, or EDG_WLL_JOB_PARTITIONABLE
 
 /* backward compatibility */
 #define EDG_WLL_JOB_SIMPLE     EDG_WLL_REGJOB_SIMPLE
- 
+#define edg_wll_RegisterJobAsync       edg_wll_RegisterJob 
+
 extern int edg_wll_RegisterJob(
        edg_wll_Context         context,
        glite_jobid_const_t     job,
 
 /**
  * Register job with L&B Proxy service.
- * Done via logging REGJOB event, may generate subjob id's and create
- * the parent-children associations.
- * Set the job as current for the context and initialize sequence code.
- *
- * Partitionable jobs should set num_subjobs=0 initially,
- * and re-register when number of subjobs becomes known.
+ * Done via logging REGJOB event in parallel both 
+ * to LB proxy (through UNIX socket) and 
+ * to LB server (through GSS)
+ * - may generate subjob id's and create the parent-children associations,
+ * - set the job as current for the context and initialize sequence code,
+ * - partitionable jobs should set num_subjobs=0 initially,
+ *   and re-register when number of subjobs becomes known.
  *
  * \param[in,out] context      context to work with
  * \param[in] job              jobId
        glite_jobid_t **        subjobs
 );
 
+/** 
+ * Job registration with an extra ACL specifying WMS to acces the job
+ * (the connection to LB server is asynchronous through GSS)
+ * \param[in] wms_dn           DN of WMS handling the job
+ */
+
+extern int edg_wll_RegisterJobACL(
+       edg_wll_Context         context,
+       glite_jobid_const_t     job,
+       enum edg_wll_RegJobJobtype      type,
+       const char *            jdl,
+       const char *            ns,
+       int                     num_subjobs,
+       const char *            seed,
+       glite_jobid_t **        subjobs,
+       char **                 wms_dn
+);
+
+extern int edg_wll_RegisterJobProxyACL(
+       edg_wll_Context         context,
+       glite_jobid_const_t     job,
+       enum edg_wll_RegJobJobtype      type,
+       const char *            jdl,
+       const char *            ns,
+       int                     num_subjobs,
+       const char *            seed,
+       glite_jobid_t **        subjobs,
+       char **                 wms_dn
+);
+
 #ifdef LB_PERF
 /* original register to LBProxy        */
 extern int edg_wll_RegisterJobProxyOld(
 
                if (ret) goto edg_wll_logeventmaster_end;
        }
 
-       if (flags & (EDG_WLL_LOGFLAG_LOCAL|EDG_WLL_LOGFLAG_PROXY|EDG_WLL_LOGFLAG_DIRECT) == 0) {
+       if ((flags & (EDG_WLL_LOGFLAG_LOCAL|EDG_WLL_LOGFLAG_PROXY|EDG_WLL_LOGFLAG_DIRECT)) == 0) {
                edg_wll_SetError(ctx,ret = EINVAL,"edg_wll_LogEventMaster(): no known flag specified");
        }
 #endif
        glite_jobid_const_t     parent,
         int                     num_subjobs,
         const char *            seed,
-        edg_wlc_JobId **        subjobs)
+        edg_wlc_JobId **        subjobs,
+       char **                 wms_dn)
 {
-       char    *seq,*type_s,*parent_s;
-       int     err = 0;
+       char    *seq,*type_s,*parent_s,*wms_dn_s;
+       int     err = 0,i;
        struct timeval sync_to;
 
-       seq = type_s = parent_s = NULL;
+       seq = type_s = parent_s = wms_dn_s = NULL;
 
        edg_wll_ResetError(ctx);
        memcpy(&sync_to, &ctx->p_sync_timeout, sizeof sync_to);
                goto edg_wll_registerjobmaster_end;
        }
        parent_s = parent ? edg_wlc_JobIdUnparse(parent) : strdup("");
+       if (wms_dn) {
+               char *aux,*aux2;
+               aux2 = strdup("");
+               for (i=0; wms_dn[i]; i++) {
+                       asprintf(&aux,"%s\n%s",aux2,wms_dn[i]);
+                       free(aux2); aux2 = aux; aux = NULL;
+               }
+               wms_dn_s = strdup(aux2);
+               free(aux2); aux2 = NULL;
+       }
 
        if ( ((flags & (EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_LOCAL)) == 
                                (EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_LOCAL)) ||
        if (edg_wll_SetLoggingJob(ctx,job,NULL,EDG_WLL_SEQ_NORMAL) == 0) {
                err = edg_wll_LogEventMaster(ctx, flags,
                        EDG_WLL_EVENT_REGJOB, EDG_WLL_FORMAT_REGJOB,
-                       (char *)jdl, ns, parent_s, type_s, num_subjobs, seed);
+                       (char *)jdl, ns, parent_s, type_s, num_subjobs, seed, wms_dn_s);
                if (err) {
                        edg_wll_UpdateError(ctx,0,"edg_wll_RegisterJobMaster(): unable to register with bkserver");
                        goto edg_wll_registerjobmaster_end;
         const char *            seed,
         edg_wlc_JobId **        subjobs)
 {
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_SYNC,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_SYNC,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,NULL);
 }
 
 /**
         const char *            seed,
         edg_wlc_JobId **        subjobs)
 {
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_ASYNC,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_ASYNC,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,NULL);
+}
+
+/**
+ *-----------------------------------------------------------------------
+ * Asynchronous job registration with an extra ACL specifying WMS to acces the job 
+ * \note simple wrapper around edg_wll_RegisterJobMaster()
+ *-----------------------------------------------------------------------
+ */
+int edg_wll_RegisterJobACL(
+        edg_wll_Context         ctx,
+        glite_jobid_const_t     job,
+        enum edg_wll_RegJobJobtype     type,
+        const char *            jdl,
+        const char *            ns,
+        int                     num_subjobs,
+        const char *            seed,
+        edg_wlc_JobId **        subjobs,
+       char **                 wms_dn)
+{
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_ASYNC,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,wms_dn);
 }
 
+
 #ifndef LB_SERIAL_REG
 
 /**
  *-----------------------------------------------------------------------
- * Register one job with L&B Proxy service 
- * \note simple wrapper around edg_wll_RegisterJobMaster()
- * this is new (!LB_SERIAL_REG) edg_wll_RegisterJobProxy 
+ * Register job with L&B Proxy service.
  *-----------------------------------------------------------------------
  */
-int edg_wll_RegisterJobProxy(
+
+int edg_wll_RegisterJobProxyMaster(
         edg_wll_Context         ctx,
         glite_jobid_const_t     job,
         enum edg_wll_RegJobJobtype     type,
         const char *            ns,
         int                     num_subjobs,
         const char *            seed,
-        edg_wlc_JobId **        subjobs)
+        edg_wlc_JobId **        subjobs,
+       char **                 wms_dn)
 {
-       char    *seq,*type_s;
+       char    *seq,*type_s,*wms_dn_s;
        edg_wll_LogLine logline = NULL;
-       int     ret = 0,n,count,fd;
+       int     ret = 0,n,count,fd,i;
        struct timeval sync_to;
        edg_wll_GssConnection   con_bkserver;
        edg_wll_PlainConnection con_lbproxy;
        fd_set fdset;
 
-       seq = type_s = NULL;
+       seq = type_s = wms_dn_s = NULL;
 
        edg_wll_ResetError(ctx);
        memcpy(&sync_to, &ctx->p_sync_timeout, sizeof sync_to);
                edg_wll_SetError(ctx,EINVAL,"edg_wll_RegisterJobProxy(): no jobtype specified");
                goto edg_wll_registerjobproxy_end;
        }
+       if (wms_dn) {
+               char *aux,*aux2;
+               aux2 = strdup("");
+               for (i=0; wms_dn[i]; i++) {
+                       asprintf(&aux,"%s\n%s",aux2,wms_dn[i]);
+                       free(aux2); aux2 = aux; aux = NULL;
+               }
+               wms_dn_s = strdup(aux2);
+               free(aux2); aux2 = NULL;
+       }
        if ((type == EDG_WLL_REGJOB_DAG || 
             type == EDG_WLL_REGJOB_PARTITIONED ||
             type == EDG_WLL_REGJOB_COLLECTION)
        /* format the RegJob event message */
        if (edg_wll_FormatLogLine(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,
                EDG_WLL_EVENT_REGJOB,&logline,
-               EDG_WLL_FORMAT_REGJOB,(char *)jdl,ns,"",type_s,num_subjobs,seed) != 0 ) {
+               EDG_WLL_FORMAT_REGJOB,(char *)jdl,ns,"",type_s,num_subjobs,seed,wms_dn_s) != 0 ) {
                edg_wll_UpdateError(ctx,EINVAL,"edg_wll_RegisterJobProxy(): edg_wll_FormatLogLine() error");
                goto edg_wll_registerjobproxy_end; 
        }       
 /**
  *-----------------------------------------------------------------------
  * Register one job with L&B Proxy service 
+ * \note simple wrapper around edg_wll_RegisterJobProxyMaster()
+ * this is new (!LB_SERIAL_REG) edg_wll_RegisterJobProxy 
+ *-----------------------------------------------------------------------
+ */
+int edg_wll_RegisterJobProxy(
+        edg_wll_Context         ctx,
+        glite_jobid_const_t     job,
+        enum edg_wll_RegJobJobtype     type,
+        const char *            jdl,
+        const char *            ns,
+        int                     num_subjobs,
+        const char *            seed,
+        edg_wlc_JobId **        subjobs)
+{
+        return edg_wll_RegisterJobProxyMaster(ctx,job,type,jdl,ns,num_subjobs,seed,subjobs,NULL);
+}
+
+/**
+ *-----------------------------------------------------------------------
+ * Proxy job registration with an extra ACL specifying WMS to acces the job 
+ * \note simple wrapper around edg_wll_RegisterJobProxyMaster()
+ *-----------------------------------------------------------------------
+ */
+int edg_wll_RegisterJobProxyACL(
+        edg_wll_Context         ctx,
+        glite_jobid_const_t     job,
+        enum edg_wll_RegJobJobtype      type,
+        const char *            jdl,
+        const char *            ns,
+        int                     num_subjobs,
+        const char *            seed,
+        edg_wlc_JobId **        subjobs,
+        char **                 wms_dn)
+{
+        return edg_wll_RegisterJobProxyMaster(ctx,job,type,jdl,ns,num_subjobs,seed,subjobs,wms_dn);
+}
+
+/**
+ *-----------------------------------------------------------------------
+ * Register one job with L&B Proxy service 
  * \note simple wrapper around edg_wll_RegisterJobMaster()
  * this is original edg_wll_RegisterJobProxy 
  *-----------------------------------------------------------------------
         edg_wlc_JobId **        subjobs)
 {
        /* first register with bkserver and then with L&B Proxy */
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,NULL);
 }
 
 #else /* LB_SERIAL_REG */
         edg_wlc_JobId **        subjobs)
 {
        /* first register with bkserver and then with L&B Proxy */
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,NULL);
+}
+
+int edg_wll_RegisterJobProxyACL(
+        edg_wll_Context         ctx,
+        glite_jobid_const_t     job,
+        enum edg_wll_RegJobJobtype     type,
+        const char *            jdl,
+        const char *            ns,
+        int                     num_subjobs,
+        const char *            seed,
+        edg_wlc_JobId **        subjobs,
+        char **                 wms_dn)
+{
+       /* first register with bkserver and then with L&B Proxy */
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_DIRECT | EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,wms_dn);
 }
 
 #endif /* LB_SERIAL_REG */
         const char *            seed,
         edg_wlc_JobId **        subjobs)
 {
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,NULL,num_subjobs,seed,subjobs,NULL);
 }
 
 /**
         const char *            seed,
         edg_wlc_JobId **        subjobs)
 {
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_LOCAL,job,type,jdl,ns,parent,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_LOCAL,job,type,jdl,ns,parent,num_subjobs,seed,subjobs,NULL);
 }
 
 /**
         const char *            seed,
         edg_wlc_JobId **        subjobs)
 {
-       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,parent,num_subjobs,seed,subjobs);
+       return edg_wll_RegisterJobMaster(ctx,EDG_WLL_LOGFLAG_PROXY,job,type,jdl,ns,parent,num_subjobs,seed,subjobs,NULL);
 }
 
 /**