/**
 * Created with IntelliJ IDEA.
 * User: Jackie Ng
 * Date: 26/11/12
 * Time: 11:37 PM
 * To change this template use File | Settings | File Templates.
 */
import org.osgeo.mapguide.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * This test harness is to exercise the java.util.Collection implementation of the MapGuide proxy classes that implement it
 * and the common usage scenarios involving them
 */
public class MapGuideApiTest {

    static List<AssertException> assertFailures;
    static String sessionId;
    static String mapName;

    public static void main(String [] args) {
        assertFailures = new ArrayList<AssertException>();
        if (args.length == 1) {
            MapGuideJavaApiEx.MgInitializeWebTier(args[0]);            
        } else {
            if (System.getProperty("os.name").startsWith("Windows")) {
                MapGuideJavaApiEx.MgInitializeWebTier("C:\\Program Files\\OSGeo\\MapGuide\\Web\\www\\webconfig.ini");
            } else {
                MapGuideJavaApiEx.MgInitializeWebTier("/usr/local/mapguideopensource/webserverextensions/www/webconfig.ini");
            }
        }

        MgUserInformation userInfo = new MgUserInformation("Administrator", "admin");
        MgSiteConnection siteConn = new MgSiteConnection();
        siteConn.open(userInfo);

        MgSite site = siteConn.getSite();
        sessionId = site.createSession();
        userInfo.setMgSessionId(sessionId);

        MgMap map = new MgMap(siteConn);
        MgResourceService resSvc = (MgResourceService)siteConn.createService(MgServiceType.ResourceService);
        MgResourceIdentifier mdfId = new MgResourceIdentifier("Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition");
        mapName = mdfId.getName();
        map.create(mdfId, mapName);

        MgSelection sel = new MgSelection(map);
        sel.save(resSvc, mapName);

        MgResourceIdentifier mapStateId = new MgResourceIdentifier("Session:" + sessionId + "//" + mapName + "." + MgResourceType.Map);
        map.save(resSvc, mapStateId);

        System.out.println("Running tests");
        runTests(siteConn, map);
        System.exit(assertFailures.size());
    }

    private static void assertCondition(boolean condition, String failureMsg) {
        if (!condition)
            throw new AssertException(failureMsg);
    }

    private static void runTests(MgSiteConnection siteConn, MgMap map) {
        System.out.print(testFeatureSchemaCollection() ? "." : "F");
        System.out.print(testClassDefinitionCollection() ? "." : "F");
        System.out.print(testPropertyDefinitionCollection() ? "." : "F");
        System.out.print(testPropertyCollection() ? "." : "F");
        System.out.print(testStringCollection() ? "." : "F");
        System.out.print(testReadOnlyLayerCollection(siteConn, map) ? "." : "F");
        System.out.print(testLayerCollection(siteConn, map) ? "." : "F");
        System.out.print(testLayerGroupCollection(siteConn, map) ? "." : "F");
        System.out.println();
        if (assertFailures.size() > 0) {
            int i = 1;
            for (AssertException ex : assertFailures) {
                System.out.println("Assertion Failure: " + i);
                ex.printStackTrace(System.out);
                i++;
            }
        }
    }

    private static boolean testReadOnlyLayerCollection(MgSiteConnection siteConn, MgMap map) {
        try {

            MgFeatureQueryOptions query1 = new MgFeatureQueryOptions();
            query1.setFilter("Autogenerated_SDF_ID < 4");

            MgFeatureQueryOptions query2 = new MgFeatureQueryOptions();
            query2.setFilter("Autogenerated_SDF_ID < 4");

            MgLayerCollection layers = map.getLayers();
            MgLayerBase item1 = layers.getItem("Parcels");
            MgLayerBase item2 = layers.getItem("Buildings");

            MgFeatureReader fr1 = item1.selectFeatures(query1);
            MgFeatureReader fr2 = item2.selectFeatures(query2);

            MgResourceService resSvc = (MgResourceService)siteConn.createService(MgServiceType.ResourceService);
            MgSelection sel = new MgSelection(map);
            sel.open(resSvc, map.getName());
            sel.fromXml(""); //Clear
            try {
                sel.addFeatures(item1, fr1, 0);
                sel.addFeatures(item2, fr2, 0);
            } finally{
                fr1.close();
                fr2.close();
            }

            sel.save(resSvc);

            //Now we can test the collection
            MgReadOnlyLayerCollection items = sel.getLayers();

            assertCondition(items.getCount() == 2, "Expected 2 items");

            //NOTE: Possible bug in ordering of MgReadOnlyLayerCollection here (I had to reverse the order of layers
            //being tested) Nevertheless, were testing that the ordering (whether correct or not) is the same when iterated
            //in both the classical and iterative methods

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Buildings"), "Expected item #" + (i+1) + " to be Buildings");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Parcels"), "Expected item #" + (i+1) + " to be Parcels");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgLayerBase item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Buildings"), "Expected item #" + (i+1) + " to be Buildings");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Parcels"), "Expected item #" + (i+1) + " to be Parcels");
                        break;
                }
                i++;
            }
            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testStringCollection() {
        try {
            MgStringCollection items = new MgStringCollection();
            String item1 = "Item1";
            String item2 = "Item2";
            String item3 = "Item3";
            String item4 = "Item4";

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (String item : items) {
                String itemName = item;
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<String> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<String> testCollection = new ArrayList<String>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgClassDefinition()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof String, "Expected item to be String");
            }
            String[] fitems = facade.toArray(new String[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new String[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new String[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testPropertyCollection() {
        try {
            MgPropertyCollection items = new MgPropertyCollection();
            MgProperty item1 = new MgStringProperty("Item1", "Hello World");
            MgProperty item2 = new MgInt32Property("Item2", 42);
            MgProperty item3 = new MgBooleanProperty("Item3", false);
            MgProperty item4 = new MgByteProperty("Item4", (short)4);

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgProperty item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgProperty> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgProperty> testCollection = new ArrayList<MgProperty>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgClassDefinition()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            i = 0;
            for (Object o : itemArray) {
                assertCondition(o instanceof MgProperty, "Expected item to be MgProperty");
                switch(i) {
                    case 0:
                        assertCondition(o instanceof MgStringProperty, "Expected item to be MgStringProperty");
                        break;
                    case 1:
                        assertCondition(o instanceof MgBooleanProperty, "Expected item to be MgBooleanProperty");
                        break;
                }
                i++;
            }

            MgProperty[] fitems = facade.toArray(new MgProperty[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgProperty[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgProperty[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testClassDefinitionCollection() {
        try {
            MgFeatureSchema parent = new MgFeatureSchema("Parent", "");
            MgClassDefinitionCollection items = parent.getClasses();
            MgClassDefinition item1 = new MgClassDefinition(); item1.setName("Item1");
            MgClassDefinition item2 = new MgClassDefinition(); item2.setName("Item2");
            MgClassDefinition item3 = new MgClassDefinition(); item3.setName("Item3");
            MgClassDefinition item4 = new MgClassDefinition(); item4.setName("Item4");

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgClassDefinition item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgClassDefinition> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgClassDefinition> testCollection = new ArrayList<MgClassDefinition>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgFeatureSchema()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof MgClassDefinition, "Expected item to be MgClassDefinition");
            }
            MgClassDefinition[] fitems = facade.toArray(new MgClassDefinition[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgClassDefinition[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgClassDefinition[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testFeatureSchemaCollection() {
        try {
            MgFeatureSchemaCollection items = new MgFeatureSchemaCollection();
            MgFeatureSchema item1 = new MgFeatureSchema("Item1", "");
            MgFeatureSchema item2 = new MgFeatureSchema("Item2", "");
            MgFeatureSchema item3 = new MgFeatureSchema("Item3", "");
            MgFeatureSchema item4 = new MgFeatureSchema("Item4", "");

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgFeatureSchema item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgFeatureSchema> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgFeatureSchema> testCollection = new ArrayList<MgFeatureSchema>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgClassDefinition()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof MgFeatureSchema, "Expected item to be MgFeatureSchema");
            }
            MgFeatureSchema[] fitems = facade.toArray(new MgFeatureSchema[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgFeatureSchema[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgFeatureSchema[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testPropertyDefinitionCollection() {
        try {
            MgClassDefinition parent = new MgClassDefinition();
            parent.setName("Parent");
            MgPropertyDefinitionCollection items = parent.getProperties();
            MgPropertyDefinition item1 = new MgDataPropertyDefinition("Item1");
            MgPropertyDefinition item2 = new MgDataPropertyDefinition("Item2");
            MgPropertyDefinition item3 = new MgDataPropertyDefinition("Item3");
            MgPropertyDefinition item4 = new MgDataPropertyDefinition("Item4");

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgPropertyDefinition item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgPropertyDefinition> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgPropertyDefinition> testCollection = new ArrayList<MgPropertyDefinition>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgFeatureSchema()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof MgPropertyDefinition, "Expected item to be MgPropertyDefinition");
            }
            MgPropertyDefinition[] fitems = facade.toArray(new MgPropertyDefinition[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgPropertyDefinition[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgPropertyDefinition[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testLayerCollection(MgSiteConnection siteConn, MgMap map) {
        try {
            map.open(mapName);
            MgResourceService resSvc = (MgResourceService)siteConn.createService(MgServiceType.ResourceService);
            MgLayerCollection items = map.getLayers();
            items.clear();
            MgResourceIdentifier ldfId = new MgResourceIdentifier("Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition");
            MgLayerBase item1 = new MgLayer(ldfId, resSvc);
            item1.setName("Item1");
            MgLayerBase item2 = new MgLayer(ldfId, resSvc);
            item2.setName("Item2");
            MgLayerBase item3 = new MgLayer(ldfId, resSvc);
            item3.setName("Item3");
            MgLayerBase item4 = new MgLayer(ldfId, resSvc);
            item4.setName("Item4");

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgLayerBase item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgLayerBase> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgLayerBase> testCollection = new ArrayList<MgLayerBase>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgFeatureSchema()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof MgLayerBase, "Expected item to be MgLayerBase");
            }
            MgLayerBase[] fitems = facade.toArray(new MgLayerBase[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgLayerBase[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgLayerBase[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }

    private static boolean testLayerGroupCollection(MgSiteConnection siteConn, MgMap map) {
        try {
            map.open(mapName);
            MgResourceService resSvc = (MgResourceService)siteConn.createService(MgServiceType.ResourceService);
            MgLayerGroupCollection items = map.getLayerGroups();
            items.clear();
            MgResourceIdentifier ldfId = new MgResourceIdentifier("Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition");
            MgLayerGroup item1 = new MgLayerGroup("Item1");
            MgLayerGroup item2 = new MgLayerGroup("Item2");
            MgLayerGroup item3 = new MgLayerGroup("Item3");
            MgLayerGroup item4 = new MgLayerGroup("Item4");

            //Items inserted the MapGuide API way
            items.addItem(item1);
            items.addItem(item2);
            items.addItem(item3);

            assertCondition(items.getCount() == 3, "Expected 3 items");
            assertCondition(!items.isEmpty(), "Expected non-empty item collection");

            int i = 0;
            //Looping the classic way
            for (i = 0; i < items.getCount(); i++) {
                switch (i){
                    case 0:
                        assertCondition(items.getItem(i).getName().equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(items.getItem(i).getName().equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(items.getItem(i).getName().equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
            }

            //Looping the iterative way
            i = 0;
            for (MgLayerGroup item : items) {
                String itemName = item.getName();
                switch (i){
                    case 0:
                        assertCondition(itemName.equals("Item1"), "Expected item #" + (i+1) + " to be Item1");
                        break;
                    case 1:
                        assertCondition(itemName.equals("Item2"), "Expected item #" + (i+1) + " to be Item2");
                        break;
                    case 2:
                        assertCondition(itemName.equals("Item3"), "Expected item #" + (i+1) + " to be Item3");
                        break;
                }
                i++;
            }

            items.clear();
            assertCondition(items.getCount() == 0, "Expected empty item collection");
            assertCondition(items.isEmpty(), "Expected empty item collection");

            //Now test through java.util.Collection facade
            Collection<MgLayerGroup> facade = items;
            //add()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");

            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //contains()
            assertCondition(facade.contains(item1), "item1 should exist");
            assertCondition(facade.contains(item2), "item2 should exist");
            assertCondition(facade.contains(item3), "item3 should exist");

            ArrayList<MgLayerGroup> testCollection = new ArrayList<MgLayerGroup>();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);

            //containsAll()
            assertCondition(facade.containsAll(testCollection), "All items in test collection should match");
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item4);
            assertCondition(!facade.containsAll(testCollection), "Should not have matched test collection");

            facade.clear();
            assertCondition(facade.size() == 0, "Expected 0 items");
            assertCondition(facade.isEmpty(), "Expected empty item collection");

            //addAll()
            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item2);
            testCollection.add(item3);
            assertCondition(facade.addAll(testCollection), "Expected addAll() success");
            assertCondition(facade.size() == 3, "Expected 3 items");
            assertCondition(!facade.isEmpty(), "Expected non-empty item collection");

            //remove()
            assertCondition(!facade.remove(item4), "Expected remove() of non-existent item to return false");
            assertCondition(!facade.remove(new MgFeatureSchema()), "Expected remove() of different type to return false");
            assertCondition(facade.remove(item2), "Expected remove() of item2 to return true");

            //removeAll()
            testCollection.remove(item2);
            assertCondition(facade.removeAll(testCollection), "Expected removeAll() to succeed");

            //retainAll()
            assertCondition(facade.add(item1), "Could not add item1 the java.util.Collection way");
            assertCondition(facade.add(item2), "Could not add item2 the java.util.Collection way");
            assertCondition(facade.add(item3), "Could not add item3 the java.util.Collection way");
            assertCondition(facade.size() == 3, "Expected 3 schemas");
            assertCondition(!facade.isEmpty(), "Expected non-empty schema collection");

            testCollection.clear();
            testCollection.add(item1);
            testCollection.add(item3);
            assertCondition(facade.retainAll(testCollection), "Expected retainAll() to succeed");
            assertCondition(facade.contains(item1), "Expected item1 to exist");
            assertCondition(!facade.contains(item2), "Expected item2 to not exist");
            assertCondition(facade.contains(item3), "Expected item3 to exist");

            //toArray()
            Object[] itemArray = facade.toArray();
            assertCondition(itemArray != null, "Expected non-null item array");
            assertCondition(itemArray.length == 2, "Expected 2 item array");
            for (Object o : itemArray) {
                assertCondition(o instanceof MgLayerGroup, "Expected item to be MgLayerBase");
            }
            MgLayerGroup[] fitems = facade.toArray(new MgLayerGroup[0]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgLayerGroup[1]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 2, "Expected 2 item array");

            fitems = facade.toArray(new MgLayerGroup[3]);
            assertCondition(fitems != null, "Expected non-null item array");
            assertCondition(fitems.length == 3, "Expected 3 item array");
            assertCondition(fitems[0] != null, "Expected non-null item #1");
            assertCondition(fitems[1] != null, "Expected non-null item #2");
            assertCondition(fitems[2] == null, "Expected null item #3");

            return true;
        }
        catch (MgException ex) {
            assertCondition(false, ex.getMessage());
        }
        catch (AssertException ex) {
            assertFailures.add(ex);
        }
        return false;
    }
}
