public static function copy($source, $destination, $mode = 0777)
	{
		$isSuccess = false;

		// if $source and $destination are given
		if ($source !== null && $destination !== null && $mode !== null) {
			// if $source is a string
			if (is_string($source)) {
				// if $destination is a string
				if (is_string($destination)) {
					// if $mode is an integer or false
					if (is_integer($mode) || $mode === false) {
						// if the source directory exists and is a directory
						if (is_dir($source)) {
							// if the source directory is readable
							if (is_readable($source)) {
								// if the destination directory does not exist and we're ok to create it
								if ( ! file_exists($destination) && is_integer($mode)) {
									mkdir($destination, $mode, true);
								}
								// if the destination directory exists and is a directory
								if (is_dir($destination)) {
									// if the destination directory is writable
									if (is_writable($destination)) {
										// open the source directory
										$sourceDir = opendir($source);
										// loop through the entities in the source directory
										$entity = readdir($sourceDir);
										while ($entity !== false) {
											// if not the special entities "." and ".."
											if ($entity != '.' && $entity != '..') {
												// if the file is a dir
												if (is_dir($source.DIRECTORY_SEPARATOR.$entity)) {
													// recursively copy the dir
													$isSuccess = self::copy(
														$source.DIRECTORY_SEPARATOR.$entity,
														$destination.DIRECTORY_SEPARATOR.$entity,
														$mode
													);
												} else {
													// otherwise, just copy the file
													$isSuccess = copy(
														$source.DIRECTORY_SEPARATOR.$entity,
														$destination.DIRECTORY_SEPARATOR.$entity
													);
												}
												// if an error occurs, stop
												if ( ! $isSuccess) {
													break;
												}
											} else {
												// there was nothing to remove
												// set $isSuccess to true in case the directory is empty
												// if it's not empty, $isSuccess will be overwritten on the next iteration
												//
												$isSuccess = true;
											}
											// advance to the next file
											$entity = readdir($sourceDir);
										}
										// close the source directory
										closedir($sourceDir);
									} else {
										throw new \InvalidArgumentException(
											__METHOD__."() expects parameter two, destination, to be a writable directory"
										);
									}
								} else {
									throw new \InvalidArgumentException(
										__METHOD__."() expects parameter two, destination, to be an existing directory ".
											"(or it expects parameter three, mode, to be an integer)"
									);
								}
							} else {
								throw new \InvalidArgumentException(
									__METHOD__."() expects parameter one, source, to be a readable directory"
								);
							}
						} else {
							throw new \InvalidArgumentException(
								__METHOD__."() expects parameter one, source, to be an existing directory"
							);
						}
					} else {
						throw new \InvalidArgumentException(
							__METHOD__."() expects parameter three, mode, to be an integer or false"
						);
					} 
				} else {
					throw new \InvalidArgumentException(
						__METHOD__."() expects parameter two, destination, to be a string"
					);
				}
			} else {
				throw new \InvalidArgumentException(
					__METHOD__."() expects parameter one, source, to be a string"
				);
			}
		} else {
			throw new \BadMethodCallException(
				__METHOD__."() expects two or three parameters: source, destination, and mode"
			);
		}

		return $isSuccess;
	}