private function createProxy(GraphElement $meta)
    {
        //Get the proxy class name, as well as the regular class name
        $proxyClass = $meta->getProxyClass();
        $className = $meta->getName();

        //If the class already exists, just make an instance of it with the correct properties and return it.
        if(class_exists($proxyClass, false))
        {
            return $this->newInstance($proxyClass);
        }

        //Create a target file for the class
        $targetFile = "{$this->proxyDir}/$proxyClass.php";

        //If the file doesn't exist
        if($this->debug || !file_exists($targetFile))
        {
            //Initialize functions
            $functions = '';

            $reflectionClass = new \ReflectionClass($className);

            //Loop through entities public methods
            foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
            {
                //If the method isn't a constructor, destructor, or final, add it to the methods via method proxy.
                if(!$method->isConstructor() && !$method->isDestructor() && !$method->isFinal())
                {
                    $functions .= $this->methodProxy($method, $meta);
                }
            }

            //Get the properties and primary key.
            $properties = $meta->getProperties();
            $properties[] = $meta->getPrimaryKey();

            //Filter out private properties
            $properties = array_filter($properties, function ($property) {
                return !$property->isPrivate();
            });

            //Create an array map by property name
            $properties = array_map(function ($property) {
                return $property->getName();
            }, $properties);

            //Create php code for properties.
            $properties = var_export($properties, true);

            //Create the actual class.
            $content = <<<CONTENT
<?php

class $proxyClass extends $className implements LRezek\\Arachnid\\Proxy\\Entity
{
    private \$neo4j_hydrated = array();
    private \$neo4j_meta;
    private \$neo4j_entity;
    private \$neo4j_loadCallback;

    function getEntity()
    {
        \$entity = new $className;

        foreach (\$this->neo4j_meta->getProperties() as \$prop)
        {
            \$prop->setValue(\$entity, \$prop->getValue(\$this));
        }

        \$prop = \$this->neo4j_meta->getPrimaryKey();
        \$prop->setValue(\$entity, \$prop->getValue(\$this));

        return \$entity;
    }

    $functions

    function __addHydrated(\$name)
    {
        \$this->neo4j_hydrated[] = \$name;
    }

    function __setMeta(\$meta)
    {
        \$this->neo4j_meta = \$meta;
    }

    function __setEntity(\$entity)
    {
        \$this->neo4j_entity = \$entity;
    }

    function __getEntity()
    {
        return \$this->neo4j_entity;
    }

    function __setLoadCallback(\$loadCallback)
    {
        \$this->neo4j_loadCallback = \$loadCallback;
    }

    private function __load(\$name, \$propertyName)
    {
        //Already hydrated
        if(in_array(\$propertyName, \$this->neo4j_hydrated))
        {
            return;
        }

        if(! \$this->neo4j_meta)
        {
            throw new \\LRezek\\Arachnid\\Exception('Proxy not fully initialized.');
        }

        \$property = \$this->neo4j_meta->findProperty(\$name);

        if(strpos(\$name, 'set') === 0)
        {
            \$this->__addHydrated(\$propertyName);
            return;
        }

        //Make property node
        if(\$property->isStart() || \$property->isEnd())
        {
            \$loader = \$this->neo4j_loadCallback;

            //Get the node
            if(\$property->isStart())
            {
                \$node = \$this->neo4j_entity->getStartNode();
            }
            else
            {
                \$node = \$this->neo4j_entity->getEndNode();
            }

            \$node = \$loader(\$node);

            //Set the property
            \$property->setValue(\$this, \$node);
        }

        //Hydrate the property
        \$this->__addHydrated(\$propertyName);

    }

    function __sleep()
    {
        return $properties;
    }
}


CONTENT;

            //Make sure the proxy directory is an actual directory
            if(!is_dir($this->proxyDir))
            {
                if(false === @mkdir($this->proxyDir, 0775, true))
                {
                    throw new Exception('Proxy Dir is not writable.');
                }
            }

            //Make sure the directory is writable
            else if(!is_writable($this->proxyDir))
            {
                throw new Exception('Proxy Dir is not writable.');
            }

            //Write the file
            file_put_contents($targetFile, $content);
        }

        //Add file to class loader
        require $targetFile;

        //Return an instance of the proxy class
        return $this->newInstance($proxyClass);
    }