original_string: public function relativeTo($directory, $cwd = null)
  	{
  		$dir = Path::info($directory);
  		if ($dir->isEmpty()) {
  			throw new \InvalidArgumentException('Directory is empty.');
  		}
  		$dir = $dir->normalize()->assumeDirectory();
  		$self = $this->normalize()->dir();
  		
  		if (! $dir->isAbsolute() && is_null($cwd)) {
  			throw new \InvalidArgumentException(sprintf('Directory "%s" is not absolute, you have to provide a working directory.', $directory));
  		}
  		if (! $self->isAbsolute() && is_null($cwd)) {
  			throw new \InvalidArgumentException(sprintf('Path "%s" is not absolute, you have to provide a working directory.', $this));
  		}
  		if (! is_null($cwd)) {
  			$cwd = Path::info($cwd)->normalize()->assumeDirectory();
  			if (! $cwd->isAbsolute()) {
  				throw new \InvalidArgumentException(sprintf('Working directory "%s" must be absolute.', $cwd));
  			}
  			if ($cwd->isEmpty()) {
  				throw new \InvalidArgumentException('Working directory is empty.');
  			}
  			$dir = $dir->abs($cwd)->normalize();
  			$self = $self->abs($cwd)->normalize();
  		}
  		
  		$i = 0;
  		while ($i < $dir->partCount && $i < $self->partCount && $dir->parts[$i] === $self->parts[$i]) {
  			$i ++;
  		}
  		$remainder = new Path('');
  		$remainder->setParts(array_slice($self->parts, $i));
  		$outsideDepth = $dir->partCount - $i - 1;
  		if ($outsideDepth > 0) {
  			$traversal = array_fill(0, $outsideDepth, '..');
  			$remainder->setParts(array_merge($traversal, $remainder->parts));
  		}
  		$result = $remainder->resolve($this->filename());
  		return $result->isEmpty() ? new Path('./') : $result;
  	}
code: public function relativeTo($directory, $cwd = null)
  	{
  		$dir = Path::info($directory);
  		if ($dir->isEmpty()) {
  			throw new \InvalidArgumentException('Directory is empty.');
  		}
  		$dir = $dir->normalize()->assumeDirectory();
  		$self = $this->normalize()->dir();
  		
  		if (! $dir->isAbsolute() && is_null($cwd)) {
  			throw new \InvalidArgumentException(sprintf('Directory "%s" is not absolute, you have to provide a working directory.', $directory));
  		}
  		if (! $self->isAbsolute() && is_null($cwd)) {
  			throw new \InvalidArgumentException(sprintf('Path "%s" is not absolute, you have to provide a working directory.', $this));
  		}
  		if (! is_null($cwd)) {
  			$cwd = Path::info($cwd)->normalize()->assumeDirectory();
  			if (! $cwd->isAbsolute()) {
  				throw new \InvalidArgumentException(sprintf('Working directory "%s" must be absolute.', $cwd));
  			}
  			if ($cwd->isEmpty()) {
  				throw new \InvalidArgumentException('Working directory is empty.');
  			}
  			$dir = $dir->abs($cwd)->normalize();
  			$self = $self->abs($cwd)->normalize();
  		}
  		
  		$i = 0;
  		while ($i < $dir->partCount && $i < $self->partCount && $dir->parts[$i] === $self->parts[$i]) {
  			$i ++;
  		}
  		$remainder = new Path('');
  		$remainder->setParts(array_slice($self->parts, $i));
  		$outsideDepth = $dir->partCount - $i - 1;
  		if ($outsideDepth > 0) {
  			$traversal = array_fill(0, $outsideDepth, '..');
  			$remainder->setParts(array_merge($traversal, $remainder->parts));
  		}
  		$result = $remainder->resolve($this->filename());
  		return $result->isEmpty() ? new Path('./') : $result;
  	}
code_tokens: public function relativeTo ( $ directory , $ cwd = null ) { $ dir = Path :: info ( $ directory ) ; if ( $ dir -> isEmpty ( ) ) { throw new \ InvalidArgumentException ( 'Directory is empty.' ) ; } $ dir = $ dir -> normalize ( ) -> assumeDirectory ( ) ; $ self = $ this -> normalize ( ) -> dir ( ) ; if ( ! $ dir -> isAbsolute ( ) && is_null ( $ cwd ) ) { throw new \ InvalidArgumentException ( sprintf ( 'Directory "%s" is not absolute, you have to provide a working directory.' , $ directory ) ) ; } if ( ! $ self -> isAbsolute ( ) && is_null ( $ cwd ) ) { throw new \ InvalidArgumentException ( sprintf ( 'Path "%s" is not absolute, you have to provide a working directory.' , $ this ) ) ; } if ( ! is_null ( $ cwd ) ) { $ cwd = Path :: info ( $ cwd ) -> normalize ( ) -> assumeDirectory ( ) ; if ( ! $ cwd -> isAbsolute ( ) ) { throw new \ InvalidArgumentException ( sprintf ( 'Working directory "%s" must be absolute.' , $ cwd ) ) ; } if ( $ cwd -> isEmpty ( ) ) { throw new \ InvalidArgumentException ( 'Working directory is empty.' ) ; } $ dir = $ dir -> abs ( $ cwd ) -> normalize ( ) ; $ self = $ self -> abs ( $ cwd ) -> normalize ( ) ; } $ i = 0 ; while ( $ i < $ dir -> partCount && $ i < $ self -> partCount && $ dir -> parts [ $ i ] === $ self -> parts [ $ i ] ) { $ i ++ ; } $ remainder = new Path ( '' ) ; $ remainder -> setParts ( array_slice ( $ self -> parts , $ i ) ) ; $ outsideDepth = $ dir -> partCount - $ i - 1 ; if ( $ outsideDepth > 0 ) { $ traversal = array_fill ( 0 , $ outsideDepth , '..' ) ; $ remainder -> setParts ( array_merge ( $ traversal , $ remainder -> parts ) ) ; } $ result = $ remainder -> resolve ( $ this -> filename ( ) ) ; return $ result -> isEmpty ( ) ? new Path ( './' ) : $ result ; }
docstring: Gets the relative path to the given directory.
  
  Example:
  new Path('/var/wwwroot/js/script.js')->relativeTo('/var/wwwroot/') => js/script.js
  
  If you provide a working directory, you can use relative paths.
  new Path('js/script.js')->relativeTo('.', '/var/wwwroot/') => js/script.js
  
  If the current path is a directory, it must end with a slash.
  
  
  @param string|Path $directory
  @param string|Path|NULL $cwd
  @throws \InvalidArgumentException
  @return static a new Path object
docstring_tokens: Gets the relative path to the given directory .