You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by nd...@apache.org on 2015/05/01 23:33:16 UTC

[29/57] [partial] airavata-php-gateway git commit: AIRAVATA 1632 + Job Description for Admin Dashboard

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/public/js/script.js
----------------------------------------------------------------------
diff --git a/public/js/script.js b/public/js/script.js
new file mode 100644
index 0000000..be0826e
--- /dev/null
+++ b/public/js/script.js
@@ -0,0 +1,323 @@
+function getAccodrionCode()
+{
+	return '<div class="panel-group" id="accordion"> \
+  <div class="panel panel-default"> \
+    <div class="panel-heading">\
+      <h4 class="panel-title">\
+        <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">\
+          Collapsible Group Item #1\
+        </a>\
+      </h4>\
+    </div>\
+    <div id="collapseOne" class="panel-collapse collapse in">\
+      <div class="panel-body">\
+        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably havent heard of them accusamus labore sustainable VHS.\
+      </div>\
+    </div>\
+  </div>';
+}
+
+$(document).ready( function(){
+
+  //making the previously opened tab open again on page reload/modifications.
+  var urlArray = window.location.href.split("#");
+  var openTab = urlArray[1];
+  $('a[href="#' + openTab + '"]').click();
+  //tab open code ends here.
+
+	$(".add-queue").click( function(){
+		$(this).before( $(".queue-block").html() );
+	});
+
+  $(".add-alias").click( function(){
+    $(this).before( '<input class="form-control" maxlength="30" name="hostaliases[]"/>');
+  });
+
+  $(".add-ip").click( function(){
+    $(this).before( '<input class="form-control" maxlength="30" name="ips[]"/>');
+  })
+
+  /* 
+   * code that relates to Job Submission Protocol Interface starts here.
+  */
+
+  $(".add-job-submission").click( function(){
+    /*$(".job-submission-info").removeClass("hide").append( "<div class='job-protocol-block col-md-12'>" + $(".select-job-protocol").html() + "</div><hr/>");
+  	
+  	$('html, body').animate({
+        scrollTop: $(this).position().top + 500
+    }, 200);
+    */
+    $(".add-jsi-body").html( "<div class='job-protocol-block col-md-12'>" + $(".select-job-protocol").html() + "</div><hr/>");
+    $("#add-jsi").modal("show");
+  });
+
+  $("body").on("change", ".selected-job-protocol", function(){
+
+    var selectedVal = $(this).children("option:selected").html().toLowerCase();
+
+    $(this).parent().find("div[class*='resourcemanager-']").remove();
+
+    var parentResDiv = "<div class='resourcemanager-" + selectedVal + "'>"
+                + "<hr/>" 
+                + "Resource Manager: <h4>" + selectedVal + "</h4>"
+                + "<hr/>";
+
+    if( selectedVal == "local")
+    {
+      $(this).after(  parentResDiv + $(".resource-manager-block").html() + "</div>" );
+    }
+    else if( selectedVal == "ssh")
+    {
+      $(this).after(  parentResDiv 
+                      + $(".ssh-block").html()
+                      + $(".resource-manager-block").html() 
+                      + "</div>" );
+      $(this).parent().find(".addedScpValue").removeClass("hide");
+    }
+    else if( selectedVal == "globus")
+    {
+    	alert("Globus Protool is not being setup right now. Please choose another option.");
+    	/*	
+      $(this).parent().append(  parentResDiv 
+                      + $(".ssh-block").html()
+                      + "<h5>Globus Gate Keeper End Point</h5>" 
+                      + "<input class='form-control' name='globusGateKeeperEndPoint'/>"
+                      + "</div>" );
+         */
+    }
+    else if( selectedVal == "unicore")
+    {
+      $(this).parent().append(  parentResDiv 
+                      + $(".ssh-block").html()
+                      + "<h5>Unicore End Point Url</h5>" 
+                      + "<input class='form-control' name='unicoreEndPointURL'/>"
+                      + "</div>" );
+    }
+    else if( selectedVal == "cloud")
+    {
+      alert("Cloud Protool is not being setup right now. Please choose another option.");
+      /*
+      $(this).parent().append(  parentResDiv 
+                      + $(".ssh-block").html()
+                      + $(".cloud-block").html()
+                      );
+      */
+    }
+    else{
+      alert("Something went wrong. Please try again");
+      $(".jspSubmit").addClass("hide");
+    }
+
+    //temporary till all protocols are not setup
+    if( selectedVal == "local" || selectedVal == "ssh" || selectedVal == "unicore" )
+      $(".jspSubmit").removeClass("hide");
+    else
+      $(".jspSubmit").addClass("hide");
+
+  });
+  
+  /* 
+   * code that relates to Job Submission Protocol Interface ends here.
+  */
+
+
+  /* 
+   * code that relates to Data Movement Interface starts here.
+  */
+
+  $(".add-data-movement").click( function(){
+    //$(".data-movement-info").removeClass("hide").append( "<div class='data-movement-block col-md-12'>" + $(".select-data-movement").html() + "</div><hr/>");
+    $(".add-dmi-body").html("<div class='data-movement-block col-md-12'>" + $(".select-data-movement").html() + "</div><hr/>");
+    $("#add-dmi").modal("show");
+  });
+
+
+  $("body").on("change", ".selected-data-movement-protocol", function(){
+
+    var selectedVal = $(this).children("option:selected").html().toLowerCase();
+
+    $(this).parent().find("div[class*='dataprotocol-']").remove();
+    var parentDataDiv = "<div class='dataprotocol-" + selectedVal + "'>"
+                + "<hr/>" 
+                + "Data Management Protocol: <h4>" + selectedVal + "</h4>"
+                + "<hr/>";
+    if( selectedVal == "local")
+    {
+      // to find out what goes here.
+    }
+    else if( selectedVal == "scp" )
+    {
+      $(this).after(  parentDataDiv 
+                      + $(".ssh-block").html()
+                      + "</div>" );
+      $(this).parent().find(".addedScpValue").removeClass("hide");
+    }
+    else if( selectedVal == "sftp")
+    {
+      alert( "SFTP has not been setup yet. Please choose another Data Movement Protocol");
+    }
+    else if( selectedVal == "gridftp")
+    {
+      $(this).after(  parentDataDiv 
+                      + $(".ssh-block").html()
+                      + $(".dm-gridftp").html()
+                      + "</div>" );
+    }
+    else if( selectedVal == "unicore_storage_service")
+    {
+      $(this).after(  parentDataDiv 
+                      + $(".ssh-block").html()
+                      + "<h5>Unicore End Point Url</h5>" 
+                      + "<input class='form-control' name='unicoreEndPointURL'/>"
+                      + "</div>" );
+    }
+    else{
+      alert("Something went wrong. Please try again");
+      $(".dmpSubmit").addClass("hide");
+    }
+    $(".dmpSubmit").removeClass("hide");
+
+  });
+
+  $("body").on("click", ".add-gridFTPEndPoint", function(){
+        $(this).before( '<input class="form-control" maxlength="30" name="gridFTPEndPoints[]"/>');
+  });
+
+   $(".delete-jsi").click( function(){
+      $(".delete-jsi-confirm").val( $(this).data("jsi-id"));
+   });
+
+  $(".delete-jsi-confirm").click( function(){
+
+    var jsiId = $(this).data("jsi-id");
+    $.ajax({
+      type: "POST",
+      url: $(".base-url").val() + "/cr/delete-jsi",
+      data: { 
+              crId : $(".crId").val(), 
+              jsiId : jsiId 
+            }
+    })
+    .complete(function( data ) {
+      $("#confirm-delete-jsi").modal("hide");
+      if( data.responseText == 1)
+      {
+        $(".job-protocol-block").each( function(i, elem){
+          var toBeRemovedChild = $(elem).find(".delete-jsi");
+          if( toBeRemovedChild.data("jsi-id") == jsiId )
+          {
+            $(elem).before("<div class='alert alert-success'>The Job Submission Interface has been successfully deleted.</div>");
+            $(elem).fadeOut().remove();
+          }
+        });
+      }
+    });
+
+  });
+
+  $(".delete-dmi").click( function(){
+      $(".delete-dmi-confirm").val($(this).data("dmi-id"));
+   });
+
+  $(".delete-dmi-confirm").click( function(){
+
+    var dmiId = $(this).data("dmi-id");
+    $.ajax({
+      type: "POST",
+      url: $(".base-url").val() + "/cr/delete-dmi",
+      data: {
+              crId : $(".crId").val(), 
+              dmiId : dmiId 
+            }
+    })
+    .complete(function( data ) {
+      $("#confirm-delete-dmi").modal("hide");
+      if( data.responseText == 1)
+      {
+        $(".data-movement-block").each( function(i, elem){
+          var toBeRemovedChild = $(elem).find(".delete-dmi");
+          if( toBeRemovedChild.data("dmi-id") == dmiId )
+          {
+            $(elem).before("<div class='alert alert-success'>The Data Movement Interface has been successfully deleted.</div>");
+            $(elem).fadeOut().remove();
+          }
+        });
+      }
+
+    });
+  });
+
+  $("#jsi-priority-form").submit( function( event ){
+    event.preventDefault();
+    $.ajax({
+        url: $(this).attr("action"),
+        type: 'post',
+        data: $('#jsi-priority-form').serialize(),
+        success: function(data) {
+                  if( data == 1)
+                  {
+                    $(".priority-updated").removeClass("hide");
+                    $(".priority-updated").fadeIn();
+                    setTimeout( function(){
+                      $(".priority-updated").addClass("hide");
+                      $("#update-jsi-priority").modal("hide");
+
+                    }, 3000);
+                    
+                  }
+        }
+    });
+  });
+
+  $("#dmi-priority-form").submit( function( event ){
+    event.preventDefault();
+    $.ajax({
+        url: $(this).attr("action"),
+        type: 'post',
+        data: $('#dmi-priority-form').serialize(),
+        success: function(data) {
+                  if( data == 1)
+                  {
+                    $(".priority-updated").removeClass("hide");
+                    $(".priority-updated").fadeIn();
+                    setTimeout( function(){
+                      $(".priority-updated").addClass("hide");
+                      $("#update-dmi-priority").modal("hide");
+
+                    }, 3000);
+                    
+                  }
+        }
+    });
+  });
+
+  $(".add-queue-block").on("click", ".create-queue-form", function(){
+    var newQueueName = $(this).parent().parent().find(".create-queue-name").val();
+
+    if (newQueueName.length > 0) {
+        children = ($("#accordion").children());
+
+        queueNameExists = false;
+        children.each( function(index, elem){
+          var existingQueueName = $(elem).find(".existing-queue-name").html();
+          if( existingQueueName == newQueueName)
+          {
+            queueNameExists = true;
+            return false;
+          }
+        });
+
+        if( queueNameExists)
+          alert( "This queue name already exists. Please choose another name.");
+        else
+          $(this).parent().parent().parent().submit();
+        
+    } else {
+        alert("Please enter queue name before submitting");
+    }
+
+  });
+
+  
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/public/robots.txt
----------------------------------------------------------------------
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100755
index 0000000..eb05362
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/server.php
----------------------------------------------------------------------
diff --git a/server.php b/server.php
new file mode 100755
index 0000000..5f187f3
--- /dev/null
+++ b/server.php
@@ -0,0 +1,19 @@
+<?php
+
+$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
+
+$uri = urldecode($uri);
+
+$paths = require __DIR__.'/bootstrap/paths.php';
+
+$requested = $paths['public'].$uri;
+
+// This file allows us to emulate Apache's "mod_rewrite" functionality from the
+// built-in PHP web server. This provides a convenient way to test a Laravel
+// application without having installed a "real" web server software here.
+if ($uri !== '/' and file_exists($requested))
+{
+	return false;
+}
+
+require_once $paths['public'].'/index.php';

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/apache/thrift
----------------------------------------------------------------------
diff --git a/vendor/apache/thrift b/vendor/apache/thrift
new file mode 160000
index 0000000..dc799ca
--- /dev/null
+++ b/vendor/apache/thrift
@@ -0,0 +1 @@
+Subproject commit dc799ca078627a8e400cfcdbb965acf6abf86eef

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/autoload.php
----------------------------------------------------------------------
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 0000000..9614c3e
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer' . '/autoload_real.php';
+
+return ComposerAutoloaderInit95aab4dcf953834b79e3b5f569ea8229::getLoader();

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/bin/boris
----------------------------------------------------------------------
diff --git a/vendor/bin/boris b/vendor/bin/boris
new file mode 120000
index 0000000..a06032d
--- /dev/null
+++ b/vendor/bin/boris
@@ -0,0 +1 @@
+../d11wtq/boris/bin/boris
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/bin/classpreloader.php
----------------------------------------------------------------------
diff --git a/vendor/bin/classpreloader.php b/vendor/bin/classpreloader.php
new file mode 120000
index 0000000..d4b4e66
--- /dev/null
+++ b/vendor/bin/classpreloader.php
@@ -0,0 +1 @@
+../classpreloader/classpreloader/classpreloader.php
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/.gitignore
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/.gitignore b/vendor/classpreloader/classpreloader/.gitignore
new file mode 100644
index 0000000..19982ea
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/LICENSE.md
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/LICENSE.md b/vendor/classpreloader/classpreloader/LICENSE.md
new file mode 100644
index 0000000..6762891
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/LICENSE.md
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Michael Dowling <mt...@gmail.com> and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/README.md
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/README.md b/vendor/classpreloader/classpreloader/README.md
new file mode 100644
index 0000000..8a1eba2
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/README.md
@@ -0,0 +1,108 @@
+Class Preloader for PHP
+=======================
+
+This tool is used to generate a single PHP script containing all of the classes
+required for a specific use case. Using a single compiled PHP script instead of relying on autoloading can help to improve the performance of specific use cases. For example, if your application executes the same bootstrap code on every request, then you could generate a preloader (the compiled output of this tool) to reduce the cost of autoloading the required classes over and over.
+
+What it actually does
+---------------------
+
+This tool listens for each file that is autoloaded, creates a list of files, traverses the parsed PHP file using [PHPParser](https://github.com/nikic/PHP-Parser) and any visitors of a Config object, wraps the code of each file in a namespace block if necessary, and writes the contents of every autoloaded file (in order) to a single PHP file.
+
+Notice
+------
+
+This tool should only be used for specific use cases. There is a tradeoff between preloading classes and autoloading classes. The point at which it is no longer beneficial to generate a preloader is application specific. You'll need to perform your own benchmarks to determine if this tool will speed up your application.
+
+Installation
+------------
+
+Add the ClassPreloader as a dependency to your composer.json file:
+
+```javascript
+{
+    "require": {
+        "classpreloader/classpreloader": "1.0.*"
+    },
+    "config": {
+        "bin-dir": "bin"
+    }
+}
+```
+
+Using the tool
+--------------
+
+You use the bin/classpreloader.php compile command with a few command line flags to generate a preloader.
+
+`--config`: A CSV containing a list of files to combine into a classmap, or the full path to a PHP script that returns an array of classes or a `\ClassPreloader\Config` object.
+
+`--output`: The path to the file to store the compiled PHP code. If the directory does not exist, the tool will attempt to create it.
+
+`--fix_dir`: (defaults to 1) Set to 0 to not replace "__DIR__" constants with the actual directory of the original file.
+
+`--fix_file`: (defaults to 1) Set to 0 to not replace "__FILE__" constants with the actual location of the original file.
+
+Writing a config file
+---------------------
+
+Creating a PHP based configuration file is fairly simple. Just include the vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php file and call the `ClassLoader::getIncludes()` method, passing a function as the only  argument. This function should accept a `ClassLoader` object and register the passed in object's autoloader using `$loader->register()`. It is important to register the `ClassLoader` autoloader after all other autoloaders are registered.
+
+An array or `\ClassPreloader\Config` must be returned from the config file. You can attach custom node visitors if you need to perform any sort of translation on each matching file before writing it to the output.
+
+```php
+<?php
+// Here's an example of creating a preloader for using Amazon DynamoDB and the
+// AWS SDK for PHP 2.
+
+require __DIR__ . '/src/ClassPreloader/ClassLoader.php';
+
+use ClassPreloader\ClassLoader;
+
+$config = ClassLoader::getIncludes(function(ClassLoader $loader) {
+    require __DIR__ . '/vendor/autoload.php';
+    $loader->register();
+    $aws = Aws\Common\Aws::factory(array(
+        'key'    => '***',
+        'secret' => '***',
+        'region' => 'us-east-1'
+    ));
+    $client = $aws->get('dynamodb');
+    $client->listTables()->getAll();
+});
+
+// Add a regex filter that requires all classes to match the regex
+// $config->addInclusiveFilter('/Foo/');
+
+// Add a regex filter that requires that a class does not match the filter
+// $config->addExclusiveFilter('/Foo/');
+
+return $config;
+```
+
+You would then run the classpreloader.php script and pass in the full path to the above PHP script.
+
+`php bin/classpreloader.php compile --config="/path/to/the_example.php" --output="/tmp/preloader.php"`
+
+The above command will create a file in /tmp/preloader.php that contains every file that was autoloaded while running the snippet of code in the anonymous function. You would generate this file and include it in your production script.
+
+Automating the process with Composer
+------------------------------------
+
+You can automate the process of creating preloaders using Composer's script functionality. For example, if you wanted to automatically create a preloader each time the AWS SDK for PHP is installed, you could define a script like the following in your composer.json file:
+
+```javascript
+{
+    "require": {
+        "classpreloader/classpreloader": "1.0.*"
+    },
+    "scripts": {
+        "post-autoload-dump": "php bin/classpreloader.php compile --config=/path/to/the_example.php --output=/path/to/preload.php"
+    },
+    "config": {
+        "bin-dir": "bin"
+    }
+}
+```
+
+Using the above composer.json file, each time the project's autoloader is recreated using the install or update command, the classpreloader.php file will be executed. This script would generate a preload.php containing the classes required to run the previously demonstrated "the_example.php" configuration file.

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/classpreloader.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/classpreloader.php b/vendor/classpreloader/classpreloader/classpreloader.php
new file mode 100755
index 0000000..5dc4da1
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/classpreloader.php
@@ -0,0 +1,10 @@
+#! /usr/bin/env php
+<?php
+
+if (file_exists($autoloadPath = __DIR__ . '/../../autoload.php')) {
+    require_once $autoloadPath;
+} else {
+    require_once __DIR__ . '/vendor/autoload.php';
+}
+$application = new ClassPreloader\Application();
+$application->run();

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/composer.json
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/composer.json b/vendor/classpreloader/classpreloader/composer.json
new file mode 100644
index 0000000..6d2a4bc
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/composer.json
@@ -0,0 +1,28 @@
+{
+    "name": "classpreloader/classpreloader",
+    "description":"Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
+    "keywords":["autoload","class","preload"],
+    "license":"MIT",
+
+    "require":{
+        "php": ">=5.3.3",
+        "symfony/console": "~2.1",
+        "symfony/filesystem": "~2.1",
+        "symfony/finder": "~2.1",
+        "nikic/php-parser": "~0.9"
+    },
+
+    "autoload": {
+        "psr-0": {
+            "ClassPreloader": "src/"
+        }
+    },
+
+    "bin": ["classpreloader.php"],
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0-dev"
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Application.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Application.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Application.php
new file mode 100644
index 0000000..9e75916
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Application.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace ClassPreloader;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Console\Application as BaseApplication;
+
+/**
+ * ClassPreloader application CLI
+ */
+class Application extends BaseApplication
+{
+    public function __construct()
+    {
+        parent::__construct('ClassPreloader');
+
+        // Create a finder to find each non-abstract command in the filesystem
+        $finder = new Finder();
+        $finder->files()
+            ->in(__DIR__ . '/Command')
+            ->notName('Abstract*')
+            ->name('*.php');
+
+        // Add each command to the CLI
+        foreach ($finder as $file) {
+            $filename = str_replace('\\', '/', $file->getRealpath());
+            $pos = strrpos($filename, '/ClassPreloader/') + strlen('/ClassPreloader/');
+            $class = __NAMESPACE__ . '\\'
+                . substr(str_replace('/', '\\', substr($filename, $pos)), 0, -4);
+            $this->add(new $class());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassList.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassList.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassList.php
new file mode 100644
index 0000000..aaea2b5
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassList.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace ClassPreloader;
+
+/**
+ * Maintains a list of classes using a sort of doubly-linked list
+ */
+class ClassList
+{
+    /**
+     * @var ClassNode The head node of the list
+     */
+    protected $head;
+
+    /**
+     * @var ClassNode The current node of the list
+     */
+    protected $current;
+
+    public function __construct()
+    {
+        $this->clear();
+    }
+
+    /**
+     * Clear the contents of the list and reset the head node and current node
+     */
+    public function clear()
+    {
+        $this->head = new ClassNode(null);
+        $this->current = $this->head;
+    }
+
+    /**
+     * Traverse to the next node in the list
+     */
+    public function next()
+    {
+        if (isset($this->current->next)) {
+            $this->current = $this->current->next;
+        } else {
+            $this->current->next = new ClassNode(null, $this->current);
+            $this->current = $this->current->next;
+        }
+    }
+
+    /**
+     * Insert a value at the current position in the list. Any currently set
+     * value at this position will be pushed back in the list after the new
+     * value
+     *
+     * @param mixed $value Value to insert
+     */
+    public function push($value)
+    {
+        if (!$this->current->value) {
+            $this->current->value = $value;
+        } else {
+            $temp = $this->current;
+            $this->current = new ClassNode($value, $temp->prev);
+            $this->current->next = $temp;
+            $temp->prev = $this->current;
+            if ($temp === $this->head) {
+                $this->head = $this->current;
+            } else {
+                $this->current->prev->next = $this->current;
+            }
+        }
+    }
+
+    /**
+     * Traverse the ClassList and return a list of classes
+     *
+     * @return array
+     */
+    public function getClasses()
+    {
+        $classes = array();
+        $current = $this->head;
+        while ($current && $current->value) {
+            $classes[] = $current->value;
+            $current = $current->next;
+        }
+
+        return array_filter($classes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php
new file mode 100644
index 0000000..55c7891
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace ClassPreloader;
+
+require_once __DIR__ . '/ClassNode.php';
+require_once __DIR__ . '/ClassList.php';
+
+/**
+ * Creates an autoloader that intercepts and keeps track of each include in
+ * order that files must be included. This autoloader proxies to all other
+ * underlying autoloaders.
+ */
+class ClassLoader
+{
+    /**
+     * @var ClassList List of loaded classes
+     */
+    public $classList;
+
+    /**
+     * Create the dependency list
+     */
+    public function __construct()
+    {
+        $this->classList = new ClassList();
+    }
+
+    /**
+     * Wrap a block of code in the autoloader and get a list of loaded classes
+     *
+     * @param \Callable $func Callable function
+     *
+     * @return Config
+     */
+    public static function getIncludes($func)
+    {
+        $loader = new self();
+        call_user_func($func, $loader);
+        $loader->unregister();
+
+        $config = new Config();
+        foreach ($loader->getFilenames() as $file) {
+            $config->addFile($file);
+        }
+
+        return $config;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     */
+    public function register()
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, true);
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return bool|null True, if loaded
+     */
+    public function loadClass($class)
+    {
+        foreach (spl_autoload_functions() as $func) {
+            if (is_array($func) && $func[0] === $this) {
+                continue;
+            }
+            $this->classList->push($class);
+            if (call_user_func($func, $class)) {
+                break;
+            }
+        }
+
+        $this->classList->next();
+
+        return true;
+    }
+
+    /**
+     * Get an array of loaded file names in order of loading
+     *
+     * @return array
+     */
+    public function getFilenames()
+    {
+        $files = array();
+        foreach ($this->classList->getClasses() as $class) {
+            // Push interfaces before classes if not already loaded
+            $r = new \ReflectionClass($class);
+            foreach ($r->getInterfaces() as $inf) {
+                $name = $inf->getFileName();
+                if ($name && !in_array($name, $files)) {
+                    $files[] = $name;
+                }
+            }
+            $files[] = $r->getFileName();
+        }
+
+        return $files;
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassNode.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassNode.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassNode.php
new file mode 100644
index 0000000..78abb28
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/ClassNode.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace ClassPreloader;
+
+/**
+ * A simple ClassNode that contains a value, previous, and next pointers
+ */
+class ClassNode
+{
+    /**
+     * @var ClassNode|null Next node pointer
+     */
+    public $next;
+
+    /**
+     * @var ClassNode|null Previous node pointer
+     */
+    public $prev;
+
+    /**
+     * @var mixed Value of the ClassNode
+     */
+    public $value;
+
+    /**
+     * Create a new ClassNode
+     *
+     * @param mixed     $value Value of the class node
+     * @param ClassNode $prev  Previous node pointer
+     */
+    public function __construct($value = null, $prev = null)
+    {
+        $this->value = $value;
+        $this->prev = $prev;
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Command/PreCompileCommand.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Command/PreCompileCommand.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Command/PreCompileCommand.php
new file mode 100644
index 0000000..b49e3e6
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Command/PreCompileCommand.php
@@ -0,0 +1,216 @@
+<?php
+
+namespace ClassPreloader\Command;
+
+use ClassPreloader\Config;
+use ClassPreloader\Parser\DirVisitor;
+use ClassPreloader\Parser\NodeTraverser;
+use ClassPreloader\Parser\FileVisitor;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+
+class PreCompileCommand extends Command
+{
+    protected $input;
+    protected $output;
+    protected $printer;
+    protected $traverser;
+    protected $parser;
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->printer = new \PHPParser_PrettyPrinter_Zend();
+        $this->parser = new \PHPParser_Parser(new \PHPParser_Lexer());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        parent::configure();
+
+        $this->setName('compile')
+            ->setDescription('Compiles classes into a single file')
+            ->addOption('config', null, InputOption::VALUE_REQUIRED, 'CSV of filenames to load, or the path to a PHP script that returns an array of file names')
+            ->addOption('output', null, InputOption::VALUE_REQUIRED)
+            ->addOption('fix_dir', null, InputOption::VALUE_REQUIRED, 'Convert __DIR__ constants to the original directory of a file', 1)
+            ->addOption('fix_file', null, InputOption::VALUE_REQUIRED, 'Convert __FILE__ constants to the original path of a file', 1)
+            ->addOption('strip_comments', null, InputOption::VALUE_REQUIRED, 'Set to 1 to strip comments from each source file', 0)
+            ->setHelp(<<<EOF
+The <info>%command.name%</info> command iterates over each script, normalizes
+the file to be wrapped in namespaces, and combines each file into a single PHP
+file.
+EOF
+        );
+    }
+
+    /**
+     * Get the node traverser used by the command
+     *
+     * @return NodeTraverser
+     */
+    protected function getTraverser()
+    {
+        if (!$this->traverser) {
+            $this->traverser = new NodeTraverser();
+            if ($this->input->getOption('fix_dir')) {
+                $this->traverser->addVisitor(new DirVisitor());
+            }
+            if ($this->input->getOption('fix_file')) {
+                $this->traverser->addVisitor(new FileVisitor());
+            }
+        }
+
+        return $this->traverser;
+    }
+
+    /**
+     * Get a pretty printed string of code from a file while applying visitors
+     *
+     * @param string $file Name of the file to get code from
+     *
+     * @return string
+     * @throws \RuntimeException
+     */
+    protected function getCode($file)
+    {
+        if (!is_readable($file)) {
+            throw new \RuntimeException("Cannot open {$file} for reading");
+        }
+
+        if ($this->input->getOption('strip_comments')) {
+            $content = php_strip_whitespace($file);
+        } else {
+            $content = file_get_contents($file);
+        }
+
+        $stmts = $this->getTraverser()
+            ->traverseFile($this->parser->parse($content), $file);
+        $pretty = $this->printer->prettyPrint($stmts);
+
+        // Remove the open PHP tag
+        if (substr($pretty, 6) == "<?php\n") {
+            $pretty = substr($pretty, 7);
+        }
+
+        // Add a wrapping namespace if needed
+        if (false === strpos($pretty, 'namespace ')) {
+            $pretty = "namespace {\n" . $pretty . "\n}\n";
+        }
+
+        return $pretty;
+    }
+
+    /**
+     * Validate the command options
+     */
+    protected function validateCommand()
+    {
+        if (!$this->input->getOption('output')) {
+            throw new \InvalidArgumentException('An output option is required');
+        }
+
+        if (!$this->input->getOption('config')) {
+            throw new \InvalidArgumentException('A config option is required');
+        }
+    }
+
+    /**
+     * Get a list of files in order
+     *
+     * @param mixed $config Configuration option
+     *
+     * @return array
+     * @throws \InvalidArgumentException
+     */
+    protected function getFileList($config)
+    {
+        $this->output->writeln('> Loading configuration file');
+        $filesystem = new Filesystem();
+
+        if (strpos($config, ',')) {
+            return array_filter(explode(',', $config));
+        }
+
+        // Ensure absolute paths are resolved
+        if (!$filesystem->isAbsolutePath($config)) {
+            $config = getcwd() . '/' . $config;
+        }
+
+        // Ensure that the config file exists
+        if (!file_exists($config)) {
+            throw new \InvalidArgumentException(sprintf('Configuration file "%s" does not exist.', $config));
+        }
+
+        $result = require $config;
+
+        if ($result instanceof Config) {
+            foreach ($result->getVisitors() as $visitor) {
+                $this->getTraverser()->addVisitor($visitor);
+            }
+
+            return $result;
+        } elseif (is_array($result)) {
+            return $result;
+        }
+
+        throw new \InvalidArgumentException(
+            'Config must return an array of filenames or a Config object'
+        );
+    }
+
+    /**
+     * Prepare the output file and directory
+     *
+     * @param string $outputFile The full path to the output file
+     *
+     * @throws \RuntimeException
+     */
+    protected function prepareOutput($outputFile)
+    {
+        $dir = dirname($outputFile);
+        if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
+            throw new \RuntimeException('Unable to create directory ' . $dir);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->input = $input;
+        $this->output = $output;
+        $this->validateCommand();
+        $outputFile = $this->input->getOption('output');
+        $config = $this->input->getOption('config');
+        $files = $this->getFileList($config);
+        $output->writeLn('- Found ' . count($files) . ' files');
+
+        // Make sure that the output dir can be used or create it
+        $this->prepareOutput($outputFile);
+
+        if (!$handle = fopen($input->getOption('output'), 'w')) {
+            throw new \RuntimeException(
+                "Unable to open {$outputFile} for writing"
+            );
+        }
+
+        // Write the first line of the output
+        fwrite($handle, "<?php\n");
+        $output->writeln('> Compiling classes');
+        foreach ($files as $file) {
+            $this->output->writeln('- Writing ' . $file);
+            fwrite($handle, $this->getCode($file) . "\n");
+        }
+        fclose($handle);
+
+        $output->writeln("> Compiled loader written to {$outputFile}");
+        $output->writeln('- ' . (round(filesize($outputFile) / 1024)) . ' kb');
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Config.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Config.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Config.php
new file mode 100644
index 0000000..30d815c
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Config.php
@@ -0,0 +1,133 @@
+<?php
+
+namespace ClassPreloader;
+
+use Parser\AbstractNodeVisitor;
+
+/**
+ * Class loader configuration object
+ */
+class Config implements \IteratorAggregate
+{
+    /**
+     * @var array Array of AbstractNodeVisitor objects that visit nodes
+     */
+    protected $visitors = array();
+
+    /**
+     * @var array Array of file names
+     */
+    protected $filenames = array();
+
+    /**
+     * @var array Array of exclusive filters
+     */
+    protected $exclusiveFilters = array();
+
+    /**
+     * @var array Array of inclusive filters
+     */
+    protected $inclusiveFilters = array();
+
+    /**
+     * Add the filename owned by the config
+     *
+     * @param string $filename File name
+     *
+     * @return self
+     */
+    public function addFile($filename)
+    {
+        $this->filenames[] = $filename;
+
+        return $this;
+    }
+
+    /**
+     * Get an array of file names that satisfy any added filters
+     *
+     * @return array
+     */
+    public function getFilenames()
+    {
+        $filenames = array();
+        foreach ($this->filenames as $f) {
+            foreach ($this->inclusiveFilters as $filter) {
+                if (!preg_match($filter, $f)) {
+                    continue 2;
+                }
+            }
+            foreach ($this->exclusiveFilters as $filter) {
+                if (preg_match($filter, $f)) {
+                    continue 2;
+                }
+            }
+            $filenames[] = $f;
+        }
+
+        return $filenames;
+    }
+
+    /**
+     * Get an iterator for the filenames
+     *
+     * @return \ArrayIterator
+     */
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->getFilenames());
+    }
+
+    /**
+     * Add a filter used to filter out classes matching a specific pattern
+     *
+     * @param string $pattern Regular expression pattern
+     *
+     * @return self
+     */
+    public function addExclusiveFilter($pattern)
+    {
+        $this->exclusiveFilters[] = $pattern;
+
+        return $this;
+    }
+
+    /**
+     * Add a filter used to grab only file names matching the pattern
+     *
+     * @param string $pattern Regular expression pattern
+     *
+     * @return self
+     */
+    public function addInclusiveFilter($pattern)
+    {
+        $this->inclusiveFilters[] = $pattern;
+
+        return $this;
+    }
+
+    /**
+     * Add a visitor that will visit each node when traversing the node list
+     * of each file.
+     *
+     * @param AbstractNodeVisitor $visitor Node visitor
+     *
+     * @return self
+     */
+    public function addVisitor(AbstractNodeVisitor $visitor)
+    {
+        $this->visitors[] = $visitor;
+
+        return $this;
+    }
+
+    /**
+     * Get an array of node visitors
+     *
+     * @return array
+     */
+    public function getVisitors()
+    {
+        return $this->visitors;
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/AbstractNodeVisitor.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/AbstractNodeVisitor.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/AbstractNodeVisitor.php
new file mode 100644
index 0000000..cd05ab9
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/AbstractNodeVisitor.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace ClassPreloader\Parser;
+
+/**
+ * Abstract node visitor used to track the filename
+ */
+abstract class AbstractNodeVisitor extends \PHPParser_NodeVisitorAbstract
+{
+    /**
+     * @var string Current file being parsed
+     */
+    protected $filename = '';
+
+    /**
+     * Set the full path to the current file being parsed
+     *
+     * @param string $filename Filename being parser
+     *
+     * @return self
+     */
+    public function setFilename($filename)
+    {
+        $this->filename = $filename;
+
+        return $this;
+    }
+
+    /**
+     * Get the full path to the current file being parsed
+     *
+     * @return string
+     */
+    public function getFilename()
+    {
+        return $this->filename;
+    }
+
+    /**
+     * Get the directory of the current file being parsed
+     *
+     * @return string
+     */
+    public function getDir()
+    {
+        return dirname($this->getFilename());
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/DirVisitor.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/DirVisitor.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/DirVisitor.php
new file mode 100644
index 0000000..24dba9e
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/DirVisitor.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace ClassPreloader\Parser;
+
+/**
+ * Finds all references to __DIR__ and replaces them with the actual directory
+ */
+class DirVisitor extends AbstractNodeVisitor
+{
+    public function enterNode(\PHPParser_Node $node)
+    {
+        if ($node instanceof \PHPParser_Node_Scalar_DirConst) {
+            return new \PHPParser_Node_Scalar_String($this->getDir());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/FileVisitor.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/FileVisitor.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/FileVisitor.php
new file mode 100644
index 0000000..bd0ed61
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/FileVisitor.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace ClassPreloader\Parser;
+
+/**
+ * Finds all references to __FILE__ and replaces them with the actual file path
+ */
+class FileVisitor extends AbstractNodeVisitor
+{
+    public function enterNode(\PHPParser_Node $node)
+    {
+        if ($node instanceof \PHPParser_Node_Scalar_FileConst) {
+            return new \PHPParser_Node_Scalar_String($this->getFilename());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/NodeTraverser.php
----------------------------------------------------------------------
diff --git a/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/NodeTraverser.php b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/NodeTraverser.php
new file mode 100644
index 0000000..960988a
--- /dev/null
+++ b/vendor/classpreloader/classpreloader/src/ClassPreloader/Parser/NodeTraverser.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace ClassPreloader\Parser;
+
+/**
+ * Allows a filename to be set when visiting
+ */
+class NodeTraverser extends \PHPParser_NodeTraverser
+{
+    public function traverseFile(array $nodes, $filename)
+    {
+        // Set the correct state on each visitor
+        foreach ($this->visitors as $visitor) {
+            if ($visitor instanceof AbstractNodeVisitor) {
+                $visitor->setFilename($filename);
+            }
+        }
+
+        return $this->traverse($nodes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/01413d65/vendor/composer/ClassLoader.php
----------------------------------------------------------------------
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..5e1469e
--- /dev/null
+++ b/vendor/composer/ClassLoader.php
@@ -0,0 +1,413 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <na...@naderman.de>
+ *     Jordi Boggiano <j....@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0 class loader
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
+ *
+ *     $loader = new \Composer\Autoload\ClassLoader();
+ *
+ *     // register classes with namespaces
+ *     $loader->add('Symfony\Component', __DIR__.'/component');
+ *     $loader->add('Symfony',           __DIR__.'/framework');
+ *
+ *     // activate the autoloader
+ *     $loader->register();
+ *
+ *     // to enable searching the include path (eg. for PEAR packages)
+ *     $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fa...@symfony.com>
+ * @author Jordi Boggiano <j....@seld.be>
+ */
+class ClassLoader
+{
+    // PSR-4
+    private $prefixLengthsPsr4 = array();
+    private $prefixDirsPsr4 = array();
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    private $prefixesPsr0 = array();
+    private $fallbackDirsPsr0 = array();
+
+    private $useIncludePath = false;
+    private $classMap = array();
+
+    private $classMapAuthoritative = false;
+
+    public function getPrefixes()
+    {
+        if (!empty($this->prefixesPsr0)) {
+            return call_user_func_array('array_merge', $this->prefixesPsr0);
+        }
+
+        return array();
+    }
+
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
+    }
+
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirsPsr0;
+    }
+
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
+    }
+
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param array $classMap Class to filename map
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
+     *
+     * @param string       $prefix  The prefix
+     * @param array|string $paths   The PSR-0 root directories
+     * @param bool         $prepend Whether to prepend the directories
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr0
+                );
+            } else {
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-0 base directories
+     * @param bool         $prepend Whether to prepend the directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixDirsPsr4[$prefix]
+            );
+        } else {
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
+     *
+     * @param string       $prefix The prefix
+     * @param array|string $paths  The PSR-0 base directories
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string       $prefix The prefix/namespace, with trailing '\\'
+     * @param array|string $paths  The PSR-4 base directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function setPsr4($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Turns off searching the prefix and fallback directories for classes
+     * that have not been registered with the class map.
+     *
+     * @param bool $classMapAuthoritative
+     */
+    public function setClassMapAuthoritative($classMapAuthoritative)
+    {
+        $this->classMapAuthoritative = $classMapAuthoritative;
+    }
+
+    /**
+     * Should class lookup fail if not found in the current class map?
+     *
+     * @return bool
+     */
+    public function isClassMapAuthoritative()
+    {
+        return $this->classMapAuthoritative;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param bool $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return bool|null True if loaded, null otherwise
+     */
+    public function loadClass($class)
+    {
+        if ($file = $this->findFile($class)) {
+            includeFile($file);
+
+            return true;
+        }
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+        if ('\\' == $class[0]) {
+            $class = substr($class, 1);
+        }
+
+        // class map lookup
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+        if ($this->classMapAuthoritative) {
+            return false;
+        }
+
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if ($file === null && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if ($file === null) {
+            // Remember that this class does not exist.
+            return $this->classMap[$class] = false;
+        }
+
+        return $file;
+    }
+
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+        } else {
+            // PEAR-like class name
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+        }
+
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+            return $file;
+        }
+    }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+    include $file;
+}