class GroupAwareJob implements Job {

	/**
	 * The separator between group and delegate job names in the final name given to this
	 * job.
	 */
	private static final String SEPARATOR = ".";

	private final Job delegate;

	private final String groupName;

	/**
	 * Create a new {@link Job} with the delegate and no group name.
	 * @param delegate a delegate for the features of a regular Job
	 */
	public GroupAwareJob(Job delegate) {
		this(null, delegate);
	}

	/**
	 * Create a new {@link Job} with the given group name and delegate.
	 * @param groupName the group name to prepend (can be {@code null})
	 * @param delegate a delegate for the features of a regular Job
	 */
	public GroupAwareJob(@Nullable String groupName, Job delegate) {
		super();
		this.groupName = groupName;
		this.delegate = delegate;
	}

	@Override
	public void execute(JobExecution execution) {
		delegate.execute(execution);
	}

	/**
	 * Concatenates the group name and the delegate job name (joining with a ".").
	 *
	 * @see org.springframework.batch.core.Job#getName()
	 */
	@Override
	public String getName() {
		return groupName == null ? delegate.getName() : groupName + SEPARATOR + delegate.getName();
	}

	@Override
	public boolean isRestartable() {
		return delegate.isRestartable();
	}

	@Override
	@Nullable
	public JobParametersIncrementer getJobParametersIncrementer() {
		return delegate.getJobParametersIncrementer();
	}

	@Override
	public JobParametersValidator getJobParametersValidator() {
		return delegate.getJobParametersValidator();
	}

	@Override
	public boolean equals(Object obj) {<FILL_FUNCTION_BODY>}

	@Override
	public int hashCode() {
		return delegate.hashCode();
	}

	@Override
	public String toString() {
		return ClassUtils.getShortName(delegate.getClass()) + ": [name=" + getName() + "]";
	}

}

		if (obj instanceof GroupAwareJob) {
			return ((GroupAwareJob) obj).delegate.equals(delegate);
		}
		return false;
	
<no_super_class>