code: public static boolean smartEquals(File one, File two, boolean checkName) throws IOException
  	{
  		if (checkName)
  		{
  			if (!one.getName().equals(two.getName()))
  			{
  				return false;
  			}
  		}
  
  		if (one.isDirectory() == two.isDirectory())
  		{
  			if (one.isDirectory())
  			{
  				File[] filesOne = one.listFiles();
  				File[] filesTwo = two.listFiles();
  
  				if (filesOne.length == filesTwo.length)
  				{
  					if (filesOne.length > 0)
  					{
  						for (int i = 0; i < filesOne.length; i++)
  						{
  							if (!smartEquals(filesOne[i], filesTwo[i], checkName))
  							{
  								return false;
  							}
  						}
  						return true; // all subfiles are equal
  					}
  					else
  					{
  						return true;
  					}
  				}
  				else
  				{
  					return false;
  				}
  			} // Otherwise, the File objects are Files
  			else if (one.isFile() && two.isFile())
  			{
  				if (one.length() == two.length())
  				{
  					return FileUtils.contentEquals(one, two);
  				}
  				else
  				{
  					return false;
  				}
  			}
  			else
  			{
  				throw new IOException("I don't know how to handle a non-file non-directory File: one=" + one + " two=" + two);
  			}
  		} // One is a directory and the other is not
  		else
  		{
  			return false;
  		}
  	}
docs: Determines if 2 files or directories are equivalent by looking inside them
  
  @param one
  File The first file/directory
  @param two
  File The second file/directory
  @param checkName
  boolean Whether names should be identical also
  
  @return boolean True if the files/directories are equivalent, otherwise false
  
  @throws IOException
  On an unhandleable error or a non-file, non-directory input