http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
new file mode 100755
index 0000000..2b76236
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
@@ -0,0 +1,114 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.internal.ClassUtils.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+public class ClassUtilsTest {
+
+       
//====================================================================================================
+       // getReadableClassName(Class)
+       // getReadableClassName(String)
+       
//====================================================================================================
+       @Test
+       public void testGetReadableClassName() throws Exception {
+               assertEquals("java.lang.Object", 
getReadableClassName(Object.class));
+               assertEquals("java.lang.Object[]", 
getReadableClassName(Object[].class));
+               assertEquals("java.lang.Object[][]", 
getReadableClassName(Object[][].class));
+
+               assertEquals("boolean", getReadableClassName(boolean.class));
+               assertEquals("boolean[]", 
getReadableClassName(boolean[].class));
+               assertEquals("boolean[][]", 
getReadableClassName(boolean[][].class));
+
+               assertEquals("byte", getReadableClassName(byte.class));
+               assertEquals("byte[]", getReadableClassName(byte[].class));
+               assertEquals("byte[][]", getReadableClassName(byte[][].class));
+
+               assertEquals("char", getReadableClassName(char.class));
+               assertEquals("char[]", getReadableClassName(char[].class));
+               assertEquals("char[][]", getReadableClassName(char[][].class));
+
+               assertEquals("double", getReadableClassName(double.class));
+               assertEquals("double[]", getReadableClassName(double[].class));
+               assertEquals("double[][]", 
getReadableClassName(double[][].class));
+
+               assertEquals("float", getReadableClassName(float.class));
+               assertEquals("float[]", getReadableClassName(float[].class));
+               assertEquals("float[][]", 
getReadableClassName(float[][].class));
+
+               assertEquals("int", getReadableClassName(int.class));
+               assertEquals("int[]", getReadableClassName(int[].class));
+               assertEquals("int[][]", getReadableClassName(int[][].class));
+
+               assertEquals("long", getReadableClassName(long.class));
+               assertEquals("long[]", getReadableClassName(long[].class));
+               assertEquals("long[][]", getReadableClassName(long[][].class));
+
+               assertEquals("short", getReadableClassName(short.class));
+               assertEquals("short[]", getReadableClassName(short[].class));
+               assertEquals("short[][]", 
getReadableClassName(short[][].class));
+
+               assertNull(getReadableClassName((Class<?>)null));
+               assertNull(getReadableClassName((String)null));
+       }
+
+       
//====================================================================================================
+       // isParentClass(Class, Class)
+       
//====================================================================================================
+       @Test
+       public void testIsParentClass() throws Exception {
+
+               // Strict
+               assertTrue(isParentClass(A.class, A1.class, true));
+               assertTrue(isParentClass(A1.class, A2.class, true));
+               assertTrue(isParentClass(Object.class, A2.class, true));
+               assertFalse(isParentClass(A.class, A.class, true));
+               assertFalse(isParentClass(A1.class, A1.class, true));
+               assertFalse(isParentClass(A2.class, A2.class, true));
+               assertFalse(isParentClass(A2.class, A1.class, true));
+               assertFalse(isParentClass(A1.class, A.class, true));
+               assertFalse(isParentClass(A2.class, Object.class, true));
+
+               // Not strict
+               assertTrue(isParentClass(A.class, A1.class, false));
+               assertTrue(isParentClass(A1.class, A2.class, false));
+               assertTrue(isParentClass(Object.class, A2.class, false));
+               assertTrue(isParentClass(A.class, A.class, false));
+               assertTrue(isParentClass(A1.class, A1.class, false));
+               assertTrue(isParentClass(A2.class, A2.class, false));
+               assertFalse(isParentClass(A2.class, A1.class, false));
+               assertFalse(isParentClass(A1.class, A.class, false));
+               assertFalse(isParentClass(A2.class, Object.class, false));
+       }
+
+       public interface A {}
+
+       public static class A1 implements A {}
+
+       public static class A2 extends A1 {}
+
+       
//====================================================================================================
+       // getReadableClassNames(Object[])
+       
//====================================================================================================
+       @Test
+       public void testGetReadableClassNames() throws Exception {
+               
assertEquals("['java.lang.String','java.lang.Integer','java.lang.Boolean','null']",
 getReadableClassNames(new Object[]{"a",1,true,null}).toString());
+       }
+
+       public void getClassFromReadableName() throws Exception {
+               fail("Not implemented");
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
new file mode 100755
index 0000000..b0446d7
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
@@ -0,0 +1,34 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.internal.CollectionUtils.*;
+import static org.junit.Assert.*;
+
+import org.apache.juneau.*;
+import org.junit.*;
+
+public class CollectionUtilsTest {
+
+       
//====================================================================================================
+       // reverse(LinkedHashMap)
+       
//====================================================================================================
+       @Test
+       public void testReverse() throws Exception {
+               assertNull(reverse(null));
+
+               assertObjectEquals("{b:2,a:1}", reverse(new 
ObjectMap("{a:1,b:2}")));
+               assertObjectEquals("{}", reverse(new ObjectMap("{}")));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/FilteredMapTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
new file mode 100755
index 0000000..b09ac9d
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
@@ -0,0 +1,44 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class FilteredMapTest {
+
+       Map<?,?> m3;
+
+       
//====================================================================================================
+       // testBasic
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+               ObjectMap m = new ObjectMap("{a:'1',b:'2'}");
+               FilteredMap<String,Object> m2 = new 
FilteredMap<String,Object>(m, new String[]{"a"});
+
+               assertObjectEquals("{a:'1'}", m2);
+
+               m2.entrySet().iterator().next().setValue("3");
+               assertObjectEquals("{a:'3'}", m2);
+
+               try { m3 = new FilteredMap<String,String>(null, new String[0]); 
fail(); } catch (IllegalArgumentException e) {}
+               try { m3 = new FilteredMap<String,Object>(m, null); fail(); } 
catch (IllegalArgumentException e) {}
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOPipeTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOPipeTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOPipeTest.java
new file mode 100755
index 0000000..6d9a1be
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOPipeTest.java
@@ -0,0 +1,282 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.IOPipe.*;
+import org.junit.*;
+
+public class IOPipeTest {
+
+       
//====================================================================================================
+       // IOPipe(Object input, Object output)
+       
//====================================================================================================
+       @Test
+       public void testConstructor() throws Exception {
+               try { IOPipe.create(null, new StringWriter()); fail(); } catch 
(IllegalArgumentException e) {}
+               try { IOPipe.create(new StringReader(""), null); fail(); } 
catch (IllegalArgumentException e) {}
+               try { IOPipe.create(new Integer(1), new StringWriter()); 
fail(); } catch (IllegalArgumentException e) {}
+               try { IOPipe.create("", new Integer(1)); fail(); } catch 
(IllegalArgumentException e) {}
+       }
+
+       
//====================================================================================================
+       // closeOut()
+       // close(boolean in, boolean out)
+       
//====================================================================================================
+       @Test
+       public void testClose() throws Exception {
+               TestReader in;
+               TestWriter out;
+               TestInputStream in2;
+               TestOutputStream out2;
+
+               in = new TestReader("foobar");
+               out = new TestWriter();
+               IOPipe.create(in, out).run();
+               assertTrue(in.closed);
+               assertFalse(out.closed);
+               assertEquals("foobar", out.toString());
+
+               in = new TestReader("foobar");
+               out = new TestWriter();
+               IOPipe.create(in, out).closeOut().run();
+               assertTrue(in.closed);
+               assertTrue(out.closed);
+               assertEquals("foobar", out.toString());
+
+               in = new TestReader("foobar");
+               out = new TestWriter();
+               IOPipe.create(in, out).close(false, true).run();
+               assertFalse(in.closed);
+               assertTrue(out.closed);
+               assertEquals("foobar", out.toString());
+
+               in2 = new TestInputStream("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in2, out2).run();
+               assertTrue(in2.closed);
+               assertFalse(out2.closed);
+               assertEquals("foobar", out2.toString());
+
+               in2 = new TestInputStream("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in2, out2).closeOut().run();
+               assertTrue(in2.closed);
+               assertTrue(out2.closed);
+               assertEquals("foobar", out2.toString());
+
+               in2 = new TestInputStream("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in2, out2).close(false, true).run();
+               assertFalse(in2.closed);
+               assertTrue(out2.closed);
+               assertEquals("foobar", out2.toString());
+
+               in = new TestReader("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in, out2).run();
+               assertTrue(in.closed);
+               assertFalse(out2.closed);
+               assertEquals("foobar", out.toString());
+
+               in = new TestReader("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in, out2).closeOut().run();
+               assertTrue(in.closed);
+               assertTrue(out2.closed);
+               assertEquals("foobar", out.toString());
+
+               in = new TestReader("foobar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in, out2).close(false, true).run();
+               assertFalse(in.closed);
+               assertTrue(out2.closed);
+               assertEquals("foobar", out.toString());
+
+               in2 = new TestInputStream("foobar");
+               out = new TestWriter();
+               IOPipe.create(in2, out).run();
+               assertTrue(in2.closed);
+               assertFalse(out.closed);
+               assertEquals("foobar", out2.toString());
+
+               in2 = new TestInputStream("foobar");
+               out = new TestWriter();
+               IOPipe.create(in2, out).closeOut().run();
+               assertTrue(in2.closed);
+               assertTrue(out.closed);
+               assertEquals("foobar", out2.toString());
+
+               in2 = new TestInputStream("foobar");
+               out = new TestWriter();
+               IOPipe.create(in2, out).close(false, true).run();
+               assertFalse(in2.closed);
+               assertTrue(out.closed);
+               assertEquals("foobar", out2.toString());
+       }
+
+
+       public static class TestReader extends StringReader {
+               boolean closed;
+
+               public TestReader(String s) {
+                       super(s);
+               }
+
+               @Override /* Reader */
+               public void close() {
+                       closed = true;
+               }
+       }
+
+       public static class TestWriter extends StringWriter {
+               boolean closed;
+
+               public TestWriter() {
+                       super();
+               }
+
+               @Override /* Writer */
+               public void close() {
+                       closed = true;
+               }
+       }
+
+       public static class TestInputStream extends ByteArrayInputStream {
+               boolean closed;
+
+               public TestInputStream(String s) {
+                       super(s.getBytes());
+               }
+
+               @Override /* InputStream */
+               public void close() throws IOException {
+                       super.close();
+                       closed = true;
+               }
+       }
+
+       public static class TestOutputStream extends ByteArrayOutputStream {
+               boolean closed;
+
+               public TestOutputStream() {
+                       super();
+               }
+
+               @Override /* OutputStream */
+               public void close() throws IOException {
+                       super.close();
+                       closed = true;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return new String(this.toByteArray(), IOUtils.UTF8);
+               }
+       }
+
+       
//====================================================================================================
+       // byLines()
+       // byLines(boolean)
+       
//====================================================================================================
+       @Test
+       public void testByLines() throws Exception {
+               TestReader in;
+               TestWriter out;
+
+               in = new TestReader("foo\nbar");
+               out = new TestWriter() {
+                       @Override public void write(String s) {
+                               super.write("["+s+"]");
+                       }
+               };
+               IOPipe.create(in, out).byLines().run();
+               assertEquals("[foo][][bar][]", 
out.toString().replaceAll("[\\r\\n]", ""));
+
+               in = new TestReader("foo\nbar");
+               out = new TestWriter() {
+                       @Override public void write(String s) {
+                               super.write("["+s+"]");
+                       }
+               };
+               IOPipe.create(in, out).byLines(true).run();
+               assertEquals("[foo][][bar][]", 
out.toString().replaceAll("[\\r\\n]", ""));
+
+               in = new TestReader("foo\nbar");
+               out = new TestWriter() {
+                       @Override public void write(String s) {
+                               super.write("["+s+"]");
+                       }
+               };
+               IOPipe.create(in, out).byLines(false).run();
+               assertEquals("foo\nbar", out.toString());
+       }
+
+       
//====================================================================================================
+       // lineProcessor()
+       
//====================================================================================================
+       @Test
+       public void testLineProcessor() throws Exception {
+               TestReader in;
+               TestWriter out;
+               LineProcessor lp = new LineProcessor() {
+                       @Override /* LineProcessor */
+                       public String process(String line) {
+                               return "[" + line + "]";
+                       }
+               };
+
+               in = new TestReader("foo\nbar");
+               out = new TestWriter();
+               IOPipe.create(in, out).lineProcessor(lp).run();
+               assertEquals("[foo][bar]", 
out.toString().replaceAll("[\\r\\n]", ""));
+
+               LineProcessor lp2 = new LineProcessor() {
+                       @Override /* LineProcessor */
+                       public String process(String line) {
+                               return line.equals("foo") ? null : line;
+                       }
+               };
+               in = new TestReader("foo\nbar");
+               out = new TestWriter();
+               IOPipe.create(in, out).lineProcessor(lp2).run();
+               assertEquals("bar", out.toString().replaceAll("[\\r\\n]", ""));
+
+               TestInputStream in2;
+               TestOutputStream out2;
+               in2 = new TestInputStream("foo\nbar");
+               out2 = new TestOutputStream();
+               IOPipe.create(in2, out2).lineProcessor(lp).run();
+               assertEquals("[foo][bar]", 
out2.toString().replaceAll("[\\r\\n]", ""));
+       }
+
+       
//====================================================================================================
+       // buffSize()
+       
//====================================================================================================
+       @Test
+       public void testBuffSize() throws Exception {
+               TestReader in;
+               TestWriter out;
+
+               in = new TestReader("foobar");
+               out = new TestWriter();
+               IOPipe.create(in, out).buffSize(1).run();
+               assertEquals("foobar", out.toString().replaceAll("[\\r\\n]", 
""));
+
+               try { IOPipe.create(in, out).buffSize(0); fail(); } catch 
(IllegalArgumentException e) {}
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOUtilsTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
new file mode 100755
index 0000000..596d5bb
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
@@ -0,0 +1,103 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class IOUtilsTest {
+
+       
//====================================================================================================
+       // read(File)
+       // read(InputStream, Charset)
+       // read(InputStream)
+       // read(Reader, int, int)
+       
//====================================================================================================
+       @Test
+       public void testRead() throws Exception {
+
+               TestReader in;
+               TestWriter out;
+
+               in = new TestReader("foobar");
+               out = new TestWriter();
+               IOPipe.create(in, out).run();
+               assertTrue(in.closed);
+               assertFalse(out.closed);
+               assertEquals("foobar", out.toString());
+       }
+
+
+       public static class TestReader extends StringReader {
+               boolean closed;
+
+               public TestReader(String s) {
+                       super(s);
+               }
+
+               @Override /* Reader */
+               public void close() {
+                       closed = true;
+               }
+       }
+
+       public static class TestWriter extends StringWriter {
+               boolean closed;
+
+               public TestWriter() {
+                       super();
+               }
+
+               @Override /* Writer */
+               public void close() {
+                       closed = true;
+               }
+       }
+
+       public static class TestInputStream extends ByteArrayInputStream {
+               boolean closed;
+
+               public TestInputStream(String s) {
+                       super(s.getBytes());
+               }
+
+               @Override /* InputStream */
+               public void close() throws IOException {
+                       super.close();
+                       closed = true;
+               }
+       }
+
+       public static class TestOutputStream extends ByteArrayOutputStream {
+               boolean closed;
+
+               public TestOutputStream() {
+                       super();
+               }
+
+               @Override /* OutputStream */
+               public void close() throws IOException {
+                       super.close();
+                       closed = true;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return new String(this.toByteArray(), IOUtils.UTF8);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/IdentityListTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/IdentityListTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IdentityListTest.java
new file mode 100755
index 0000000..e554e49
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/IdentityListTest.java
@@ -0,0 +1,38 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class IdentityListTest {
+
+       
//====================================================================================================
+       // test - Basic tests
+       
//====================================================================================================
+       @Test
+       public void test() throws Exception {
+               List<String> l = new IdentityList<String>();
+               String a = "a";
+               l.add(a);
+               l.add(a);
+               l.add("b");
+               assertEquals(2, l.size());
+               assertTrue(l.contains("a"));
+               assertFalse(l.contains("c"));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/KeywordStoreTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/KeywordStoreTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/KeywordStoreTest.java
new file mode 100755
index 0000000..b267b06
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/KeywordStoreTest.java
@@ -0,0 +1,45 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class KeywordStoreTest {
+
+       
//====================================================================================================
+       // test - Basic tests
+       
//====================================================================================================
+       @Test
+       public void test() throws Exception {
+               KeywordSet ks = new KeywordSet("aaa", "zzz");
+               assertTrue(ks.contains("aaa"));
+               assertTrue(ks.contains("zzz"));
+               assertFalse(ks.contains("xxx"));
+               assertFalse(ks.contains("aaaa"));
+               assertFalse(ks.contains("zzzz"));
+               assertFalse(ks.contains("\u0000\u1000"));
+               assertFalse(ks.contains("z"));
+               assertFalse(ks.contains(null));
+               assertFalse(ks.contains("a|"));
+               assertFalse(ks.contains("|a"));
+               assertFalse(ks.contains("Aa"));
+               assertFalse(ks.contains("aA"));
+
+               for (String s : new String[]{"a","aA","Aa","a|","|a"}) {
+                       try { ks = new KeywordSet(s); fail(); } catch 
(IllegalArgumentException e) {}
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiIterableTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiIterableTest.java
 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiIterableTest.java
new file mode 100755
index 0000000..2418b44
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiIterableTest.java
@@ -0,0 +1,70 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class MultiIterableTest {
+
+       
//====================================================================================================
+       // Basic tests
+       
//====================================================================================================
+       @SuppressWarnings({ "unchecked", "rawtypes" })
+       @Test
+       public void test() throws Exception {
+               List
+                       l1 = new ObjectList(),
+                       l2 = new ObjectList("['a','b']"),
+                       l3 = new ObjectList("['c']");
+
+               MultiIterable mi = new 
MultiIterable(l1.iterator(),l2.iterator());
+               mi.append(l3.iterator());
+
+               assertObjectEquals("['a','b','c']", mi.iterator());
+
+               mi = new MultiIterable(l1.iterator());
+               assertObjectEquals("[]", mi.iterator());
+
+               mi = new MultiIterable(l2.iterator(), l1.iterator());
+               assertObjectEquals("['a','b']", mi.iterator());
+
+               mi = new MultiIterable(l2.iterator(), l1.iterator(), 
l3.iterator());
+               assertObjectEquals("['a','b','c']", mi.iterator());
+
+               mi = new MultiIterable();
+               assertObjectEquals("[]", mi.iterator());
+
+               try { mi.append(null); fail(); } catch 
(IllegalArgumentException e) {}
+
+               mi = new MultiIterable(l1.iterator());
+               try { mi.iterator().next(); fail(); } catch 
(NoSuchElementException e) {}
+
+               mi = new MultiIterable(l1.iterator());
+               Iterator i = mi.iterator();
+               assertFalse(i.hasNext());
+               try { i.remove(); fail(); } catch (NoSuchElementException e) {}
+
+               mi = new MultiIterable(l2.iterator());
+               i = mi.iterator();
+               assertTrue(i.hasNext());
+               assertEquals("a", i.next());
+               i.remove();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiSetTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiSetTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiSetTest.java
new file mode 100755
index 0000000..4d6d927
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/utils/MultiSetTest.java
@@ -0,0 +1,143 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class MultiSetTest {
+
+       @Test
+       @SuppressWarnings({ "unchecked" })
+       public void doTest() throws Exception {
+               List<String> l1, l2;
+               MultiSet<String> ms;
+               Iterator<String> i;
+
+               l1 = Arrays.asList(new String[]{"1","2"});
+               l2 = Arrays.asList(new String[]{"3","4"});
+               ms = new MultiSet<String>(l1, l2);
+               i = ms.iterator();
+               assertTrue(i.hasNext());
+               assertEquals("1", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("2", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("3", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("4", i.next());
+               assertFalse(i.hasNext());
+               try {
+                       i.next();
+                       fail("Exception expected");
+               } catch (NoSuchElementException e) {
+               }
+
+               l1 = Arrays.asList(new String[]{"1","2"});
+               l2 = Arrays.asList(new String[]{});
+               ms = new MultiSet<String>(l1, l2);
+               i = ms.iterator();
+               assertTrue(i.hasNext());
+               assertEquals("1", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("2", i.next());
+               assertFalse(i.hasNext());
+               try {
+                       i.next();
+                       fail("Exception expected");
+               } catch (NoSuchElementException e) {
+               }
+
+               l1 = Arrays.asList(new String[]{});
+               l2 = Arrays.asList(new String[]{"3","4"});
+               ms = new MultiSet<String>(l1, l2);
+               i = ms.iterator();
+               assertTrue(i.hasNext());
+               assertEquals("3", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("4", i.next());
+               assertFalse(i.hasNext());
+               try {
+                       i.next();
+                       fail("Exception expected");
+               } catch (NoSuchElementException e) {
+               }
+
+               l1 = Arrays.asList(new String[]{});
+               l2 = Arrays.asList(new String[]{});
+               ms = new MultiSet<String>(l1, l2);
+               i = ms.iterator();
+               assertFalse(i.hasNext());
+               try {
+                       i.next();
+                       fail("Exception expected");
+               } catch (NoSuchElementException e) {
+               }
+
+               l1 = Arrays.asList(new String[]{"1","2"});
+               ms = new MultiSet<String>(l1);
+               i = ms.iterator();
+               assertTrue(i.hasNext());
+               assertEquals("1", i.next());
+               assertTrue(i.hasNext());
+               assertEquals("2", i.next());
+               assertFalse(i.hasNext());
+               try {
+                       i.next();
+                       fail("Exception expected");
+               } catch (NoSuchElementException e) {
+               }
+
+               l1 = new LinkedList<String>(Arrays.asList(new 
String[]{"1","2"}));
+               l2 = new LinkedList<String>(Arrays.asList(new 
String[]{"3","4"}));
+               ms = new MultiSet<String>(l1).append(l2);
+               assertObjectEquals("['1','2','3','4']", ms);
+               assertObjectEquals("['1','2','3','4']", ms.enumerator());
+               assertEquals(4, ms.size());
+
+               Iterator<String> t = ms.iterator();
+               t.next();
+               t.remove();
+               assertObjectEquals("['2','3','4']", ms.enumerator());
+
+               t = ms.iterator();
+               t.next();
+               t.remove();
+               assertObjectEquals("['3','4']", ms.enumerator());
+
+               t = ms.iterator();
+               t.next();
+               t.remove();
+               assertObjectEquals("['4']", ms.enumerator());
+
+               t = ms.iterator();
+               t.next();
+               t.remove();
+               assertObjectEquals("[]", ms.enumerator());
+               assertEquals(0, ms.size());
+
+               ms = new MultiSet<String>();
+               assertObjectEquals("[]", ms);
+               assertEquals(0, ms.size());
+
+               try { ms = new MultiSet<String>((Collection<String>)null); 
fail(); } catch (IllegalArgumentException e) {}
+               try { new MultiSet<String>().iterator().next(); fail(); } catch 
(NoSuchElementException e) {}
+               try { new MultiSet<String>().iterator().remove(); fail(); } 
catch (NoSuchElementException e) {}
+
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/ParserReaderTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/ParserReaderTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/ParserReaderTest.java
new file mode 100755
index 0000000..c4b7e01
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/ParserReaderTest.java
@@ -0,0 +1,48 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.parser.*;
+import org.junit.*;
+
+public class ParserReaderTest {
+
+       
//====================================================================================================
+       // test
+       
//====================================================================================================
+       @Test
+       public void test() throws Exception {
+               ParserReader r = new ParserReader("abc123");
+               try {
+                       assertEquals('a', r.read());
+                       r.unread();
+                       assertEquals('a', r.read());
+                       assertEquals('b', r.read());
+                       r.unread();
+                       assertEquals("bc", r.read(2));
+                       assertEquals('1', r.read());
+                       r.unread();
+                       r.read();
+                       assertEquals('2', r.peek());
+                       assertEquals('2', r.peek());
+                       assertEquals('2', r.read());
+                       assertEquals('3', r.read());
+                       assertEquals(-1, r.read());
+                       assertEquals(-1, r.read());
+               } finally {
+                       r.close();
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoIntrospectorTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoIntrospectorTest.java
 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoIntrospectorTest.java
new file mode 100755
index 0000000..e6f3868
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoIntrospectorTest.java
@@ -0,0 +1,53 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+public class PojoIntrospectorTest {
+
+       
//====================================================================================================
+       // testBasic
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+               String in = null;
+               Object r;
+
+               r = new PojoIntrospector(in, 
null).invokeMethod("substring(int,int)", "[3,6]");
+               assertNull(r);
+
+               in = "foobar";
+               r = new PojoIntrospector(in).invokeMethod("substring(int,int)", 
"[3,6]");
+               assertEquals("bar", r);
+
+               r = new PojoIntrospector(in).invokeMethod("toString", null);
+               assertEquals("foobar", r);
+
+               r = new PojoIntrospector(in).invokeMethod("toString", "");
+               assertEquals("foobar", r);
+
+               r = new PojoIntrospector(in).invokeMethod("toString", "[]");
+               assertEquals("foobar", r);
+
+               try { new PojoIntrospector(in).invokeMethod("noSuchMethod", 
"[3,6]"); fail(); } catch (NoSuchMethodException e) {}
+
+               r = new 
PojoIntrospector(null).invokeMethod(String.class.getMethod("toString"), null);
+               assertNull(r);
+
+               r = new 
PojoIntrospector("foobar").invokeMethod(String.class.getMethod("toString"), 
null);
+               assertEquals("foobar", r);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoQueryTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
new file mode 100755
index 0000000..3c405a3
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
@@ -0,0 +1,680 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you 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.apache.juneau.utils;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transforms.*;
+import org.junit.*;
+
+@SuppressWarnings({"serial","rawtypes"})
+public class PojoQueryTest {
+
+       
//====================================================================================================
+       // filterCollection, string search, 1 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionStringSearchOneLevel() throws Exception 
{
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               List results;
+
+               List<A> in = new LinkedList<A>() {{
+                       add(new A("foo"));
+                       add(new A("bar"));
+                       add(new A("baz"));
+               }};
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'foo'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:'foo'}]", results);
+
+               query = new ObjectMap("{f:'fo*'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:'foo'}]", results);
+
+               query = new ObjectMap("{f:'*ar'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:'bar'}]", results);
+
+               query = new ObjectMap("{f:'foo bar'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:'foo'},{f:'bar'}]", results);
+       }
+
+       public class A {
+               public String f;
+
+               A() {}
+
+               A(String f) {
+                       this.f = f;
+               }
+       }
+
+       
//====================================================================================================
+       // filterCollection, date search, 1 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionDateSearchOneLevel() throws Exception {
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               WriterSerializer s = new 
JsonSerializer.Simple().addTransforms(CalendarTransform.Simple.class);
+               B[] in;
+               PojoQuery filter;
+
+               List results;
+
+               in = new B[] {
+                       new B(2010, 0, 1),
+                       new B(2011, 0, 1),
+                       new B(2011, 0, 31),
+                       new B(2012, 0, 1)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2011'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 00:00:00'},{f:'2011/01/31 
00:00:00'}]", s.serialize(results));
+
+               query = new ObjectMap("{f:'2011.01'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 00:00:00'},{f:'2011/01/31 
00:00:00'}]", s.serialize(results));
+
+               query = new ObjectMap("{f:'2011.01.01'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 00:00:00'}]", 
s.serialize(results));
+
+               in = new B[] {
+                       new B(2011, 00, 01, 11, 59, 59),
+                       new B(2011, 00, 01, 12, 00, 00),
+                       new B(2011, 00, 01, 12, 59, 59),
+                       new B(2011, 00, 01, 13, 00, 00)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2011.01.01.12'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:00:00'},{f:'2011/01/01 
12:59:59'}]", s.serialize(results));
+
+               in = new B[] {
+                       new B(2011, 00, 01, 12, 29, 59),
+                       new B(2011, 00, 01, 12, 30, 00),
+                       new B(2011, 00, 01, 12, 30, 59),
+                       new B(2011, 00, 01, 12, 31, 00)
+               };
+               filter = new PojoQuery(in, bc);
+               query = new ObjectMap("{f:'2011.01.01.12.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:30:00'},{f:'2011/01/01 
12:30:59'}]", s.serialize(results));
+
+               in = new B[] {
+                       new B(2011, 00, 01, 12, 30, 29),
+                       new B(2011, 00, 01, 12, 30, 30),
+                       new B(2011, 00, 01, 12, 30, 31)
+               };
+               filter = new PojoQuery(in, bc);
+               query = new ObjectMap("{f:'2011.01.01.12.30.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:30:30'}]", 
s.serialize(results));
+
+               // Open-ended ranges
+
+               in = new B[] {
+                       new B(2000, 11, 31),
+                       new B(2001, 00, 01)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'>2000'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2001/01/01 00:00:00'}]", 
s.serialize(results));
+
+               query = new ObjectMap("{f:'>=2001'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2001/01/01 00:00:00'}]", 
s.serialize(results));
+
+               query = new ObjectMap("{f:'<2001'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2000/12/31 00:00:00'}]", 
s.serialize(results));
+
+               query = new ObjectMap("{f:'<=2000'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2000/12/31 00:00:00'}]", 
s.serialize(results));
+
+               in = new B[] {
+                       new B(2011, 00, 01, 12, 29, 59),
+                       new B(2011, 00, 01, 12, 30, 00)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'>=2011.01.01.12.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:30:00'}]", 
s.serialize(results));
+
+               query = new ObjectMap("{f:'<2011.01.01.12.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:29:59'}]", 
s.serialize(results));
+
+               in = new B[] {
+                       new B(2011, 00, 01, 12, 30, 59),
+                       new B(2011, 00, 01, 12, 31, 00)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'>2011.01.01.12.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:31:00'}]", 
s.serialize(results));
+
+               query = new ObjectMap("{f:'<=2011.01.01.12.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2011/01/01 12:30:59'}]", 
s.serialize(results));
+
+               // Closed range
+
+               in = new B[] {
+                       new B(2000, 11, 31, 23, 59, 59),
+                       new B(2001, 00, 01, 00, 00, 00),
+                       new B(2003, 05, 30, 23, 59, 59),
+                       new B(2003, 06, 01, 00, 00, 00)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2001 - 2003.06.30'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2001/01/01 00:00:00'},{f:'2003/06/30 
23:59:59'}]", s.serialize(results));
+
+               // ORed timestamps
+
+               in = new B[] {
+                       new B(2000, 11, 31),
+                       new B(2001, 00, 01),
+                       new B(2001, 11, 31),
+                       new B(2002, 00, 01)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2001 2003 2005'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2001/01/01 00:00:00'},{f:'2001/12/31 
00:00:00'}]", s.serialize(results));
+
+               in = new B[] {
+                       new B(2002, 11, 31),
+                       new B(2003, 00, 01),
+                       new B(2003, 11, 31),
+                       new B(2004, 00, 01)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2001 2003 2005'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2003/01/01 00:00:00'},{f:'2003/12/31 
00:00:00'}]", s.serialize(results));
+
+               in = new B[] {
+                       new B(2004, 11, 31),
+                       new B(2005, 00, 01),
+                       new B(2005, 11, 31),
+                       new B(2006, 00, 01)
+               };
+               filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'2001 2003 2005'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f:'2005/01/01 00:00:00'},{f:'2005/12/31 
00:00:00'}]", s.serialize(results));
+       }
+
+       public class B {
+               public Calendar f;
+
+               B() {}
+
+               B(int year, int month, int day) {
+                       this.f = new GregorianCalendar(year, month, day);
+               }
+
+               B(int year, int month, int day, int hour, int minute, int 
second) {
+                       this.f = new GregorianCalendar(year, month, day, hour, 
minute, second);
+               }
+       }
+
+       
//====================================================================================================
+       // filterCollection, int search, 1 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionIntSearchOneLevel() throws Exception {
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               List results;
+
+               List<C> in = new LinkedList<C>() {{
+                       add(new C(1));
+                       add(new C(2));
+                       add(new C(3));
+               }};
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:'1'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:1}]", results);
+
+               query = new ObjectMap("{f:'>1'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:2},{f:3}]", results);
+
+               query = new ObjectMap("{f:'>=2'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:2},{f:3}]", results);
+
+               query = new ObjectMap("{f:'<=2'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:1},{f:2}]", results);
+
+               query = new ObjectMap("{f:'<2'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:1}]", results);
+
+               query = new ObjectMap("{f:'1 3'}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:1},{f:3}]", results);
+       }
+
+       public class C {
+               public int f;
+
+               C() {}
+
+               C(int f) {
+                       this.f = f;
+               }
+       }
+
+       
//====================================================================================================
+       // filterCollection, string search, 2 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionStringSearchTwoLevel() throws Exception 
{
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               List results;
+
+               List<D1> in = new LinkedList<D1>() {{
+                       add(new D1("foo"));
+                       add(new D1("bar"));
+                       add(new D1("baz"));
+               }};
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               query = new ObjectMap("{f:{f:'foo'}}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:{f:'foo'}}]", results);
+
+               query = new ObjectMap("{f:{f:'fo*'}}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:{f:'foo'}}]", results);
+
+               query = new ObjectMap("{f:{f:'*ar'}}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:{f:'bar'}}]", results);
+
+               query = new ObjectMap("{f:{f:'foo bar'}}");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f:{f:'foo'}},{f:{f:'bar'}}]", results);
+       }
+
+       public class D1 {
+               public D2 f;
+
+               D1() {}
+
+               D1(String f) {
+                       this.f = new D2(f);
+               }
+       }
+       public class D2 {
+               public String f;
+
+               D2() {}
+
+               D2(String f) {
+                       this.f = f;
+               }
+       }
+
+       
//====================================================================================================
+       // filterCollection, view, 1 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionViewOneLevel() throws Exception {
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               List results;
+
+               List<E> in = new LinkedList<E>() {{
+                       add(new E("foo", 1, true));
+                       add(new E("bar", 2, false));
+                       add(new E("baz", 3, true));
+               }};
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               view = new ObjectList("['f1']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f1:'foo'},{f1:'bar'},{f1:'baz'}]", 
results);
+
+               view = new ObjectList("['f2']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f2:1},{f2:2},{f2:3}]", results);
+
+               view = new ObjectList("['f3']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f3:true},{f3:false},{f3:true}]", results);
+
+               view = new ObjectList("['f3','f2','f1']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               
assertObjectEquals("[{f3:true,f2:1,f1:'foo'},{f3:false,f2:2,f1:'bar'},{f3:true,f2:3,f1:'baz'}]",
 results);
+       }
+
+       public class E {
+               public String f1;
+               public int f2;
+               public boolean f3;
+
+               E() {}
+
+               E(String f1, int f2, boolean f3) {
+                       this.f1 = f1;
+                       this.f2 = f2;
+                       this.f3 = f3;
+               }
+       }
+
+       
//====================================================================================================
+       // filterCollection, view, 2 level
+       
//====================================================================================================
+       @Test
+       public void testFilterCollectionViewTwoLevel() throws Exception {
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               List results;
+
+               List<F1> in = new LinkedList<F1>() {{
+                       add(new F1("foo"));
+                       add(new F1("bar"));
+                       add(new F1("baz"));
+               }};
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               view = new ObjectList("['f1']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertObjectEquals("[{f1:'foo'},{f1:'bar'},{f1:'baz'}]", 
results);
+
+               view = new ObjectList("[{f2:['f1']}]");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               
assertObjectEquals("[{f2:{f1:'f2_foo'}},{f2:{f1:'f2_bar'}},{f2:{f1:'f2_baz'}}]",
 results);
+
+               view = new ObjectList("['f1',{f3:['f1']}]");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               
assertObjectEquals("[{f1:'foo',f3:[{f1:'f31_foo'},{f1:'f32_foo'}]},{f1:'bar',f3:[{f1:'f31_bar'},{f1:'f32_bar'}]},{f1:'baz',f3:[{f1:'f31_baz'},{f1:'f32_baz'}]}]",
 results);
+       }
+
+       public class F1 {
+               public String f1;
+               public F2 f2;
+               public List<F2> f3;
+
+               F1() {}
+
+               F1(final String f1) {
+                       this.f1 = f1;
+                       this.f2 = new F2("f2_"+f1);
+                       this.f3 = new LinkedList<F2>() {{
+                               add(new F2("f31_"+f1));
+                               add(new F2("f32_"+f1));
+                       }};
+               }
+       }
+
+       public class F2 {
+               public String f1;
+               public String f2;
+
+               F2() {}
+
+               F2(String f1) {
+                       this.f1 = f1;
+                       this.f2 = f1;
+               }
+       }
+
+       
//====================================================================================================
+       // filterMap, 1 level
+       
//===================================================================================================
+       @Test
+       public void testFilterMapOneLevel() throws Exception {
+               ObjectList view = null;
+               BeanContext bc = BeanContext.DEFAULT;
+               Map results;
+
+               G in = new G("foo", 1, true);
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               view = new ObjectList("['f1']");
+               results = filter.filterMap(view);
+               assertObjectEquals("{f1:'foo'}", results);
+
+               view = new ObjectList("['f2']");
+               results = filter.filterMap(view);
+               assertObjectEquals("{f2:1}", results);
+
+               view = new ObjectList("['f3','f1']");
+               results = filter.filterMap(view);
+               assertObjectEquals("{f3:true,f1:'foo'}", results);
+       }
+
+       public class G {
+               public String f1;
+               public int f2;
+               public boolean f3;
+
+               G() {}
+
+               G(String f1, int f2, boolean f3) {
+                       this.f1 = f1;
+                       this.f2 = f2;
+                       this.f3 = f3;
+               }
+       }
+
+       
//====================================================================================================
+       // filterMap, 2 level
+       
//====================================================================================================
+       @Test
+       public void testFilterMapTwoLevel() throws Exception {
+               ObjectList view = null;
+               BeanContext bc = BeanContext.DEFAULT;
+               Map results;
+
+               H1 in = new H1("foo");
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               view = new ObjectList("['f1']");
+               results = filter.filterMap(view);
+               assertObjectEquals("{f1:'foo'}", results);
+
+               view = new ObjectList("[{f2:['f1']}]");
+               results = filter.filterMap(view);
+               assertObjectEquals("{f2:{f1:'f2_foo'}}", results);
+
+               view = new ObjectList("['f1',{f3:['f1']}]");
+               results = filter.filterMap(view);
+               
assertObjectEquals("{f1:'foo',f3:[{f1:'f31_foo'},{f1:'f32_foo'}]}", results);
+       }
+
+       public class H1 {
+               public String f1;
+               public H2 f2;
+               public List<H2> f3;
+
+               H1() {}
+
+               H1(final String f1) {
+                       this.f1 = f1;
+                       this.f2 = new H2("f2_"+f1);
+                       this.f3 = new LinkedList<H2>() {{
+                               add(new H2("f31_"+f1));
+                               add(new H2("f32_"+f1));
+                       }};
+               }
+       }
+
+       public class H2 {
+               public String f1;
+               public String f2;
+
+               H2() {}
+
+               H2(String f1) {
+                       this.f1 = f1;
+                       this.f2 = f1;
+               }
+       }
+
+       
//====================================================================================================
+       // testSorting
+       
//====================================================================================================
+       @Test
+       public void testSorting() throws Exception {
+               ObjectMap query = null;
+               List view = null;
+               List sort = null;
+               int pos = 0;
+               int limit = 0;
+               boolean ignoreCase = false;
+               BeanContext bc = BeanContext.DEFAULT;
+               WriterSerializer s = new 
JsonSerializer.Simple().addTransforms(CalendarTransform.Simple.class);
+               List results;
+
+               I[] in = new I[] {
+                       new I(1, "foo", true, 2010, 1, 1),
+                       new I(2, "bar", false, 2011, 1, 1),
+                       new I(3, "baz", true, 2012, 1, 1),
+               };
+
+               PojoQuery filter = new PojoQuery(in, bc);
+
+               sort = new ObjectList("['f2']");
+               view = new ObjectList("['f1','f2']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               
assertEquals("[{f1:2,f2:'bar'},{f1:3,f2:'baz'},{f1:1,f2:'foo'}]", 
s.serialize(results));
+
+               sort = new ObjectList("[{f2:'d'}]");
+               view = new ObjectList("['f1','f2']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               
assertEquals("[{f1:1,f2:'foo'},{f1:3,f2:'baz'},{f1:2,f2:'bar'}]", 
s.serialize(results));
+
+               sort = new ObjectList("['f3']");
+               view = new ObjectList("['f1','f3']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:2,f3:false},{f1:1,f3:true},{f1:3,f3:true}]", 
s.serialize(results));
+
+               sort = new ObjectList("['f3',{f1:'a'}]");
+               view = new ObjectList("['f1','f3']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:2,f3:false},{f1:1,f3:true},{f1:3,f3:true}]", 
s.serialize(results));
+
+               sort = new ObjectList("['f3',{f1:'d'}]");
+               view = new ObjectList("['f1','f3']");
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:2,f3:false},{f1:3,f3:true},{f1:1,f3:true}]", 
s.serialize(results));
+
+               sort = new ObjectList("['f1']");
+               view = new ObjectList("['f1']");
+               limit = 1;
+               pos = 0;
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:1}]", s.serialize(results));
+
+               limit = 3;
+               pos = 0;
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:1},{f1:2},{f1:3}]", s.serialize(results));
+
+               limit = 1;
+               pos = 2;
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:3}]", s.serialize(results));
+
+               limit = 100;
+               pos = 2;
+               results = filter.filterCollection(query, view, sort, pos, 
limit, ignoreCase);
+               assertEquals("[{f1:3}]", s.serialize(results));
+       }
+
+       public class I {
+               public int f1;
+               public String f2;
+               public boolean f3;
+               public Calendar f4;
+
+               I() {}
+
+               I(int f1, String f2, boolean f3, int year, int month, int day) {
+                       this.f1 = f1;
+                       this.f2 = f2;
+                       this.f3 = f3;
+                       this.f4 = new GregorianCalendar(year, month, day);
+               }
+       }
+}
\ No newline at end of file

Reply via email to