diff --git a/config/pe/ClosedLoopControlName.drl b/config/pe/ClosedLoopControlName.drl
deleted file mode 100644
index 3273dc6..0000000
--- a/config/pe/ClosedLoopControlName.drl
+++ /dev/null
@@ -1,1223 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.controlloop;
-
-import org.onap.policy.controlloop.VirtualControlLoopEvent;
-import org.onap.policy.controlloop.VirtualControlLoopNotification;
-import org.onap.policy.controlloop.ControlLoopEventStatus;
-import org.onap.policy.controlloop.ControlLoopNotificationType;
-import org.onap.policy.controlloop.ControlLoopLogger;
-import org.onap.policy.controlloop.policy.PolicyResult;
-import org.onap.policy.controlloop.policy.ControlLoopPolicy;
-import org.onap.policy.controlloop.policy.Policy;
-import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
-import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
-import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager;
-import org.onap.policy.controlloop.actor.so.SOActorServiceProvider;
-import org.onap.policy.appc.Request;
-import org.onap.policy.appc.Response;
-import org.onap.policy.appc.CommonHeader;
-import org.onap.policy.appclcm.LCMRequestWrapper;
-import org.onap.policy.appclcm.LCMResponseWrapper;
-import org.onap.policy.appclcm.LCMRequest;
-import org.onap.policy.appclcm.LCMResponse;
-import org.onap.policy.appclcm.LCMCommonHeader;
-import org.onap.policy.vfc.VFCRequest;
-import org.onap.policy.vfc.VFCResponse;
-import org.onap.policy.vfc.VFCManager;
-import org.onap.policy.so.SOManager;
-import org.onap.policy.so.SORequest;
-import org.onap.policy.so.SORequestStatus;
-import org.onap.policy.so.SORequestDetails;
-import org.onap.policy.so.SOModelInfo;
-import org.onap.policy.so.SOCloudConfiguration;
-import org.onap.policy.so.SORequestInfo;
-import org.onap.policy.so.SORequestParameters;
-import org.onap.policy.so.SORelatedInstanceListElement;
-import org.onap.policy.so.SORelatedInstance;
-import org.onap.policy.so.SOResponse;
-import org.onap.policy.guard.PolicyGuard;
-import org.onap.policy.guard.PolicyGuard.LockResult;
-import org.onap.policy.guard.TargetLock;
-import org.onap.policy.guard.GuardResult;
-import org.onap.policy.guard.PolicyGuardRequest;
-import org.onap.policy.guard.PolicyGuardResponse;
-import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes;
-import org.onap.policy.guard.PolicyGuardXacmlHelper;
-
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-
-import java.time.Instant;
-import java.util.LinkedList;
-import java.util.Iterator;
-
-import org.onap.policy.drools.system.PolicyEngine;
-
-declare Params
-  closedLoopControlName : String
-  controlLoopYaml : String
-end
-
-
-declare OperationTimer
-  closedLoopControlName : String
-  requestID : String
-  delay : String
-end
-
-declare ControlLoopTimer
-  closedLoopControlName : String
-  requestID : String
-  delay : String
-end
-
-/*
-*
-* Called once and only once to insert the parameters into working memory for this Closed Loop policy.
-*
-*/
-rule "${policyName}.SETUP"
-    when
-    then
-    
-    Params params = new Params();
-    params.setClosedLoopControlName("${closedLoopControlName}");
-    params.setControlLoopYaml("${controlLoopYaml}");
-    insert(params);
-
-    // Note: globals have bad behavior when persistence is used,
-    //       hence explicitly getting the logger vs using a global
-    
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {} : YAML=[{}]", params.getClosedLoopControlName(), drools.getRule().getName(), params.getControlLoopYaml());
-    
-    String sqlDbUsername = PolicyEngine.manager.getEnvironmentProperty("sql.db.username");
-    
-    String aaiUrl = PolicyEngine.manager.getEnvironmentProperty("aai.url");
-    String aaiUsername = PolicyEngine.manager.getEnvironmentProperty("aai.username");
-    String aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
-    
-    String soUrl =PolicyEngine.manager.getEnvironmentProperty("so.url");
-    String soUsername = PolicyEngine.manager.getEnvironmentProperty("so.username");
-    String soPassword = PolicyEngine.manager.getEnvironmentProperty("so.password");
-    
-    String vfcUrl =PolicyEngine.manager.getEnvironmentProperty("vfc.url");
-    String vfcUsername = PolicyEngine.manager.getEnvironmentProperty("vfc.username");
-    String vfcPassword = PolicyEngine.manager.getEnvironmentProperty("vfc.password");
-    
-    String guardUrl = PolicyEngine.manager.getEnvironmentProperty("guard.url");
-    String guardUsername = PolicyEngine.manager.getEnvironmentProperty("pdpx.username");
-    String guardPassword = PolicyEngine.manager.getEnvironmentProperty("pdpx.password");
-    String guardJdbcUrl = PolicyEngine.manager.getEnvironmentProperty("guard.jdbc.url");
-    String guardDisabled = PolicyEngine.manager.getEnvironmentProperty("guard.disabled");
-    
-    logger.info("{}: {} : AAI=[{}:{}]", params.getClosedLoopControlName(), drools.getRule().getName(), aaiUrl, aaiUsername);
-    logger.info("{}: {} : SO=[{}:{}]", params.getClosedLoopControlName(), drools.getRule().getName(), soUrl, soUsername);
-    logger.info("{}: {} : VFC=[{}:{}]", params.getClosedLoopControlName(), drools.getRule().getName(), vfcUrl, vfcUsername);
-    logger.info("{}: {} : GUARD=[{}:{}:{}:{}]", params.getClosedLoopControlName(), drools.getRule().getName(), guardUrl, guardUsername, guardJdbcUrl, guardDisabled);
-    logger.info("{}: {} : DB=[{}]", params.getClosedLoopControlName(), drools.getRule().getName(), sqlDbUsername);
-end
-
-/*
-*
-* This rule responds to DCAE Events where there is no manager yet. Either it is
-* the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
-*
-*/
-rule "${policyName}.EVENT"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
-    then
- 
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    
-    try {
-      
-        //
-        // Check the event, because we need it to not be null when
-        // we create the ControlLoopEventManager. The ControlLoopEventManager
-        // will do extra syntax checking as well check if the closed loop is disabled.
-        //
-        if ($event.requestID == null) {
-            VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-            notification.notification = ControlLoopNotificationType.REJECTED;
-            notification.from = "policy";
-            notification.message = "Missing requestID";
-            notification.policyName = drools.getRule().getName();
-            notification.policyScope = "${policyScope}";
-            notification.policyVersion = "${policyVersion}";
-            
-            //
-            // Let interested parties know
-            //
-            PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-            
-            //
-            // Retract it from memory
-            //
-            retract($event);
-        } else {
-            //
-            // Create an EventManager
-            //
-            ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
-            //
-            // Determine if EventManager can actively process the event (i.e. syntax, is_closed_loop_disabled checks etc.)
-            //
-            VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
-            notification.from = "pdp-0001-controller=controlloop"; // Engine.getInstanceName()
-            notification.policyName = drools.getRule().getName();
-            notification.policyScope = "${policyScope}";
-            notification.policyVersion = "${policyVersion}";
-            //
-            // Are we actively pursuing this event?
-            //
-            if (notification.notification == ControlLoopNotificationType.ACTIVE) {
-                //
-                // Insert Event Manager into memory, this will now kick off processing.
-                //
-                insert(manager);
-                //
-                // Let interested parties know
-                //
-                PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-                //
-                // Setup the Overall Control Loop timer
-                //
-                ControlLoopTimer clTimer = new ControlLoopTimer();
-                clTimer.setClosedLoopControlName($event.closedLoopControlName);
-                clTimer.setRequestID($event.requestID.toString());
-                clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
-                //
-                // Insert it
-                //
-                insert(clTimer);
-            } else {
-                //
-                // Let interested parties know
-                //
-                PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-                //
-                // Retract it from memory
-                //
-                retract($event);
-            }
-            
-            //
-            // Now that the manager is inserted into Drools working memory, we'll wait for
-            // another rule to fire in order to continue processing. This way we can also
-            // then screen for additional ONSET and ABATED events for this RequestID.
-            //
-        }
-    } catch (Exception e) {
-        logger.warn("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName(), e);
-        
-        VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-        notification.notification = ControlLoopNotificationType.REJECTED;
-        notification.message = "Exception occurred " + e.getMessage();
-        notification.policyName = drools.getRule().getName();
-        notification.policyScope = "${policyScope}";
-        notification.policyVersion = "${policyVersion}";
-        //
-        //
-        //
-        PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-        //
-        // Retract the event
-        //
-        retract($event);
-    }
-end
-
-/*
-*
-* This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
-* is now created. We can start processing the yaml specification via the Event Manager.
-*
-*/
-rule "${policyName}.EVENT.MANAGER"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}: event={} manager={} clTimer={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $clTimer);
-    //
-    // Check which event this is.
-    //
-    ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
-
-    //
-    // Check what kind of event this is
-    //
-    if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
-        //
-        // We don't care about subsequent onsets
-        //
-        logger.info("{}: {}: subsequent onset", 
-                    $params.getClosedLoopControlName(), drools.getRule().getName());
-        retract($event);
-        return;
-    }
-    if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
-        //
-        // Ignore any bad syntax events
-        //
-        logger.warn("{}: {}: syntax error", 
-                    $params.getClosedLoopControlName(), drools.getRule().getName());
-        retract($event);
-        return;
-    }
-    //
-    // We only want the initial ONSET event in memory,
-    // all the other events need to be retracted to support
-    // cleanup and avoid the other rules being fired for this event.
-    //
-    if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
-        logger.warn("{}: {}: no first onset", 
-                    $params.getClosedLoopControlName(), drools.getRule().getName());
-        retract($event);
-    }
-    
-    logger.debug("{}: {}: target={}", $params.getClosedLoopControlName(), 
-                 drools.getRule().getName(), $event.target);
-    //
-    // Now start seeing if we need to process this event
-    //
-    try {
-        //
-        // Check if this is a Final Event
-        //
-        VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
-    
-    
-        if (notification != null) {
-            //
-            // Its final, but are we waiting for abatement?
-            //
-            if ($manager.getNumAbatements() > 0) {
-                logger.info("{}: {}: abatement received for {}.  Closing the control loop", 
-                            $params.getClosedLoopControlName(), drools.getRule().getName(), 
-                            $event.requestID);
-                notification.from = "policy";
-                notification.policyName = drools.getRule().getName();
-                notification.policyScope = "${policyScope}";
-                notification.policyVersion = "${policyVersion}";
-                //
-                // In this case, we are done
-                //
-                PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-                //
-                // Unlock the target
-                //
-                TargetLock lock = $manager.unlockCurrentOperation();
-                if (lock != null) {
-                    logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(), 
-                                 drools.getRule().getName(), lock);
-                    retract(lock);
-                }
-                //
-                // Retract everything from memory
-                //
-                logger.info("{}: {}: retracting onset, manager, and timer", 
-                            $params.getClosedLoopControlName(), drools.getRule().getName());
-                
-                retract($manager.getOnsetEvent());
-                retract($manager);
-                retract($clTimer);
-                //
-                // TODO - what if we get subsequent Events for this RequestID?
-                // By default, it will all start over again. May be confusing for Ruby.
-                // Or, we could track this and then subsequently ignore the events
-                //
-            } else {
-                //
-                // Check whether we need to wait for abatement
-                //
-                if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
-                  logger.info("{}: {}: waiting for abatement ..", 
-                              $params.getClosedLoopControlName(), drools.getRule().getName());
-                } else {
-                  logger.info("{}: {}: no abatement expect for {}.  Closing the control loop", 
-                              $params.getClosedLoopControlName(), drools.getRule().getName(), 
-                              $event.requestID);
-                  
-                  notification.from = "policy";
-                  notification.policyName = drools.getRule().getName();
-                  notification.policyScope = "${policyScope}";
-                  notification.policyVersion = "${policyVersion}";
-                  
-                  //
-                  // In this case, we are done
-                  //
-                  PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-                  //
-                  // Unlock the target
-                  //
-                  TargetLock lock = $manager.unlockCurrentOperation();
-                  if (lock != null) {
-                      logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(), 
-                                  drools.getRule().getName(), lock);
-                      retract(lock);
-                  }
-                  //
-                  // Retract everything from memory
-                  //
-                  logger.info("{}: {}: retracting onset, manager, and timer", 
-                              $params.getClosedLoopControlName(), drools.getRule().getName());
-                  
-                  retract($manager.getOnsetEvent());
-                  retract($manager);
-                  retract($clTimer);
-                }
-            }
-        } else {
-            //
-            // NOT final, so let's ask for the next operation
-            //
-            ControlLoopOperationManager operation = $manager.processControlLoop();
-            if (operation != null) {
-              logger.info("{}: {}: starting operation={}", 
-                          $params.getClosedLoopControlName(), drools.getRule().getName(), 
-                          operation);
-              //
-              // insert into memory
-              //
-              insert(operation);
-              //
-              // insert operation timeout object
-              //
-              OperationTimer opTimer = new OperationTimer();
-              opTimer.setClosedLoopControlName($event.closedLoopControlName);
-              opTimer.setRequestID($event.requestID.toString());
-              opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
-              insert(opTimer);
-      
-              //
-              // Let's ask for a lock right away
-              //
-              LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
-              if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
-                logger.info("{}: {}: guard lock acquired={}", 
-                            $params.getClosedLoopControlName(), drools.getRule().getName(), 
-                            result.getB());
-                
-                //
-                // Insert into memory
-                //
-                insert(result.getB());
-              }
-            } else {
-                //
-                // Probably waiting for abatement
-                //
-              logger.info("{}: {}: no operation, probably waiting for abatement", 
-                          $params.getClosedLoopControlName(), drools.getRule().getName());
-            }
-        }
-    } catch (Exception e) {
-      logger.warn("{}: {}: unexpected", 
-                  $params.getClosedLoopControlName(), 
-                  drools.getRule().getName(), e);
-
-      //
-      // TODO should we abort if we get an exception?
-      //
-    }
-        
-end
-
-
-
-/*
-*
-* 
-*
-*/
-rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
-    timer (int: 5s 5s)
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        not ( TargetLock (requestID == $event.requestID) )
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}: event={} manager={} operation={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation);
-    
-    //
-    // Need to ask for a Lock
-    //
-    LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
-    if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
-      logger.info("{}: {}: guard lock acquired={}", 
-                  $params.getClosedLoopControlName(), drools.getRule().getName(), 
-                  result.getB());
-      
-        //
-        // Insert into memory
-        //
-        insert(result.getB());
-    }
-    
-end
-
-/*
-*
-* Guard Permitted, let's send request to the actor.
-*
-*/
-rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
-        $lock : TargetLock (requestID == $event.requestID)
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}: event={} manager={} operation={} lock={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation, $lock);    
-
-    Object request = $operation.startOperation($event);
-    
-    if (request != null) {
-      logger.debug("{}: {}: starting operation ..", 
-                   $params.getClosedLoopControlName(), drools.getRule().getName());
-      //
-      // Tell interested parties we are performing this Operation
-      //
-      VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-      notification.notification = ControlLoopNotificationType.OPERATION;
-      notification.message = $operation.getOperationMessage();
-      notification.history = $operation.getHistory();
-      notification.from = "policy";
-      notification.policyName = drools.getRule().getName();
-      notification.policyScope = "${policyScope}";
-      notification.policyVersion = "${policyVersion}";
-      
-      PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-      
-      switch ($operation.policy.getActor()){
-          
-          case "APPC":
-      
-              if (request instanceof Request) {
-                  PolicyEngine.manager.deliver("APPC-CL", request);
-              }
-              else if (request instanceof LCMRequestWrapper) {
-                  PolicyEngine.manager.deliver("APPC-LCM-READ", request);
-              }
-              break;
-          case "SO":
-              // at this point the AAI named query request should have already been made, the response recieved and used
-              // in the construction of the SO Request which is stored in operationRequest
-              
-              if(request instanceof SORequest) {
-                  // Call SO. The response will be inserted into memory once it's received 
-                  SOActorServiceProvider.sendRequest(drools.getWorkingMemory(), request);                        
-              }
-              break;
-          case "VFC":
-              if (request instanceof VFCRequest) {
-                  // Start VFC thread
-                  Thread t = new Thread(new VFCManager(drools.getWorkingMemory(), (VFCRequest)request));
-                  t.start();
-              }          
-              break;
-      }
-    } else {
-      //
-      // What happens if its null?
-      //
-      logger.warn("{}: {}: unexpected null operation request", 
-                  $params.getClosedLoopControlName(), 
-                  drools.getRule().getName());
-    }
-end
-
-
-/*
-*
-* We were able to acquire a lock so now let's ask Xacml Guard whether 
-* we are allowed to proceed with the request to the actor.
-*
-*/
-rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "NONE" )
-        $lock : TargetLock (requestID == $event.requestID)
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}: event={} manager={} operation={} lock={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation, $lock);
-    
-    //
-    // Sending notification that we are about to query Guard ("DB write - start operation")
-    //
-    VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-    notification.notification = ControlLoopNotificationType.OPERATION;
-    notification.message = "Sending guard query for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe();
-    notification.history = $operation.getHistory();
-    notification.from = "policy";
-    notification.policyName = drools.getRule().getName();
-    notification.policyScope = "${policyScope}";
-    notification.policyVersion = "${policyVersion}";
-    
-    PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-        
-    //
-    // Now send Guard Request to XACML Guard. In order to bypass the call to Guard, 
-    // just change guardEnabled to false.
-    // 
-    // In order to use REST XACML, provide a URL instead of "" as a second argument 
-    // to the CallGuardTask() and set the first argument to null 
-    // (instead of XacmlPdpEngine).
-    //
-    
-    // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
-    boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
-    
-    if(guardEnabled){
-    
-        Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
-                                                        drools.getWorkingMemory(),
-                                                        $event.closedLoopControlName,
-                                                        $operation.policy.getActor().toString(),
-                                                        $operation.policy.getRecipe(),
-                                                        $manager.getTargetInstance($operation.policy),
-                                                        //$event.target,
-                                                        $event.requestID.toString()
-                                                        ));
-        t.start();
-    }
-    else{
-        insert(new PolicyGuardResponse("Permit", $event.requestID, $operation.policy.getRecipe()));
-    }
-
-end
-
-//
-// This rule will be triggered when a thread talking to the XACML Guard inserts a 
-// guardResponse object into the working memory
-//
-rule "${policyName}.GUARD.RESPONSE"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) 
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        $lock : TargetLock (requestID == $event.requestID)
-        $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-        $guardResponse : PolicyGuardResponse(requestID == $event.requestID, $operation.policy.recipe == operation)
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}", 
-                 $params.getClosedLoopControlName(), drools.getRule().getName(),
-                 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
-        
-        
-    //we will permit the operation if there was no Guard for it
-    if("Indeterminate".equalsIgnoreCase($guardResponse.result)){
-        $guardResponse.result = "Permit";
-    }
-    
-    //
-    // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
-    //
-    VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-    notification.notification = ControlLoopNotificationType.OPERATION;
-    notification.message = "Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe() + " is " + $guardResponse.result;
-    notification.history = $operation.getHistory();
-    notification.from = "policy";
-    notification.policyName = drools.getRule().getName();
-    notification.policyScope = "${policyScope}";
-    notification.policyVersion = "${policyVersion}";
-    
-    PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-    
-    if("Permit".equalsIgnoreCase($guardResponse.result)){
-    
-        modify($operation){setGuardApprovalStatus($guardResponse.result)};
-    }
-    else {
-        //This is the Deny case
-        $operation.setOperationHasGuardDeny();
-        retract($opTimer);
-        retract($operation);
-        modify($manager) {finishOperation($operation)};
-    }
-    
-    retract($guardResponse);
-            
-end
-
-/*
-*
-* This rule responds to APPC Response Events
-*
-* I would have like to be consistent and write the Response like this:
-* $response : Response( CommonHeader.RequestID == $onset.requestID )
-*
-* However, no compile error was given. But a runtime error was given. I think
-* because drools is confused between the classname CommonHeader vs the property CommonHeader.
-*
-*/
-rule "${policyName}.APPC.RESPONSE"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) 
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-        $lock : TargetLock (requestID == $event.requestID)
-        $response : Response( getCommonHeader().RequestID == $event.requestID )
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", 
-                 $params.getClosedLoopControlName(), drools.getRule().getName(),
-                 $event, $manager, $operation, $lock, $opTimer, $response);
-    //
-    // Get the result of the operation
-    //
-    PolicyResult policyResult = $operation.onResponse($response);
-    if (policyResult != null) {
-        logger.debug("{}: {}: operation finished - result={}", 
-                    $params.getClosedLoopControlName(), drools.getRule().getName(),
-                    policyResult);
-        //
-        // This Operation has completed, construct a notification showing our results. (DB write - end operation)
-        //
-        VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-        notification.from = "policy";
-        notification.policyName = drools.getRule().getName();
-        notification.policyScope = "${policyScope}";
-        notification.policyVersion = "${policyVersion}";
-        notification.message = $operation.getOperationHistory();
-        notification.history = $operation.getHistory();
-        if (policyResult.equals(PolicyResult.SUCCESS)) {
-            notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
-            //
-            // Let interested parties know
-            //
-            PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-        } else {
-            notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
-            //
-            // Let interested parties know
-            //
-            PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-        }
-        //
-        // Ensure the operation is complete
-        //
-        if ($operation.isOperationComplete() == true) {
-            //
-            // It is complete, remove it from memory
-            //
-            retract($operation);
-            //
-            // We must also retract the timer object
-            // NOTE: We could write a Rule to do this
-            //
-            retract($opTimer);
-            //
-            // Complete the operation
-            //
-            modify($manager) {finishOperation($operation)};
-        } else {
-            //
-            // Just doing this will kick off the LOCKED rule again
-            //
-            modify($operation) {};
-        }
-    } else {
-        //
-        // Its not finished yet (i.e. expecting more Response objects)
-        //
-        // Or possibly it is a leftover response that we timed the request out previously
-        //
-    }
-    //
-    // We are going to retract these objects from memory
-    //
-    retract($response);
-end
-
-/*
-*
-* The problem with Responses is that they don't have a controlLoopControlName
-* field in them, so the only way to attach them is via RequestID. If we have multiple
-* control loop .drl's loaded in the same container, we need to be sure the cleanup
-* rules don't remove Responses for other control loops.
-*
-*/
-rule "${policyName}.APPC.RESPONSE.CLEANUP"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $response : Response($id : getCommonHeader().RequestID )
-        not ( VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) 
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: orphan appc response={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(), $id);
-        
-    //
-    // Retract it
-    //
-    retract($response);
-end
-
-/*
-*
-* This rule responds to APPC Response Events using the new LCM interface provided by appc
-*
-*/
-rule "${policyName}.APPC.LCM.RESPONSE"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) 
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-        $lock : TargetLock (requestID == $event.requestID)
-        $response : LCMResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.requestID )
-    then
-
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation, $lock, $operation, $opTimer, $response);
-    
-    //
-    // Get the result of the operation
-    //
-    PolicyResult policyResult = $operation.onResponse($response);
-    if (policyResult != null) {
-      logger.debug("{}: {}: operation finished - result={}", 
-                  $params.getClosedLoopControlName(), drools.getRule().getName(),
-                  policyResult);
-      
-      //
-      // This Operation has completed, construct a notification showing our results. (DB write - end operation)
-      //
-      VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-      notification.from = "policy";
-      notification.policyName = drools.getRule().getName();
-      notification.policyScope = "${policyScope}";
-      notification.policyVersion = "${policyVersion}";
-      notification.message = $operation.getOperationHistory();
-      notification.history = $operation.getHistory();
-      if (policyResult.equals(PolicyResult.SUCCESS)) {
-          notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
-      } else {
-          notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
-      }
-      PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-      //
-      // Ensure the operation is complete
-      //
-      if ($operation.isOperationComplete() == true) {
-          //
-          // It is complete, remove it from memory
-          //
-          retract($operation);
-          //
-          // We must also retract the timer object
-          // NOTE: We could write a Rule to do this
-          //
-          retract($opTimer);
-          //
-          // Complete the operation
-          //
-          modify($manager) {finishOperation($operation)};
-      } else {
-          //
-          // Just doing this will kick off the LOCKED rule again
-          //
-          modify($operation) {};
-      }
-    } else {
-        //
-        // Its not finished yet (i.e. expecting more Response objects)
-        //
-        // Or possibly it is a leftover response that we timed the request out previously
-        //
-    }
-    //
-    // We are going to retract these objects from memory
-    //
-    retract($response);
-end
-
-/*
-*
-* Clean Up any lingering LCM reponses
-*
-*/
-rule "${policyName}.APPC.LCM.RESPONSE.CLEANUP"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $response : LCMResponseWrapper($id : getBody().getCommonHeader().getRequestId )
-        not ( VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) 
-    then
-    
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: orphan appc response={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(), $id);
-    //
-    // Retract it
-    //
-    retract($response);
-end
-
-/*
-*
-* This rule responds to SO Response Events
-*
-*/
-rule "${policyName}.SO.RESPONSE"
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-        $lock : TargetLock (requestID == $event.requestID)
-        $response : SOResponse( requestReferences.requestId.toString() == $event.requestID.toString() )  
-    then
-        
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation, $lock, $operation, $opTimer, $response);
-        
-    // Get the result of the operation
-    //
-    PolicyResult policyResult = $operation.onResponse($response);
-    if (policyResult != null) {
-        logger.debug("{}: {}: operation finished - result={}", 
-                    $params.getClosedLoopControlName(), drools.getRule().getName(),
-                    policyResult);
-      
-        //
-        // This Operation has completed, construct a notification showing our results
-        //
-        VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-        notification.from = "policy";
-        notification.policyName = drools.getRule().getName();
-        notification.policyScope = "${policyScope}";
-        notification.policyVersion = "${policyVersion}";
-        notification.message = $operation.getOperationHistory();
-        notification.history = $operation.getHistory();
-        if (policyResult.equals(PolicyResult.SUCCESS)) {
-            notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
-        } else {
-            notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
-
-        }
-        PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-        //
-        // Ensure the operation is complete
-        //
-        if ($operation.isOperationComplete() == true) {
-            //
-            // It is complete, remove it from memory
-            //
-            retract($operation);
-            //
-            // We must also retract the timer object
-            // NOTE: We could write a Rule to do this
-            //
-            retract($opTimer);
-            //
-            // Complete the operation
-            //
-            modify($manager) {finishOperation($operation)};
-        } else {
-            //
-            // Just doing this will kick off the LOCKED rule again
-            //
-            modify($operation) {};
-        }
-    } else {
-        //
-        // Its not finished yet (i.e. expecting more Response objects)
-        //
-        // Or possibly it is a leftover response that we timed the request out previously
-        //
-    }
-    //
-    // We are going to retract these objects from memory
-    //
-    retract($response);
-
-end
-
-/*
-*
-* This rule responds to VFC Response Events
-*
-*/
-rule "${policyName}.VFC.RESPONSE"
-	when
-		$params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-		$event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
-		$manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
-		$operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-		$opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
-        $lock : TargetLock (requestID == $event.requestID)
-		$response : VFCResponse( requestId.toString() == $event.requestID.toString() )	
-	then
-		Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    	logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    	logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", 
-                	$params.getClosedLoopControlName(), drools.getRule().getName(),
-                	$event, $manager, $operation, $lock, $operation, $opTimer, $response);
-		
-		// Get the result of the operation
-		//
-		PolicyResult policyResult = $operation.onResponse($response);
-		if (policyResult != null) {
-			//
-			// This Operation has completed, construct a notification showing our results
-			//
-			VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-			notification.from = "policy";
-			notification.policyName = drools.getRule().getName();
-			notification.policyScope = "${policyScope}";
-			notification.policyVersion = "${policyVersion}";
-			notification.message = $operation.getOperationHistory();
-			notification.history = $operation.getHistory();
-			//
-			// Ensure the operation is complete
-			//
-			if ($operation.isOperationComplete() == true) {
-				//
-				// It is complete, remove it from memory
-				//
-				retract($operation);
-				//
-				// We must also retract the timer object
-				// NOTE: We could write a Rule to do this
-				//
-				retract($opTimer);
-				//
-				// Complete the operation
-				//
-				modify($manager) {finishOperation($operation)};
-			} else {
-				//
-				// Just doing this will kick off the LOCKED rule again
-				//
-				modify($operation) {};
-			}
-		} else {
-			//
-			// Its not finished yet (i.e. expecting more Response objects)
-			//
-			// Or possibly it is a leftover response that we timed the request out previously
-			//
-		}
-		//
-		// We are going to retract these objects from memory
-		//
-		retract($response);
-
-end
-
-/*
-*
-* This is the timer that manages the timeout for an individual operation.
-*
-*/
-rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT"
-    timer (expr: $to )
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
-        $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
-        $lock : TargetLock (requestID == $event.requestID)
-    then
-    
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-    logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}", 
-                $params.getClosedLoopControlName(), drools.getRule().getName(),
-                $event, $manager, $operation, $lock, $operation, $opTimer);
-    
-    //
-    // Tell it its timed out
-    //
-    $operation.setOperationHasTimedOut();
-    //
-    // Create a notification for it ("DB Write - end operation")
-    //
-    VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
-    notification.from = "policy";
-    notification.policyName = drools.getRule().getName();
-    notification.policyScope = "${policyScope}";
-    notification.policyVersion = "${policyVersion}";
-    notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
-    notification.message = $operation.getOperationHistory();
-    notification.history = $operation.getHistory();
-    //
-    // Let interested parties know
-    //
-    PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-    //
-    // Get rid of the timer
-    //
-    retract($opTimer);
-    //
-    // Ensure the operation is complete
-    //
-    if ($operation.isOperationComplete() == true) {
-        //
-        // It is complete, remove it from memory
-        //
-        retract($operation);
-        //
-        // Complete the operation
-        //
-        modify($manager) {finishOperation($operation)};
-    } else {
-        //
-        // Just doing this will kick off the LOCKED rule again
-        //
-        modify($operation) {};
-    }
-end
-
-/*
-*
-* This is the timer that manages the overall control loop timeout.
-*
-*/
-rule "${policyName}.EVENT.MANAGER.TIMEOUT"
-    timer (expr: $to )
-    when
-        $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
-        $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
-        $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
-        $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
-        $operations : LinkedList()
-                        from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID ) )
-        $opTimers : LinkedList()
-                        from collect( OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() ) )
-        $locks : LinkedList()
-                        from collect( TargetLock (requestID == $event.requestID) )
-    then
-    
-    Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
-    logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
-
-    if ($operations == null) {
-      logger.debug("{}: {}: event={} manager={} clTimer={} operations=0", 
-                  $params.getClosedLoopControlName(), drools.getRule().getName(),
-                  $event, $manager, $clTimer);
-    } else {
-      logger.debug("{}: {}: event={} manager={} clTimer={} operations={}", 
-                  $params.getClosedLoopControlName(), drools.getRule().getName(),
-                  $event, $manager, $clTimer, $operations.size());
-    }
-    //
-    // Tell the Event Manager it has timed out
-    //
-    VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
-    if (notification != null) {
-        notification.from = "policy";
-        notification.policyName = drools.getRule().getName();
-        notification.policyScope = "${policyScope}";
-        notification.policyVersion = "${policyVersion}";
-        //
-        // Let interested parties know
-        //
-        PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
-    }
-    //
-    // Retract EVERYTHING
-    //
-    retract($event);
-    retract($manager);
-    retract($clTimer);
-    if ($operations != null && $operations.size() > 0) {
-        Iterator<ControlLoopOperationManager> iter = $operations.iterator();
-        while (iter.hasNext()) {
-            ControlLoopOperationManager manager = iter.next();
-            retract(manager);
-        }
-    }
-    if ($opTimers != null && $opTimers.size() > 0) {
-        Iterator<OperationTimer> iter = $opTimers.iterator();
-        while (iter.hasNext()) {
-            OperationTimer opTimer = iter.next();
-            retract(opTimer);
-        }
-    }
-    if ($locks != null && $locks.size() > 0) {
-        Iterator<TargetLock> iter = $locks.iterator();
-        while (iter.hasNext()) {
-            TargetLock lock = iter.next();
-            //
-            // Ensure we release the lock
-            //
-            PolicyGuard.unlockTarget(lock);
-            //
-            //
-            //
-            retract(lock);
-        }
-    }
-end
