// Path: app/models/Item.java
// @Entity
// public class Item extends Model {
//     @Id
//     public Long id;
// 
//     public String name;
// 
//     public String storageKey;
// 
//     public Date uploadDate;
// 
//     public Long fileSize;
// 
//     @ManyToMany(mappedBy = "items", cascade = CascadeType.ALL)
//     public List<Tag> tags;
// 
//     public static Finder<Long,Item> find = new Finder<Long,Item>(
//             "default", Item.class
//     );
// 
//     public Item () {
//         tags = new ArrayList<>();
//     }
// 
//     public List<Tag> getTags() {
//         return tags;
//     }
// 
//     public void setTags(List<Tag> tags) {
//         this.tags = tags;
//     }
// }
// 
// Path: app/models/Tag.java
// @Entity
// public class Tag extends Model {
//     @Id
//     public Long id;
// 
//     public String name;
// 
//     @ManyToMany(cascade = CascadeType.ALL)
//     public List<Item> items;
// 
//     public static Finder<Long,Tag> find = new Finder<Long,Tag>(
//             "default", Tag.class
//     );
// 
//     public Tag () {
//         items = new ArrayList<>();
//     }
// 
//     public List<Item> getItems() {
//         return items;
//     }
// 
//     public void setItems(List<Item> items) {
//         this.items = items;
//     }
// }


import static org.junit.Assert.*;
import static play.test.Helpers.fakeApplication;
import static play.test.Helpers.running;
import com.avaje.ebean.Query;
import com.google.common.collect.ImmutableMap;
import models.Item;
import models.Tag;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import play.db.Database;
import play.db.Databases;
import play.db.evolutions.Evolutions;
import java.util.*;

            Tag retrievedTag1 = Tag.find.byId(t1.id);
            assertEquals("Tag 1 items count is not 2", 2, retrievedTag1.getItems().size());
            assertTrue("Tag 1 does not contain item 1", retrievedTag1.getItems().contains(i1));
            assertTrue("Tag 1 does not contain item 2", retrievedTag1.getItems().contains(i2));

            Tag retrievedTag2 = Tag.find.byId(t2.id);
            assertEquals("Tag 2 items count is not 2", 2, retrievedTag2.getItems().size());
            assertTrue("Tag 2 does not contain item 2", retrievedTag2.getItems().contains(i2));
            assertTrue("Tag 2 does not contain item 3", retrievedTag2.getItems().contains(i3));

            Tag retrievedTag3 = Tag.find.byId(t3.id);
            assertEquals("Tag 3 items count is not 2", 2, retrievedTag3.getItems().size());
            assertTrue("Tag 3 does not contain item 3", retrievedTag3.getItems().contains(i3));
            assertTrue("Tag 3 does not contain item 1", retrievedTag3.getItems().contains(i1));
        });
    }

    /**
     * Tests items' search by tags
     */
    @Test
    public void testItemsSearchByTags() throws Exception {
        running(fakeApplication(configOverrides), () -> {
            Tag t1 = new Tag();
            t1.save();

            Tag t2 = new Tag();
            t2.save();

// Path: app/models/Item.java
// @Entity
// public class Item extends Model {
//     @Id
//     public Long id;
// 
//     public String name;
// 
//     public String storageKey;
// 
//     public Date uploadDate;
// 
//     public Long fileSize;
// 
//     @ManyToMany(mappedBy = "items", cascade = CascadeType.ALL)
//     public List<Tag> tags;
// 
//     public static Finder<Long,Item> find = new Finder<Long,Item>(
//             "default", Item.class
//     );
// 
//     public Item () {
//         tags = new ArrayList<>();
//     }
// 
//     public List<Tag> getTags() {
//         return tags;
//     }
// 
//     public void setTags(List<Tag> tags) {
//         this.tags = tags;
//     }
// }
// 
// Path: app/models/Tag.java
// @Entity
// public class Tag extends Model {
//     @Id
//     public Long id;
// 
//     public String name;
// 
//     @ManyToMany(cascade = CascadeType.ALL)
//     public List<Item> items;
// 
//     public static Finder<Long,Tag> find = new Finder<Long,Tag>(
//             "default", Tag.class
//     );
// 
//     public Tag () {
//         items = new ArrayList<>();
//     }
// 
//     public List<Item> getItems() {
//         return items;
//     }
// 
//     public void setItems(List<Item> items) {
//         this.items = items;
//     }
// }


// Path: test/DatabaseTest.java
import static org.junit.Assert.*;
import static play.test.Helpers.fakeApplication;
import static play.test.Helpers.running;
import com.avaje.ebean.Query;
import com.google.common.collect.ImmutableMap;
import models.Item;
import models.Tag;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import play.db.Database;
import play.db.Databases;
import play.db.evolutions.Evolutions;
import java.util.*;


            Tag retrievedTag1 = Tag.find.byId(t1.id);
            assertEquals("Tag 1 items count is not 2", 2, retrievedTag1.getItems().size());
            assertTrue("Tag 1 does not contain item 1", retrievedTag1.getItems().contains(i1));
            assertTrue("Tag 1 does not contain item 2", retrievedTag1.getItems().contains(i2));

            Tag retrievedTag2 = Tag.find.byId(t2.id);
            assertEquals("Tag 2 items count is not 2", 2, retrievedTag2.getItems().size());
            assertTrue("Tag 2 does not contain item 2", retrievedTag2.getItems().contains(i2));
            assertTrue("Tag 2 does not contain item 3", retrievedTag2.getItems().contains(i3));

            Tag retrievedTag3 = Tag.find.byId(t3.id);
            assertEquals("Tag 3 items count is not 2", 2, retrievedTag3.getItems().size());
            assertTrue("Tag 3 does not contain item 3", retrievedTag3.getItems().contains(i3));
            assertTrue("Tag 3 does not contain item 1", retrievedTag3.getItems().contains(i1));
        });
    }

    /**
     * Tests items' search by tags
     */
    @Test
    public void testItemsSearchByTags() throws Exception {
        running(fakeApplication(configOverrides), () -> {
            Tag t1 = new Tag();
            t1.save();

            Tag t2 = new Tag();
            t2.save();

            Tag t3 = new Tag();