private static String generateShortName( String longname )
	{
		// assume that it is actually long, don't check it again
		longname = longname.replaceAll( "\\.$|^\\.", "" );

		int dotIdx = longname.lastIndexOf( '.' );
		String baseName = dotIdx == -1 ? longname : longname.substring( 0, dotIdx );
		String ext = dotIdx == -1 ? "" : longname.substring( dotIdx + 1 );

		ext = ext.replaceAll( " ", "" ).replaceAll( "[\\.\"\\/\\\\\\[\\]:;=,\\+]", "_" );
		ext = ext.substring( 0, Math.min( 3, ext.length() ) );

		baseName = baseName.replaceAll( " ", "" ).replaceAll( "[\\.\"\\/\\\\\\[\\]:;=,\\+]", "_" );
		baseName = baseName.substring( 0, Math.min( 6, baseName.length() ) );

		// well, for same short names we should use "~2", "~3" and so on,
		// but actual index is generated by os while creating a file and stored in filesystem
		// so it is not possible to get actual one
		StringBuilder shortname = new StringBuilder( baseName + "~1" + ( ext.isEmpty() ? "" : "." + ext ) );

		// i have no idea how non-asci symbols are converted in dos names
		CharsetEncoder asciiEncoder = Charset.forName( "US-ASCII" ).newEncoder();
		for( int i = 0; i < shortname.length(); ++i )
		{
			if( !asciiEncoder.canEncode( shortname.charAt( i ) ) )
				shortname.setCharAt( i, '_' );
		}

		return shortname.toString().toUpperCase();
	}