/**
 * Copyright (c) 2008-2012, http://www.snakeyaml.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.yaml.snakeyaml.issues.issue73;

import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import junit.framework.TestCase;

import org.yaml.snakeyaml.Util;
import org.yaml.snakeyaml.Yaml;

public class RecursiveSortedSetTest extends TestCase {
    public void testDumpException() {
        SortedSet<Object> set = new TreeSet<Object>();
        Bean11 bean = new Bean11();
        bean.setId("ID555");
        bean.setSet(set);
        set.add("ggg");
        set.add("hhh");
        set.add(bean);
        Yaml yaml = new Yaml();
        String doc = yaml.dump(bean);
        // System.out.println(doc);
        assertEquals(Util.getLocalResource("issues/issue73-recursive9.txt"), doc);
    }

    public void testLoadException() {
        String doc = Util.getLocalResource("issues/issue73-recursive10.txt");
        // System.out.println(doc);
        Yaml yaml = new Yaml();
        try {
            yaml.load(doc);
            fail("Recursive sets are not supported.");
        } catch (Exception e) {
            assertTrue(e.getMessage(), e.getMessage().contains("Set cannot be recursive."));
        }
    }

    /**
     * XXX: sets can be recursive
     */
    public void testLoadRecursiveTest() {
        String doc = Util.getLocalResource("issues/issue73-recursive9.txt");
        // System.out.println(doc);
        Yaml yaml = new Yaml();
        Bean11 obj = (Bean11) yaml.load(doc);
        Set<Object> set = obj.getSet();
        // System.out.println(set);
        assertEquals(TreeSet.class, set.getClass());
        assertEquals("ID555", obj.getId());
        assertEquals(3, set.size());
        assertTrue(set.remove("ggg"));
        assertTrue(set.remove("hhh"));
        //
        Bean11 beanRef = (Bean11) set.iterator().next();
        assertEquals(obj, beanRef);
        assertSame(obj, beanRef);
        //
        try {
            set.add(obj);
            fail("Recursive set fails to provide a hashcode.");
        } catch (StackOverflowError e) {
            // ignore
        }
        set.clear();
        assertTrue("Empty set is not recursive.", set.add(obj));
    }

    public static class Bean11 implements Comparable<Object> {
        private SortedSet<Object> set;
        private String id;

        public SortedSet<Object> getSet() {
            return set;
        }

        public void setSet(SortedSet<Object> set) {
            this.set = set;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public int compareTo(Object o) {
            return id.compareTo(o.toString());
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Bean11) {
                Bean11 b = (Bean11) obj;
                return id.equals(b.id);
            } else {
                return false;
            }
        }

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

        @Override
        public String toString() {
            return "Bean id=" + id + "set=" + set.toString();
        }
    }
}

@@ -1780,34 +1780,44 @@
   * 
-XXX: sets can be recursive
+set and JavaBean refer to each other
 %0A   
@@ -2023,19 +2023,27 @@
  Bean11 
-obj
+beanWithSet
  = (Bean
@@ -2092,55 +2092,27 @@
 t = 
-obj.getSet();%0A        // System.out.println(s
+beanWithSet.getS
 et
+(
 );%0A 
@@ -2193,19 +2193,27 @@
 ID555%22, 
-obj
+beanWithSet
 .getId()
@@ -2287,24 +2287,70 @@
 ve(%22ggg%22));%0A
+        // assertFalse(set.remove(%22ggg%22));???%0A
         asse
@@ -2372,24 +2372,61 @@
 ve(%22hhh%22));%0A
+        assertEquals(1, set.size());%0A
         //%0A 
@@ -2502,19 +2502,27 @@
 tEquals(
-obj
+beanWithSet
 , beanRe
@@ -2544,19 +2544,27 @@
 ertSame(
-obj
+beanWithSet
 , beanRe
@@ -2590,195 +2590,214 @@
     
-try %7B%0A            set.add(obj);%0A            fail(%22Recursive set fails to provide a hashcode.%22);%0A        %7D catch (StackOverflowError e) %7B%0A            // ignore%0A        %7D%0A        set.clear(
+assertFalse(set.isEmpty());%0A        assertTrue(set.contains(beanWithSet));%0A        assertFalse(set.add(beanWithSet));%0A        assertTrue(set.remove(beanWithSet));%0A        assertFalse(set.remove(beanWithSet)
 );%0A 
@@ -2818,50 +2818,20 @@
 rue(
-%22Empty 
 set
- is not recursive.%22, set.add(obj
+.isEmpty(
 ));%0A
@@ -3339,18 +3339,26 @@
  return 
-id
+toString()
 .compare
@@ -3715,18 +3715,26 @@
  return 
-id
+toString()
 .hashCod
@@ -3852,21 +3852,35 @@
 %22 + 
-set.toString(
+System.identityHashCode(set
 );%0A 

Improve RecursiveSortedSetTest