@Override
    public boolean equals(Object o)
    {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ZMsg zMsg = (ZMsg) o;

        //based on AbstractList
        Iterator<ZFrame> e1 = frames.iterator();
        Iterator<ZFrame> e2 = zMsg.frames.iterator();
        while (e1.hasNext() && e2.hasNext()) {
            ZFrame o1 = e1.next();
            ZFrame o2 = e2.next();
            if (!(Objects.equals(o1, o2))) {
                return false;
            }
        }
        return !(e1.hasNext() || e2.hasNext());
    }
@Test
    public void testEquals()
    {
        ZMsg msg = new ZMsg().addString("123");
        ZMsg other = new ZMsg();

        assertThat(msg.equals(msg), is(true));
        assertThat(msg.equals(null), is(false));
        assertThat(msg.equals(""), is(false));

        assertThat(msg.equals(other), is(false));

        other.add("345");
        assertThat(msg.equals(other), is(false));
        other.popString();
        other.add("123");
        assertThat(msg.equals(other), is(true));

        assertThat(msg.duplicate(), is(msg));

        msg.destroy();
    }