public function execute($scheme = 'ALL', $request, $debug = 0, $keepGoing = false)
 {
     if (empty($scheme) || !is_array($request) || empty($request)) {
         return '';
     }
     $trunk_info = array();
     foreach ($request as $key => $value) {
         $key = preg_replace('/^agi_/', '', $key);
         $trunk_info[$key] = $value;
     }
     $this->out(sprintf(_("Scheme Asked is: %s"), $scheme));
     $this->out(sprintf(_("The DID is: %s"), $trunk_info['extension']));
     $this->out(sprintf(_("The CNUM is: %s"), $trunk_info['callerid']));
     $this->out(sprintf(_("The CNAME is: %s"), $trunk_info['calleridname']));
     //If ALL then run through all Schemes, else just the single one
     if ($scheme == 'ALL') {
         $schemes = $this->getAllPoweredSchemes();
     } else {
         $schemes[0] = array("name" => $scheme);
     }
     include __DIR__ . '/includes/superfecta_base.php';
     include __DIR__ . '/includes/processors/superfecta_multi.php';
     include __DIR__ . '/includes/processors/superfecta_single.php';
     global $db, $amp_conf, $astman;
     $options = array('db' => $this->db, 'amp_conf' => $amp_conf, 'astman' => $astman, 'debug' => 0, 'path_location' => __DIR__ . '/sources', 'trunk_info' => $trunk_info);
     foreach ($schemes as $s) {
         $this->out("");
         $this->out(sprintf(_("Starting scheme %s"), $s['name']));
         //reset these each time
         $cnum = $trunk_info['callerid'];
         $cnam = $trunk_info['calleridname'];
         $did = $trunk_info['extension'];
         $options['scheme_name'] = "base_" . $s['name'];
         $options['scheme_settings'] = $this->getScheme($s['name']);
         $options['module_parameters'] = $this->getSchemeAllModuleSettings($s['name']);
         switch ($options['scheme_settings']) {
             case 'superfecta_multi.php':
                 //TODO: This is broken and needs to be fixed, there are better ways to do it of course
                 //for now send all results back through to single
                 //$options['multifecta_id'] = isset($multifecta_id) ? $multifecta_id : null;
                 //$options['source'] = isset($source) ? $source : null;
                 //$superfecta = NEW \superfecta_multi($options);
                 //break;
             //TODO: This is broken and needs to be fixed, there are better ways to do it of course
             //for now send all results back through to single
             //$options['multifecta_id'] = isset($multifecta_id) ? $multifecta_id : null;
             //$options['source'] = isset($source) ? $source : null;
             //$superfecta = NEW \superfecta_multi($options);
             //break;
             case 'superfecta_single.php':
             default:
                 $superfecta = new \superfecta_single($options);
                 break;
         }
         $superfecta->setDebug($debug);
         $superfecta->setCLI(true);
         $superfecta->setDID($did);
         $superfecta->set_CurlTimeout($options['scheme_settings']['Curl_Timeout']);
         // Determine if this is the correct DID, if this scheme is limited to a DID.
         $rule_match = $superfecta->match_pattern_all(isset($options['scheme_settings']['DID']) ? $options['scheme_settings']['DID'] : '', $did);
         if ($rule_match['number']) {
             $this->out(sprintf(_("Matched DID Rule: %s with %s"), $rule_match['pattern'], $rule_match['number']));
         } elseif ($rule_match['status']) {
             $this->out(_("No matching DID rules. Skipping scheme"));
             continue;
         }
         // Determine if the CID matches any patterns defined for this scheme
         $rule_match = $superfecta->match_pattern_all(isset($options['scheme_settings']['CID_rules']) ? $options['scheme_settings']['CID_rules'] : '', $cnum);
         if ($rule_match['number']) {
             $this->out(sprintf(_("Matched CID Rule: %s with %s"), $rule_match['pattern'], $rule_match['number']));
             $cnum = $rule_match['number'];
             $this->out(sprintf(_("Changed CNUM to: %s"), $cnum));
         } elseif ($rule_match['status']) {
             $this->out(_("No matching CID rules. Skipping scheme"));
             continue;
         }
         //if a prefix lookup is enabled, look it up, and truncate the result to 10 characters
         ///Clean these up, set NULL values instead of blanks then don't check for ''
         $superfecta->set_Prefix('');
         if (isset($scheme_param['Prefix_URL']) && trim($scheme_param['Prefix_URL']) != '') {
             $start_time = $superfecta->mctime_float();
             $superfecta->set_Prefix($superfecta->get_url_contents(str_replace("[thenumber]", $cnum, $options['scheme_settings']['Prefix_URL'])));
             if ($superfecta->prefix != '') {
                 $this->out(sprintf(_("Prefix Url defined as: %s"), $superfecta->get_Prefix()));
             } else {
                 $this->out(_("Prefix Url defined but result was empty"));
             }
             $this->out(sprintf(_("Prefix Url result took %s seconds."), number_format(mctime_float() - $start_time, 4)));
         }
         $trunk_info['callerid'] = $cnum;
         $superfecta->set_TrunkInfo($trunk_info);
         if ($this->agi === null) {
             $callerid = $superfecta->web_debug();
         } else {
             $callerid = $superfecta->get_results();
         }
         $callerid = trim($callerid);
         $found = false;
         if (!empty($callerid)) {
             $found = true;
             //$first_caller_id = _utf8_decode($first_caller_id);
             $callerid = trim(strip_tags($callerid));
             if ($superfecta->isCharSetIA5()) {
                 $callerid = $superfecta->stripAccents($callerid);
             }
             //Why?
             $callerid = preg_replace("/[\";']/", "", $callerid);
             //limit caller id to the first 60 char
             $callerid = substr($callerid, 0, 60);
             //send off
             $superfecta->send_results($callerid);
         }
         //Set Spam text
         $spam_text = $superfecta->isSpam() ? $options['scheme_settings']['SPAM_Text'] : '';
         if ($superfecta->isSpam() && $options['scheme_settings']['SPAM_Text_Substitute'] == 'Y') {
             dbug($options['scheme_settings']);
             $callerid = $spam_text;
         } else {
             $callerid = $spam_text . " " . $superfecta->get_Prefix() . $callerid;
         }
         // Display issues on phones and CDR with special characters
         // convert CNAM to UTF-8 to fix
         if ($found && function_exists('mb_convert_encoding')) {
             $this->out("Converting result to UTF-8");
             $callerid = mb_convert_encoding($callerid, "UTF-8");
         }
         //Set Spam Destination
         $spam_dest = !empty($options['scheme_settings']['spam_interceptor']) && $options['scheme_settings']['spam_interceptor'] == 'Y' ? $options['scheme_settings']['spam_destination'] : '';
         $this->spamCount = $this->spamCount + (int) $superfecta->get_SpamCount();
         if (!empty($spam_dest) && $this->spamCount >= (int) $options['scheme_settings']['SPAM_threshold']) {
             $parts = explode(",", $spam_dest);
             $this->destination = $parts;
             //stop all processing at this point, the spam score is too high
             if (!$keepGoing) {
                 $this->out(sprintf(_("Spam Call, Sending call to: %s"), $spam_dest));
                 return $callerid;
             } else {
                 $this->out(sprintf(_("Call detected as spam, would send call to: %s"), $spam_dest));
             }
         }
         if (!empty($callerid)) {
             if (!$keepGoing) {
                 $this->out(sprintf(_("Setting caller id to: %s"), $callerid));
                 return $callerid;
             } else {
                 $this->out(sprintf(_("This scheme would set the caller id to: %s"), $callerid));
             }
         } else {
             $this->out(_("No callerid found"));
         }
     }
     if (empty($callerid) && !$keepGoing) {
         //No callerid so I guess?
         return $trunk_info['calleridname'];
     } elseif (empty($callerid) && $keepGoing) {
         return false;
     } elseif (!empty($callerid) && $keepGoing) {
         return $callerid;
     }
 }