static function getDemos() {
   $da = get_instances_of('FDDemo');
   $rv = array();
   foreach($da as $className) {
     $rc = new ReflectionClass($className);
     $rm = $rc->getMethod('getDescription');
     $desc = $rm->invoke(null);
     $rv[$className] = $desc;
   }
   return $rv;
 }
  /**
   * Create new request from HTTP parameters.
   * This method is used by ActionController to parse HTTP parameters to build initial Request
   * All instances of RequestAdaptor type will be queried and one that is
   * capable of processing content type of the request data will be instantiated.
   * Later the Request will query the Adaptor for parameters.
   *
   * <b>Note</b><br/>
   * This method is <i>always</i> called by the ActionController on every request.
   * @return  Request  request created from HTTP parameters (GET/POST/COOKIE and session referer)
   * @throws  ConfigurationException  if the config option <tt>locationRewriter</tt> specifies non-existent <class>LocationRewriter</class> 
   */
  static function parseHTTP() {
    // Create the URL
    $prot = split('/', $_SERVER['SERVER_PROTOCOL']);
    self::$URL = strtolower($prot[0]) . '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['PHP_SELF'];
    
    // Fake HTTP headers from $_SERVER and $_ENV
    $headers = array();
    foreach($_SERVER as $k=>$v) {
      if(substr($k, 0, 5) == 'HTTP_') {
        $headers[str_replace('_', '-', substr($k, 5))] = $v;
      } else {
        if($k == 'CONTENT_TYPE' || $k == 'CONTENT_LENGTH') {
          $headers[str_replace('_', '-', $k)] = $v;
        }
      }
    }

    // Get request method 
    $method = strToUpper($_SERVER['REQUEST_METHOD']) == 'POST' ? self::METHOD_POST : self::METHOD_GET;
    
    // Find proper request adaptor for POST methods
    $parameters = array();
    if($method == Request::METHOD_POST) {
      $ctype = $headers['CONTENT-TYPE'];
      $rads = get_instances_of('RequestAdaptor');
      foreach($rads as $ra) {
        $rac = new ReflectionClass($ra);
        $m = $rac->getMethod('isSupportedContentType');
        if($m->invoke(null, $ctype)) {
          $requestAdaptor = $rac->newInstance();
          $parameters = $requestAdaptor->getParameters($headers);
          break;
        }
      }
    } else {     
      // Decode the possibly encoded query string with the LocationRewriter
      $pkg = Package::getPackageByName('freeform');
      if($lrc = $pkg->getProperty('locationRewriter')) {
        try {
          $lrrc = new ReflectionClass($lrc);
          $lrm = $lrrc->getMethod('decode');
          $parameters = $lrm->invoke(null, $_SERVER['QUERY_STRING']);
        } catch(ReflectionException $re) {
          throw new ConfigurationException('freeform', 'locationRewriter', 'denotes non-existent class ' . $lrc);
        }
      } else {
        $parameters = $_GET;
      }
      if(get_magic_quotes_gpc()) {
        array_walk_recursive($parameters, 'strip_slashes_gpc');
      }
    }
    
    if(get_magic_quotes_gpc()) {
      array_walk_recursive($_COOKIE, 'strip_slashes_gpc');
    }
    
    return new Request($parameters, $_COOKIE, $headers, $method);
  }