You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by am...@apache.org on 2016/02/22 23:34:58 UTC

[10/34] incubator-asterixdb git commit: Enabled Feed Tests and Added External Library tests

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/PrettyPrint.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/PrettyPrint.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/PrettyPrint.java
new file mode 100644
index 0000000..e738bb9
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/PrettyPrint.java
@@ -0,0 +1,257 @@
+/*
+ * 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.asterix.external.classad;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.asterix.external.classad.ExprTree.NodeKind;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class PrettyPrint extends ClassAdUnParser {
+    private int classadIndent;
+    private int listIndent;
+    private boolean wantStringQuotes;
+    private boolean minimalParens;
+    private int indentLevel;
+
+    public PrettyPrint() {
+        classadIndent = 4;
+        listIndent = 3;
+        wantStringQuotes = true;
+        minimalParens = false;
+        indentLevel = 0;
+    }
+
+    /// Set the indentation width for displaying lists
+    public void setListIndentation() {
+        // default is 4
+        setListIndentation(4);
+    }
+
+    public void setClassAdIndentation(int len) {
+        classadIndent = len;
+    }
+
+    public int setClassAdIndentation() {
+        return (classadIndent);
+    }
+
+    public void setListIndentation(int len) {
+        listIndent = len;
+    }
+
+    public int getListIndentation() {
+        return (listIndent);
+    }
+
+    public void setWantStringQuotes(boolean b) {
+        wantStringQuotes = b;
+    }
+
+    public boolean getWantStringQuotes() {
+        return (wantStringQuotes);
+    }
+
+    public void setMinimalParentheses(boolean b) {
+        minimalParens = b;
+    }
+
+    public boolean getMinimalParentheses() {
+        return (minimalParens);
+    }
+
+    @Override
+    public void unparseAux(AMutableCharArrayString buffer, int op, ExprTreeHolder op1, ExprTreeHolder op2,
+            ExprTreeHolder op3) throws HyracksDataException {
+        if (!minimalParens) {
+            super.unparseAux(buffer, op, op1, op2, op3);
+            return;
+        }
+
+        // case 0: parentheses op
+        if (op == Operation.OpKind_PARENTHESES_OP) {
+            unparse(buffer, op1);
+            return;
+        }
+        // case 1: check for unary ops
+        if (op == Operation.OpKind_UNARY_PLUS_OP || op == Operation.OpKind_UNARY_MINUS_OP
+                || op == Operation.OpKind_LOGICAL_NOT_OP || op == Operation.OpKind_BITWISE_NOT_OP) {
+            buffer.appendString(opString[op]);
+            unparse(buffer, op1);
+            return;
+        }
+        // case 2: check for ternary op
+        if (op == Operation.OpKind_TERNARY_OP) {
+            unparse(buffer, op1);
+            buffer.appendString(" ? ");
+            unparse(buffer, op2);
+            buffer.appendString(" : ");
+            unparse(buffer, op3);
+            return;
+        }
+        // case 3: check for subscript op
+        if (op == Operation.OpKind_SUBSCRIPT_OP) {
+            unparse(buffer, op1);
+            buffer.appendChar('[');
+            unparse(buffer, op2);
+            buffer.appendChar(']');
+            return;
+        }
+        // all others are binary ops
+        AMutableInt32 top = new AMutableInt32(0);
+        ExprTreeHolder t1 = new ExprTreeHolder(), t2 = new ExprTreeHolder(), t3 = new ExprTreeHolder();
+
+        if (op1.getKind() == NodeKind.OP_NODE) {
+            ((Operation) op1.getInnerTree()).getComponents(top, t1, t2, t3);
+            if (Operation.precedenceLevel(top.getIntegerValue().intValue()) < Operation.precedenceLevel(op)) {
+                buffer.appendString(" ( ");
+                unparseAux(buffer, top.getIntegerValue().intValue(), t1, t2, t3);
+                buffer.appendString(" ) ");
+            }
+        } else {
+            unparse(buffer, op1);
+        }
+        buffer.appendString(opString[op]);
+        if (op2.getKind() == NodeKind.OP_NODE) {
+            ((Operation) op2.getInnerTree()).getComponents(top, t1, t2, t3);
+            if (Operation.precedenceLevel(top.getIntegerValue().intValue()) < Operation.precedenceLevel(op)) {
+                buffer.appendString(" ( ");
+                unparseAux(buffer, top.getIntegerValue().intValue(), t1, t2, t3);
+                buffer.appendString(" ) ");
+            }
+        } else {
+            unparse(buffer, op2);
+        }
+    }
+
+    @Override
+    public void unparseAux(AMutableCharArrayString buffer, Map<CaseInsensitiveString, ExprTree> attrs)
+            throws HyracksDataException {
+        if (classadIndent > 0) {
+            indentLevel += classadIndent;
+            buffer.appendChar('\n');
+            int i = 0;
+            while (i < indentLevel) {
+                buffer.appendChar(' ');
+                i++;
+            }
+            buffer.appendChar('[');
+            indentLevel += classadIndent;
+        } else {
+            buffer.appendString("[ ");
+        }
+        for (Entry<CaseInsensitiveString, ExprTree> entry : attrs.entrySet()) {
+            if (classadIndent > 0) {
+                buffer.appendChar('\n');
+                int i = 0;
+                while (i < indentLevel) {
+                    buffer.appendChar(' ');
+                    i++;
+                }
+            }
+            super.unparseAux(buffer, entry.getKey().get());
+            buffer.appendString(" = ");
+            unparse(buffer, entry.getValue());
+            buffer.appendString("; ");
+        }
+        if (buffer.charAt(buffer.getLength() - 2) == ';') {
+            buffer.setLength(buffer.getLength() - 2);
+        }
+        if (classadIndent > 0) {
+            indentLevel -= classadIndent;
+            buffer.appendChar('\n');
+            int i = 0;
+            while (i < indentLevel) {
+                buffer.appendChar(' ');
+                i++;
+            }
+            buffer.appendChar(']');
+            indentLevel -= classadIndent;
+        } else {
+            buffer.appendString(" ]");
+        }
+    }
+
+    @Override
+    public void unparseAux(AMutableCharArrayString buffer, ExprList exprs) throws HyracksDataException {
+        if (listIndent > 0) {
+            indentLevel += listIndent;
+            buffer.appendChar('\n');
+            int i = 0;
+            while (i < indentLevel) {
+                buffer.appendChar(' ');
+                i++;
+            }
+            buffer.appendChar('{');
+            indentLevel += listIndent;
+        } else {
+            buffer.appendString("{ ");
+        }
+        for (ExprTree itr : exprs.getExprList()) {
+            if (listIndent > 0) {
+                int i = 0;
+                buffer.appendChar('\n');
+                while (i < indentLevel) {
+                    buffer.appendChar(' ');
+                    i++;
+                }
+            }
+            super.unparse(buffer, itr);
+            buffer.appendChar(',');;
+        }
+        if (exprs.size() > 0) {
+            buffer.decrementLength();;
+        }
+        if (listIndent > 0) {
+            indentLevel -= listIndent;
+            buffer.appendChar('\n');
+            int i = 0;
+            while (i < indentLevel) {
+                buffer.appendChar(' ');
+                i++;
+            }
+            buffer.appendChar('}');
+            indentLevel -= listIndent;
+        } else {
+            buffer.appendString(" }");
+        }
+    }
+
+    /* Checks whether string qualifies to be a non-quoted attribute */
+    public static boolean identifierNeedsQuoting(String str) {
+        boolean needs_quoting;
+        // must start with [a-zA-Z_]
+        if (!Character.isAlphabetic(str.charAt(0)) && str.charAt(0) != '_') {
+            needs_quoting = true;
+        } else {
+
+            // all other characters must be [a-zA-Z0-9_]
+            int i = 1;
+            while (i < str.length() && (Character.isLetterOrDigit(str.charAt(i)) || str.charAt(i) == '_')) {
+                i++;
+            }
+            // needs quoting if we found a special character
+            // before the end of the string.
+            needs_quoting = str.charAt(i - 1) != '\0';
+        }
+        return needs_quoting;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/StringLexerSource.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/StringLexerSource.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/StringLexerSource.java
new file mode 100644
index 0000000..d5c7589
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/StringLexerSource.java
@@ -0,0 +1,82 @@
+/*
+ * 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.asterix.external.classad;
+
+public class StringLexerSource extends LexerSource {
+    private String aString;
+    private int offset;
+
+    public StringLexerSource(String aString, int offset) {
+        setNewSource(aString, offset);
+    }
+
+    public StringLexerSource(String aString) {
+        setNewSource(aString, 0);
+    }
+
+    @Override
+    public int getPosition() {
+        return offset;
+    }
+
+    public void setNewSource(String aString, int offset) {
+        this.aString = aString;
+        this.offset = offset;
+    }
+
+    @Override
+    public char readCharacter() {
+        if (offset == aString.length()) {
+            previousCharacter = Lexer.EOF;
+            return previousCharacter;
+        } else {
+            previousCharacter = aString.charAt(offset);
+            offset++;
+            return previousCharacter;
+        }
+    }
+
+    @Override
+    public void unreadCharacter() {
+        if (offset > 0) {
+            if (previousCharacter != Lexer.EOF) {
+                offset--;
+            }
+        }
+    }
+
+    @Override
+    public boolean atEnd() {
+        return offset == aString.length();
+    }
+
+    public int getCurrentLocation() {
+        return offset;
+    }
+
+    public void setNewSource(String buffer) {
+        setNewSource(buffer, 0);
+    }
+
+    @Override
+    public char[] getBuffer() {
+        return aString.toCharArray();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/TokenValue.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/TokenValue.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/TokenValue.java
new file mode 100644
index 0000000..af86d9b
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/TokenValue.java
@@ -0,0 +1,157 @@
+/*
+ * 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.asterix.external.classad;
+
+import org.apache.asterix.external.classad.Lexer.TokenType;
+import org.apache.asterix.external.classad.Value.NumberFactor;
+import org.apache.asterix.om.base.AMutableDouble;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.commons.lang3.mutable.MutableBoolean;
+
+public class TokenValue {
+    private TokenType tt;
+    private NumberFactor factor;
+    private long intValue;
+    private double realValue;
+    private boolean boolValue;
+    private AMutableCharArrayString strValue;
+    private ClassAdTime time;
+
+    public TokenValue() {
+        tt = TokenType.LEX_TOKEN_ERROR;
+        factor = NumberFactor.NO_FACTOR;
+        intValue = 0;
+        realValue = 0.0;
+        boolValue = false;
+        strValue = new AMutableCharArrayString();
+        time = new ClassAdTime();
+    }
+
+    public void setTokenType(TokenType t) {
+        tt = t;
+    }
+
+    public void setIntValue(long i, NumberFactor f) {
+        intValue = i;
+        factor = f;
+    }
+
+    public void setRealValue(double r, NumberFactor f) {
+        realValue = r;
+        factor = f;
+    }
+
+    public void setBoolValue(boolean b) {
+        boolValue = b;
+    }
+
+    public void setStringValue(char[] str) {
+        strValue.copyValue(str, str.length);
+    }
+
+    public void setStringValue(char[] str, int length) {
+        strValue.copyValue(str, length);
+    }
+
+    public void setStringValue(AMutableCharArrayString aString) {
+        strValue.setValue(aString);
+    }
+
+    public void setAbsTimeValue(ClassAdTime asecs) {
+        time.setValue(asecs);
+    }
+
+    public void setRelTimeValue(double rsecs) {
+        time.setValue((long) rsecs);
+    }
+
+    public TokenType getTokenType() {
+        return tt;
+    }
+
+    public void getIntValue(AMutableInt64 i, AMutableNumberFactor f) {
+        i.setValue(intValue);
+        f.setFactor(factor);
+    }
+
+    public void getRealValue(AMutableDouble r, AMutableNumberFactor f) {
+        r.setValue(realValue);
+        f.setFactor(factor);
+    }
+
+    public void getBoolValue(MutableBoolean b) {
+        b.setValue(boolValue);
+    }
+
+    void getStringValue(AMutableCharArrayString str) {
+        str.copyValue(strValue.getValue(), strValue.getLength());
+    }
+
+    void getAbsTimeValue(ClassAdTime asecs) {
+        asecs.setValue(time);
+    }
+
+    void getRelTimeValue(ClassAdTime rsecs) {
+        rsecs.setValue(time.getRelativeTime());
+    }
+
+    void copyFrom(TokenValue tv) {
+        tt = tv.tt;
+        factor = tv.factor;
+        intValue = tv.intValue;
+        realValue = tv.realValue;
+        boolValue = tv.boolValue;
+        time.setValue(tv.time);
+        strValue.setValue(tv.strValue);
+    }
+
+    public void reset() {
+        tt = TokenType.LEX_TOKEN_ERROR;
+        factor = NumberFactor.NO_FACTOR;
+        intValue = 0;
+        realValue = 0.0;
+        boolValue = false;
+        strValue.reset();
+        time.reset();
+    }
+
+    public NumberFactor getFactor() {
+        return factor;
+    }
+
+    public long getIntValue() {
+        return intValue;
+    }
+
+    public double getRealValue() {
+        return realValue;
+    }
+
+    public boolean getBoolValue() {
+        return boolValue;
+    }
+
+    public AMutableCharArrayString getStrValue() {
+        return strValue;
+    }
+
+    public ClassAdTime getTimeValue() {
+        return time;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Util.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Util.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Util.java
new file mode 100644
index 0000000..cbecb1b
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Util.java
@@ -0,0 +1,262 @@
+/*
+ * 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.asterix.external.classad;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Random;
+import java.util.TimeZone;
+
+import org.apache.asterix.om.base.AMutableInt32;
+
+public class Util {
+    // convert escapes in-place
+    // the string can only shrink while converting escapes so we can safely convert in-place.
+    // needs verification
+    public static boolean convertEscapes(AMutableCharArrayString text) {
+        boolean validStr = true;
+        if (text.getLength() == 0)
+            return true;
+        int length = text.getLength();
+        int dest = 0;
+        for (int source = 0; source < length; ++source) {
+            char ch = text.charAt(source);
+            // scan for escapes, a terminating slash cannot be an escape
+            if (ch == '\\' && source < length - 1) {
+                ++source; // skip the \ character
+                ch = text.charAt(source);
+
+                // The escape part should be re-validated
+                switch (ch) {
+                    case 'b':
+                        ch = '\b';
+                        break;
+                    case 'f':
+                        ch = '\f';
+                        break;
+                    case 'n':
+                        ch = '\n';
+                        break;
+                    case 'r':
+                        ch = '\r';
+                        break;
+                    case 't':
+                        ch = '\t';
+                        break;
+                    case '\\':
+                        ch = '\\';
+                        break;
+                    default:
+                        if (Lexer.isodigit(ch)) {
+                            int number = ch - '0';
+                            // There can be up to 3 octal digits in an octal escape
+                            //  \[0..3]nn or \nn or \n. We quit at 3 characters or
+                            // at the first non-octal character.
+                            if (source + 1 < length) {
+                                char digit = text.charAt(source + 1); // is the next digit also
+                                if (Lexer.isodigit(digit)) {
+                                    ++source;
+                                    number = (number << 3) + digit - '0';
+                                    if (number < 0x20 && source + 1 < length) {
+                                        digit = text.charAt(source + 1);
+                                        if (Lexer.isodigit(digit)) {
+                                            ++source;
+                                            number = (number << 3) + digit - '0';
+                                        }
+                                    }
+                                }
+                            }
+                            if (ch == 0) { // "\\0" is an invalid substring within a string literal
+                                validStr = false;
+                            }
+                        } else {
+                            // pass char after \ unmodified.
+                        }
+                        break;
+                }
+            }
+
+            if (dest == source) {
+                // no need to assign ch to text when we haven't seen any escapes yet.
+                // text[dest] = ch;
+                ++dest;
+            } else {
+                text.erase(dest);
+                text.setChar(dest, ch);
+                ++dest;
+                --source;
+            }
+        }
+
+        if (dest < length) {
+            text.erase(dest);
+            length = dest;
+        }
+        // silly, but to fulfull the original contract for this function
+        // we need to remove the last character in the string if it is a '\0'
+        // (earlier logic guaranteed that a '\0' can ONLY be the last character)
+        if (length > 0 && !(text.charAt(length - 1) == '\0')) {
+            //text.erase(length - 1);
+        }
+        return validStr;
+    }
+
+    /***************************************************************
+     * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
+     * University of Wisconsin-Madison, WI.
+     * Licensed under the Apache License, Version 2.0 (the "License"); you
+     * may not use this file except in compliance with the License. You may
+     * obtain a copy of the License at
+     * http://www.apache.org/licenses/LICENSE-2.0
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     * See the License for the specific language governing permissions and
+     * limitations under the License.
+     ***************************************************************/
+
+    public static Random initialized = new Random((new Date()).getTime());
+
+    public static int getRandomInteger() {
+        return initialized.nextInt();
+    }
+
+    public static double getRandomReal() {
+        return initialized.nextDouble();
+    }
+
+    public static int timezoneOffset(ClassAdTime clock) {
+        return clock.getOffset();
+    }
+
+    public static void getLocalTime(ClassAdTime now, ClassAdTime localtm) {
+        localtm.setValue(Calendar.getInstance(), now);
+        localtm.isAbsolute(true);
+    }
+
+    public static void absTimeToString(ClassAdTime atime, AMutableCharArrayString buffer) {
+        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        //"yyyy-MM-dd'T'HH:mm:ss"
+        //2004-01-01T00:00:00+11:00
+        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
+        buffer.appendString(formatter.format(atime.getCalendar().getTime()));
+        buffer.appendString(
+                (atime.getOffset() >= 0 ? "+" : "-") + String.format("%02d", (Math.abs(atime.getOffset()) / 3600000))
+                        + ":" + String.format("%02d", ((Math.abs(atime.getOffset() / 60) % 60))));
+    }
+
+    public static void relTimeToString(long rsecs, AMutableCharArrayString buffer) {
+        double fractional_seconds;
+        int days, hrs, mins;
+        double secs;
+
+        if (rsecs < 0) {
+            buffer.appendChar('-');
+            rsecs = -rsecs;
+        }
+        fractional_seconds = rsecs % 1000;
+
+        days = (int) (rsecs / 1000);
+        hrs = days % 86400;
+        mins = hrs % 3600;
+        secs = (mins % 60) + (fractional_seconds / 1000.0);
+        days = days / 86400;
+        hrs = hrs / 3600;
+        mins = mins / 60;
+
+        if (days != 0) {
+            if (fractional_seconds == 0) {
+                buffer.appendString(String.format("%d+%02d:%02d:%02d", days, hrs, mins, (int) secs));
+            } else {
+                buffer.appendString(String.format("%d+%02d:%02d:%g", days, hrs, mins, secs));
+            }
+        } else if (hrs != 0) {
+            if (fractional_seconds == 0) {
+                buffer.appendString(String.format("%02d:%02d:%02d", hrs, mins, (int) secs));
+            } else {
+                buffer.appendString(String.format("%02d:%02d:%02g", hrs, mins, secs));
+            }
+        } else if (mins != 0) {
+            if (fractional_seconds == 0) {
+                buffer.appendString(String.format("%02d:%02d", mins, (int) secs));
+            } else {
+                buffer.appendString(String.format("%02d:%02g", mins, secs));
+            }
+            return;
+        } else {
+            if (fractional_seconds == 0) {
+                buffer.appendString(String.format("%02d", (int) secs));
+            } else {
+                buffer.appendString(String.format("%02g", secs));
+            }
+        }
+    }
+
+    public static void dayNumbers(int year, int month, int day, AMutableInt32 weekday, AMutableInt32 yearday) {
+        int fixed = fixedFromGregorian(year, month, day);
+        int jan1_fixed = fixedFromGregorian(year, 1, 1);
+        weekday.setValue(fixed % 7);
+        yearday.setValue(fixed - jan1_fixed);
+        return;
+    }
+
+    public static int fixedFromGregorian(int year, int month, int day) {
+        int fixed;
+        int month_adjustment;
+        if (month <= 2) {
+            month_adjustment = 0;
+        } else if (isLeapYear(year)) {
+            month_adjustment = -1;
+        } else {
+            month_adjustment = -2;
+        }
+        fixed = 365 * (year - 1) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400)
+                + ((367 * month - 362) / 12) + month_adjustment + day;
+        return fixed;
+    }
+
+    public static boolean isLeapYear(int year) {
+        int mod4;
+        int mod400;
+        boolean leap_year;
+
+        mod4 = year % 4;
+        mod400 = year % 400;
+
+        if (mod4 == 0 && mod400 != 100 && mod400 != 200 && mod400 != 300) {
+            leap_year = true;
+        } else {
+            leap_year = false;
+        }
+        return leap_year;
+    }
+
+    public static int isInf(double x) {
+        if (Double.isInfinite(x)) {
+            return (x < 0.0) ? (-1) : 1;
+        }
+        return 0;
+    }
+
+    public static boolean isNan(double x) {
+        return Double.isNaN(x);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Value.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Value.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Value.java
new file mode 100644
index 0000000..f0466b2
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/Value.java
@@ -0,0 +1,871 @@
+/*
+ * 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.asterix.external.classad;
+
+import org.apache.asterix.om.base.AMutableDouble;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class Value {
+
+    private ValueType valueType;
+    private long longVal;
+    private double doubleVal;
+    private boolean boolVal;
+    private ClassAdTime timeVal = new ClassAdTime();
+    private ClassAd classadVal = new ClassAd();
+    private ExprList listVal = new ExprList();
+    private String stringVal;
+
+    /// Value types
+    public enum ValueType {
+        NULL_VALUE,
+        /** The error value */
+        ERROR_VALUE,
+        /** The undefined value */
+        UNDEFINED_VALUE,
+        /** A boolean value (false, true) */
+        BOOLEAN_VALUE,
+        /** An integer value */
+        INTEGER_VALUE,
+        /** A real value */
+        REAL_VALUE,
+        /** A relative time value */
+        RELATIVE_TIME_VALUE,
+        /** An absolute time value */
+        ABSOLUTE_TIME_VALUE,
+        /** A string value */
+        STRING_VALUE,
+        /** A classad value */
+        CLASSAD_VALUE,
+        /** A list value (not owned here) */
+        LIST_VALUE,
+        /** A list value (owned via shared_ptr) */
+        SLIST_VALUE
+    };
+
+    /// Number factors
+    public enum NumberFactor {
+        /** No factor specified */
+        NO_FACTOR,
+        /** Byte factor */
+        B_FACTOR,
+        /** Kilo factor */
+        K_FACTOR,
+        /** Mega factor */
+        M_FACTOR,
+        /** Giga factor */
+        G_FACTOR,
+        /** Terra factor */
+        T_FACTOR
+    };
+
+    public ValueType getType() {
+        return valueType;
+    }
+
+    public boolean isBooleanValue(MutableBoolean b) {
+        if (valueType == ValueType.BOOLEAN_VALUE) {
+            b.setValue(boolVal);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isBooleanValue() {
+        return (valueType == ValueType.BOOLEAN_VALUE);
+    }
+
+    public boolean isIntegerValue(AMutableInt64 i) {
+        if (valueType == ValueType.INTEGER_VALUE) {
+            i.setValue(longVal);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isIntegerValue() {
+        return (valueType == ValueType.INTEGER_VALUE);
+    }
+
+    public boolean isRealValue(AMutableDouble r) {
+
+        if (valueType == ValueType.REAL_VALUE) {
+            r.setValue(doubleVal);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isRealValue() {
+        return (valueType == ValueType.REAL_VALUE);
+    }
+
+    public boolean isListValue(ExprList el) {
+        if (valueType == ValueType.LIST_VALUE || valueType == ValueType.SLIST_VALUE) {
+            el.getExprList().addAll(listVal.getExprList());
+            el.isShared = listVal.isShared;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isListValue() {
+        return (valueType == ValueType.LIST_VALUE || valueType == ValueType.SLIST_VALUE);
+    }
+
+    public boolean isStringValue() {
+        return (valueType == ValueType.STRING_VALUE);
+    }
+
+    public boolean isStringValue(AMutableCharArrayString s) {
+        if (valueType == ValueType.STRING_VALUE) {
+            s.setValue(stringVal);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isStringValue(AMutableCharArrayString s, int len) {
+        if (valueType == ValueType.STRING_VALUE) {
+            s.setValue(stringVal, len);
+            return (true);
+        }
+        return (false);
+    }
+
+    public boolean isStringValue(AMutableInt32 size) {
+        if (valueType == ValueType.STRING_VALUE) {
+            size.setValue(stringVal.length());
+            return true;
+        } else {
+            size.setValue(-1);
+            return false;
+        }
+    }
+
+    public boolean isClassAdValue(ClassAd ad) {
+        if (valueType == ValueType.CLASSAD_VALUE) {
+            ad.setValue(classadVal);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isClassAdValue() {
+        return (valueType == ValueType.CLASSAD_VALUE);
+    }
+
+    public boolean isUndefinedValue() {
+        return (valueType == ValueType.UNDEFINED_VALUE);
+    }
+
+    public boolean isErrorValue() {
+        return (valueType == ValueType.ERROR_VALUE);
+    }
+
+    public boolean isExceptional() {
+        return (valueType == ValueType.UNDEFINED_VALUE || valueType == ValueType.ERROR_VALUE);
+    }
+
+    public boolean isAbsoluteTimeValue() {
+        return (valueType == ValueType.ABSOLUTE_TIME_VALUE);
+    }
+
+    public boolean isAbsoluteTimeValue(ClassAdTime secs) {
+        if (valueType == ValueType.ABSOLUTE_TIME_VALUE) {
+            secs.setValue(timeVal);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isRelativeTimeValue() {
+        return (valueType == ValueType.RELATIVE_TIME_VALUE);
+    }
+
+    public boolean isRelativeTimeValue(ClassAdTime secs) {
+
+        if (valueType == ValueType.RELATIVE_TIME_VALUE) {
+            secs.setValue(timeVal);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isNumber() {
+        return (valueType == ValueType.INTEGER_VALUE || valueType == ValueType.REAL_VALUE);
+    }
+
+    public boolean isNumber(AMutableInt64 i) {
+        switch (valueType) {
+            case INTEGER_VALUE:
+                i.setValue(longVal);
+                return true;
+
+            case REAL_VALUE:
+                i.setValue((long) doubleVal);
+                return true;
+
+            case BOOLEAN_VALUE:
+                i.setValue(boolVal ? 1L : 0L);
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public boolean isNumber(AMutableDouble r) {
+        switch (valueType) {
+            case INTEGER_VALUE:
+                r.setValue(longVal);
+                return true;
+
+            case REAL_VALUE:
+                r.setValue(doubleVal);
+                return true;
+
+            case BOOLEAN_VALUE:
+                r.setValue(boolVal ? 1.0 : 0.0);
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    // Implementation
+    public static final double[] ScaleFactor = { 1.0, // none
+            1.0, // B
+            1024.0, // Kilo
+            1024.0 * 1024.0, // Mega
+            1024.0 * 1024.0 * 1024.0, // Giga
+            1024.0 * 1024.0 * 1024.0 * 1024.0 // Terra
+    };
+
+    public Value() {
+        valueType = ValueType.UNDEFINED_VALUE;
+    }
+
+    public Value(Value value) throws HyracksDataException {
+        valueType = value.valueType;
+        switch (value.valueType) {
+            case ABSOLUTE_TIME_VALUE:
+                timeVal = new ClassAdTime(value.timeVal);
+                break;
+            case BOOLEAN_VALUE:
+                this.boolVal = value.boolVal;
+                break;
+            case CLASSAD_VALUE:
+                this.classadVal = new ClassAd(value.classadVal);
+                break;
+            case ERROR_VALUE:
+                break;
+            case INTEGER_VALUE:
+                this.longVal = value.longVal;
+                break;
+            case LIST_VALUE:
+                this.listVal = new ExprList(value.listVal);
+                break;
+            case NULL_VALUE:
+                break;
+            case REAL_VALUE:
+                this.doubleVal = value.doubleVal;
+                break;
+            case RELATIVE_TIME_VALUE:
+                this.timeVal = new ClassAdTime(value.timeVal);
+                break;
+            case SLIST_VALUE:
+                this.listVal = new ExprList(value.listVal);
+                break;
+            case STRING_VALUE:
+                this.stringVal = value.stringVal;
+                break;
+            case UNDEFINED_VALUE:
+                break;
+            default:
+                break;
+        }
+    }
+
+    public void setValue(Value value) throws HyracksDataException {
+        valueType = value.valueType;
+        switch (value.valueType) {
+            case ABSOLUTE_TIME_VALUE:
+                this.timeVal.setValue(value.timeVal);
+                break;
+            case BOOLEAN_VALUE:
+                this.boolVal = value.boolVal;
+                break;
+            case CLASSAD_VALUE:
+                this.classadVal.setValue(value.classadVal);
+                break;
+            case ERROR_VALUE:
+                break;
+            case INTEGER_VALUE:
+                this.longVal = value.longVal;
+                break;
+            case LIST_VALUE:
+                this.listVal.setValue(value.listVal);
+                break;
+            case NULL_VALUE:
+                break;
+            case REAL_VALUE:
+                this.doubleVal = value.doubleVal;
+                break;
+            case RELATIVE_TIME_VALUE:
+                this.timeVal.setValue((value.timeVal));
+                break;
+            case SLIST_VALUE:
+                listVal.setValue(value.listVal);
+                break;
+            case STRING_VALUE:
+                stringVal = value.stringVal;
+                break;
+            case UNDEFINED_VALUE:
+                break;
+            default:
+                break;
+        }
+    }
+
+    public void assign(Value value) throws HyracksDataException {
+        if (this != value) {
+            setValue(value);
+        }
+    }
+
+    public void clear() {
+        valueType = ValueType.UNDEFINED_VALUE;
+    }
+
+    public void setRealValue(double r) {
+        valueType = ValueType.REAL_VALUE;
+        doubleVal = r;
+    }
+
+    public void setRealValue(AMutableDouble r) {
+        valueType = ValueType.REAL_VALUE;
+        doubleVal = r.getDoubleValue();
+    }
+
+    public void setBooleanValue(boolean b) {
+        valueType = ValueType.BOOLEAN_VALUE;
+        boolVal = b;
+    }
+
+    public void setBooleanValue(MutableBoolean b) {
+        valueType = ValueType.BOOLEAN_VALUE;
+        boolVal = b.booleanValue();
+    }
+
+    public void setIntegerValue(long i) {
+        valueType = ValueType.INTEGER_VALUE;
+        longVal = i;
+    }
+
+    public void setUndefinedValue() {
+        valueType = ValueType.UNDEFINED_VALUE;
+    }
+
+    public void setErrorValue() {
+        valueType = ValueType.ERROR_VALUE;
+    }
+
+    public void setStringValue(AMutableCharArrayString s) {
+        valueType = ValueType.STRING_VALUE;
+        stringVal = s.toString();
+    }
+
+    public void setStringValue(String s) {
+        valueType = ValueType.STRING_VALUE;
+        stringVal = s;
+    }
+
+    public void setListValue(ExprList expList) throws HyracksDataException {
+        valueType = expList.isShared ? ValueType.SLIST_VALUE : ValueType.LIST_VALUE;
+        listVal.setValue(expList);
+    }
+
+    public void setClassAdValue(ClassAd ad) {
+        clear();
+        valueType = ValueType.CLASSAD_VALUE;
+        classadVal.setValue(ad);
+    }
+
+    public void setRelativeTimeValue(ClassAdTime rsecs) {
+        clear();
+        valueType = ValueType.RELATIVE_TIME_VALUE;
+        timeVal.setValue(rsecs);
+    }
+
+    public void setRelativeTimeValue(long rsecs) {
+        clear();
+        valueType = ValueType.RELATIVE_TIME_VALUE;
+        timeVal.setValue(rsecs);
+        timeVal.isAbsolute(false);
+    }
+
+    public void setAbsoluteTimeValue(ClassAdTime tim) {
+        clear();
+        valueType = ValueType.ABSOLUTE_TIME_VALUE;
+        timeVal.setValue(tim);
+    }
+
+    public boolean sameAs(Value otherValue) {
+        boolean is_same = false;
+        if (valueType != otherValue.valueType) {
+            is_same = false;
+        } else {
+            switch (valueType) {
+                case NULL_VALUE:
+                case ERROR_VALUE:
+                case UNDEFINED_VALUE:
+                    is_same = true;
+                    break;
+                case BOOLEAN_VALUE:
+                    is_same = (boolVal == otherValue.boolVal);
+                    break;
+                case INTEGER_VALUE:
+                    is_same = (longVal == otherValue.longVal);
+                    break;
+                case REAL_VALUE:
+                    is_same = (doubleVal == otherValue.doubleVal);
+                    break;
+                case LIST_VALUE:
+                case SLIST_VALUE:
+                    is_same = listVal.equals(otherValue.listVal);
+                    break;
+                case CLASSAD_VALUE:
+                    is_same = classadVal.equals(otherValue.classadVal);
+                    break;
+                case RELATIVE_TIME_VALUE:
+                case ABSOLUTE_TIME_VALUE:
+                    is_same = timeVal.equals(otherValue.timeVal);
+                    break;
+                case STRING_VALUE:
+                    is_same = stringVal.equals(otherValue.stringVal);
+                    break;
+            }
+        }
+        return is_same;
+    }
+
+    public boolean equals(Value value) {
+        return sameAs(value);
+    }
+
+    public boolean isBooleanValueEquiv(MutableBoolean b) {
+        return isBooleanValue(b);
+    }
+
+    @Override
+    public String toString() {
+        ClassAdUnParser unparser = new PrettyPrint();
+        AMutableCharArrayString unparsed_text = new AMutableCharArrayString();
+        switch (valueType) {
+            case ABSOLUTE_TIME_VALUE:
+            case CLASSAD_VALUE:
+            case RELATIVE_TIME_VALUE:
+            case SLIST_VALUE:
+            case LIST_VALUE:
+                try {
+                    unparser.unparse(unparsed_text, this);
+                } catch (HyracksDataException e) {
+                    e.printStackTrace();
+                }
+                return unparsed_text.toString();
+            case BOOLEAN_VALUE:
+                if (boolVal) {
+                    return "true";
+                } else {
+                    return "false";
+                }
+            case ERROR_VALUE:
+                return "error";
+            case INTEGER_VALUE:
+                return String.valueOf(longVal);
+            case NULL_VALUE:
+                return "(null)";
+            case REAL_VALUE:
+                return String.valueOf(doubleVal);
+            case STRING_VALUE:
+                return stringVal;
+            case UNDEFINED_VALUE:
+                return "undefined";
+            default:
+                break;
+        }
+        return null;
+    }
+
+    public static boolean convertValueToRealValue(Value value, Value realValue) throws HyracksDataException {
+        boolean could_convert;
+        AMutableCharArrayString buf = new AMutableCharArrayString();
+        int endIndex;
+        char end;
+        AMutableInt64 ivalue = new AMutableInt64(0);
+        ClassAdTime atvalue = new ClassAdTime();
+        MutableBoolean bvalue = new MutableBoolean();
+        double rvalue;
+        NumberFactor nf = NumberFactor.NO_FACTOR;
+
+        switch (value.getType()) {
+            case UNDEFINED_VALUE:
+                realValue.setUndefinedValue();
+                could_convert = false;
+                break;
+
+            case ERROR_VALUE:
+            case CLASSAD_VALUE:
+            case LIST_VALUE:
+            case SLIST_VALUE:
+                realValue.setErrorValue();
+                could_convert = false;
+                break;
+
+            case STRING_VALUE:
+                could_convert = true;
+                value.isStringValue(buf);
+                endIndex = buf.fistNonDoubleDigitChar();
+                if (endIndex < 0) {
+                    // no non digit
+                    String buffString = buf.toString();
+                    if (buffString.contains("INF")) {
+                        buffString = buffString.replace("INF", "Infinity");
+                    }
+                    rvalue = Double.parseDouble(buffString);
+                    nf = NumberFactor.NO_FACTOR;
+                } else {
+                    rvalue = Double.parseDouble(buf.substr(0, endIndex));
+                    end = buf.charAt(endIndex);
+                    switch (Character.toUpperCase(end)) {
+                        case 'B':
+                            nf = NumberFactor.B_FACTOR;
+                            break;
+                        case 'K':
+                            nf = NumberFactor.K_FACTOR;
+                            break;
+                        case 'M':
+                            nf = NumberFactor.M_FACTOR;
+                            break;
+                        case 'G':
+                            nf = NumberFactor.G_FACTOR;
+                            break;
+                        case 'T':
+                            nf = NumberFactor.T_FACTOR;
+                            break;
+                        case '\0':
+                            nf = NumberFactor.NO_FACTOR;
+                            break;
+                        default:
+                            nf = NumberFactor.NO_FACTOR;
+                            break;
+                    }
+                }
+
+                if (could_convert) {
+                    realValue.setRealValue(rvalue * Value.ScaleFactor[nf.ordinal()]);
+                }
+                break;
+
+            case BOOLEAN_VALUE:
+                value.isBooleanValue(bvalue);
+                realValue.setRealValue(bvalue.booleanValue() ? 1.0 : 0.0);
+                could_convert = true;
+                break;
+
+            case INTEGER_VALUE:
+                value.isIntegerValue(ivalue);
+                realValue.setRealValue(ivalue.getLongValue());
+                could_convert = true;
+                break;
+
+            case REAL_VALUE:
+                realValue.copyFrom(value);
+                could_convert = true;
+                break;
+
+            case ABSOLUTE_TIME_VALUE:
+                value.isAbsoluteTimeValue(atvalue);
+                realValue.setRealValue(atvalue.getTimeInMillis() / 1000.0);
+                could_convert = true;
+                break;
+
+            case RELATIVE_TIME_VALUE:
+                value.isRelativeTimeValue(atvalue);
+                realValue.setRealValue(atvalue.getRelativeTime() / 1000.0);
+                could_convert = true;
+                break;
+
+            default:
+                could_convert = false; // Make gcc's -Wuninitalized happy
+                throw new HyracksDataException("Should not reach here");
+        }
+        return could_convert;
+    }
+
+    public static boolean convertValueToIntegerValue(Value value, Value integerValue) throws HyracksDataException {
+        boolean could_convert;
+        AMutableCharArrayString buf = new AMutableCharArrayString();
+        char end;
+        AMutableInt64 ivalue = new AMutableInt64(0);
+        AMutableDouble rtvalue = new AMutableDouble(0);
+        ClassAdTime atvalue = new ClassAdTime();
+        MutableBoolean bvalue = new MutableBoolean();
+        NumberFactor nf;
+
+        switch (value.getType()) {
+            case UNDEFINED_VALUE:
+                integerValue.setUndefinedValue();
+                could_convert = false;
+                break;
+
+            case ERROR_VALUE:
+            case CLASSAD_VALUE:
+            case LIST_VALUE:
+            case SLIST_VALUE:
+                integerValue.setErrorValue();
+                could_convert = false;
+                break;
+
+            case STRING_VALUE:
+                could_convert = true;
+                value.isStringValue(buf);
+                int endIndex = buf.firstNonDigitChar();
+                if (endIndex < 0) {
+                    // no non digit
+                    ivalue.setValue(Long.parseLong(buf.toString()));
+                    nf = NumberFactor.NO_FACTOR;
+                    break;
+                } else {
+                    ivalue.setValue(Long.parseLong(buf.substr(0, endIndex)));
+                    end = buf.charAt(endIndex);
+                    switch (Character.toUpperCase(end)) {
+                        case 'B':
+                            nf = NumberFactor.B_FACTOR;
+                            break;
+                        case 'K':
+                            nf = NumberFactor.K_FACTOR;
+                            break;
+                        case 'M':
+                            nf = NumberFactor.M_FACTOR;
+                            break;
+                        case 'G':
+                            nf = NumberFactor.G_FACTOR;
+                            break;
+                        case 'T':
+                            nf = NumberFactor.T_FACTOR;
+                            break;
+                        case '\0':
+                            nf = NumberFactor.NO_FACTOR;
+                            break;
+                        default:
+                            nf = NumberFactor.NO_FACTOR;
+                            break;
+                    }
+                    if (could_convert) {
+                        integerValue
+                                .setIntegerValue((long) ((ivalue.getLongValue() * Value.ScaleFactor[nf.ordinal()])));
+                    }
+                }
+                break;
+
+            case BOOLEAN_VALUE:
+                value.isBooleanValue(bvalue);
+                integerValue.setIntegerValue(bvalue.booleanValue() ? 1 : 0);
+                could_convert = true;
+                break;
+
+            case INTEGER_VALUE:
+                integerValue.copyFrom(value);
+                could_convert = true;
+                break;
+
+            case REAL_VALUE:
+                value.isRealValue(rtvalue);
+                integerValue.setIntegerValue((long) rtvalue.getDoubleValue());
+                could_convert = true;
+                break;
+
+            case ABSOLUTE_TIME_VALUE:
+                value.isAbsoluteTimeValue(atvalue);
+                integerValue.setIntegerValue(atvalue.getTimeInMillis() / 1000L);
+                could_convert = true;
+                break;
+            case RELATIVE_TIME_VALUE:
+
+                value.isRelativeTimeValue(atvalue);
+                integerValue.setIntegerValue((atvalue.getTime() / 1000L));
+                could_convert = true;
+                break;
+
+            default:
+                could_convert = false; // Make gcc's -Wuninitalized happy
+                throw new HyracksDataException("Should not reach here");
+        }
+        return could_convert;
+    }
+
+    public void copyFrom(Value val) throws HyracksDataException {
+        clear();
+        valueType = val.valueType;
+        switch (val.valueType) {
+            case STRING_VALUE:
+                stringVal = val.stringVal;
+                return;
+
+            case BOOLEAN_VALUE:
+                boolVal = val.boolVal;
+                return;
+
+            case INTEGER_VALUE:
+                longVal = val.longVal;
+                return;
+
+            case REAL_VALUE:
+
+                doubleVal = val.doubleVal;
+                return;
+            case UNDEFINED_VALUE:
+            case ERROR_VALUE:
+                return;
+            case LIST_VALUE:
+            case SLIST_VALUE:
+                listVal.copyFrom(val.listVal);
+                return;
+            case CLASSAD_VALUE:
+                classadVal.copyFrom(val.classadVal);
+                return;
+
+            case RELATIVE_TIME_VALUE:
+            case ABSOLUTE_TIME_VALUE:
+                timeVal.setValue(val.timeVal);
+                return;
+            default:
+                setUndefinedValue();
+        }
+    }
+
+    public static boolean convertValueToStringValue(Value value, Value stringValue) throws HyracksDataException {
+        boolean could_convert = false;
+        ClassAdTime atvalue = new ClassAdTime();
+        AMutableCharArrayString string_representation = new AMutableCharArrayString();
+        ClassAdUnParser unparser = new PrettyPrint();
+
+        switch (value.getType()) {
+            case UNDEFINED_VALUE:
+                stringValue.setUndefinedValue();
+                could_convert = false;
+                break;
+
+            case ERROR_VALUE:
+                stringValue.setErrorValue();
+                could_convert = false;
+                break;
+
+            case STRING_VALUE:
+                stringValue.copyFrom(value);
+                could_convert = true;
+                break;
+
+            case CLASSAD_VALUE:
+            case LIST_VALUE:
+            case SLIST_VALUE:
+            case BOOLEAN_VALUE:
+            case INTEGER_VALUE:
+            case REAL_VALUE:
+                unparser.unparse(string_representation, value);
+                stringValue.setStringValue(string_representation);
+                could_convert = true;
+                break;
+
+            case ABSOLUTE_TIME_VALUE:
+                value.isAbsoluteTimeValue(atvalue);
+                Util.absTimeToString(atvalue, string_representation);
+                stringValue.setStringValue(string_representation);
+                could_convert = true;
+                break;
+
+            case RELATIVE_TIME_VALUE:
+                value.isRelativeTimeValue(atvalue);
+                Util.relTimeToString(atvalue.getTimeInMillis(), string_representation);
+                stringValue.setStringValue(string_representation);
+                could_convert = true;
+                break;
+
+            default:
+                could_convert = false; // Make gcc's -Wuninitalized happy
+                throw new HyracksDataException("Should not reach here");
+        }
+        return could_convert;
+    }
+
+    public boolean isSListValue(ExprList l) throws HyracksDataException {
+        if (valueType == ValueType.SLIST_VALUE || valueType == ValueType.LIST_VALUE) {
+            l.setValue(listVal);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public ValueType getValueType() {
+        return valueType;
+    }
+
+    public long getLongVal() {
+        return longVal;
+    }
+
+    public double getDoubleVal() {
+        return doubleVal;
+    }
+
+    public boolean getBoolVal() {
+        return boolVal;
+    }
+
+    public ClassAdTime getTimeVal() {
+        return timeVal;
+    }
+
+    public ClassAd getClassadVal() {
+        return classadVal;
+    }
+
+    public ExprList getListVal() {
+        return listVal;
+    }
+
+    public String getStringVal() {
+        return stringVal;
+    }
+
+    public static double[] getScalefactor() {
+        return ScaleFactor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/AttributeReferencePool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/AttributeReferencePool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/AttributeReferencePool.java
new file mode 100644
index 0000000..d7bcfcc
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/AttributeReferencePool.java
@@ -0,0 +1,35 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.AttributeReference;
+
+public class AttributeReferencePool extends Pool<AttributeReference> {
+
+    @Override
+    public AttributeReference newInstance() {
+        return new AttributeReference();
+    }
+
+    @Override
+    protected void reset(AttributeReference obj) {
+        obj.reset();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/BitSetPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/BitSetPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/BitSetPool.java
new file mode 100644
index 0000000..b6f110d
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/BitSetPool.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.asterix.external.classad.object.pool;
+
+import java.util.BitSet;
+
+public class BitSetPool extends Pool<BitSet> {
+
+    @Override
+    public BitSet newInstance() {
+        return new BitSet();
+    }
+
+    @Override
+    protected void reset(BitSet obj) {
+        obj.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CaseInsensitiveStringPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CaseInsensitiveStringPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CaseInsensitiveStringPool.java
new file mode 100644
index 0000000..7e88961
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CaseInsensitiveStringPool.java
@@ -0,0 +1,55 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import java.util.Stack;
+
+import org.apache.asterix.external.classad.CaseInsensitiveString;
+
+public class CaseInsensitiveStringPool extends Pool<CaseInsensitiveString> {
+
+    protected Stack<CaseInsensitiveString> stock = new Stack<CaseInsensitiveString>();
+
+    @Override
+    public CaseInsensitiveString get() {
+        if (!stock.isEmpty()) {
+            return stock.pop();
+        } else {
+            return newInstance();
+
+        }
+    }
+
+    @Override
+    public void reset() {
+    }
+
+    public void put(CaseInsensitiveString aString) {
+        stock.push(aString);
+    }
+
+    @Override
+    public CaseInsensitiveString newInstance() {
+        return new CaseInsensitiveString();
+    }
+
+    @Override
+    protected void reset(CaseInsensitiveString obj) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CharArrayStringPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CharArrayStringPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CharArrayStringPool.java
new file mode 100644
index 0000000..6fe1d16
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/CharArrayStringPool.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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.AMutableCharArrayString;
+
+public class CharArrayStringPool extends Pool<AMutableCharArrayString> {
+
+    @Override
+    public AMutableCharArrayString newInstance() {
+        return new AMutableCharArrayString(32);
+    }
+
+    @Override
+    protected void reset(AMutableCharArrayString obj) {
+        obj.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ClassAdPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ClassAdPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ClassAdPool.java
new file mode 100644
index 0000000..40b8eb3
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ClassAdPool.java
@@ -0,0 +1,36 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.ClassAd;
+
+public class ClassAdPool extends Pool<ClassAd> {
+
+    @Override
+    public ClassAd newInstance() {
+        return new ClassAd(false, false);
+    }
+
+    @Override
+    protected void reset(ClassAd obj) {
+        //probably we want to get the expressions stored inside the classad so we can return them to their pools
+        obj.reset();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprHolderPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprHolderPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprHolderPool.java
new file mode 100644
index 0000000..b34e863
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprHolderPool.java
@@ -0,0 +1,33 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.ExprTreeHolder;
+
+public class ExprHolderPool extends Pool<ExprTreeHolder> {
+    @Override
+    public ExprTreeHolder newInstance() {
+        return new ExprTreeHolder();
+    }
+
+    @Override
+    protected void reset(ExprTreeHolder obj) {
+        obj.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprListPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprListPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprListPool.java
new file mode 100644
index 0000000..1f2958a
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ExprListPool.java
@@ -0,0 +1,35 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.ExprList;
+
+public class ExprListPool extends Pool<ExprList> {
+
+    @Override
+    public ExprList newInstance() {
+        return new ExprList();
+    }
+
+    @Override
+    protected void reset(ExprList obj) {
+        obj.reset();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/LiteralPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/LiteralPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/LiteralPool.java
new file mode 100644
index 0000000..23d8dae
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/LiteralPool.java
@@ -0,0 +1,33 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.Literal;
+
+public class LiteralPool extends Pool<Literal> {
+    @Override
+    public Literal newInstance() {
+        return new Literal();
+    }
+
+    @Override
+    protected void reset(Literal obj) {
+        obj.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/OperationPool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/OperationPool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/OperationPool.java
new file mode 100644
index 0000000..062d870
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/OperationPool.java
@@ -0,0 +1,35 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.Operation;
+
+public class OperationPool extends Pool<Operation> {
+
+    @Override
+    public Operation newInstance() {
+        return new Operation();
+    }
+
+    @Override
+    protected void reset(Operation obj) {
+        obj.reset();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/Pool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/Pool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/Pool.java
new file mode 100644
index 0000000..6a39596
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/Pool.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.asterix.external.classad.object.pool;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class Pool<T> {
+    protected List<T> inUse = new ArrayList<T>();
+    protected int pointer = 0;
+
+    public T get() {
+        if (pointer >= inUse.size()) {
+            inUse.add(newInstance());
+        }
+        T t = inUse.get(pointer);
+        pointer++;
+        reset(t);
+        return t;
+    }
+
+    public abstract T newInstance();
+
+    public void reset() {
+        pointer = 0;
+    }
+
+    protected abstract void reset(T obj);
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/TokenValuePool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/TokenValuePool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/TokenValuePool.java
new file mode 100644
index 0000000..a5328ee
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/TokenValuePool.java
@@ -0,0 +1,33 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.TokenValue;
+
+public class TokenValuePool extends Pool<TokenValue> {
+    @Override
+    public TokenValue newInstance() {
+        return new TokenValue();
+    }
+
+    @Override
+    protected void reset(TokenValue obj) {
+        obj.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ValuePool.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ValuePool.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ValuePool.java
new file mode 100644
index 0000000..5034dbe
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/object/pool/ValuePool.java
@@ -0,0 +1,33 @@
+/*
+ * 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.asterix.external.classad.object.pool;
+
+import org.apache.asterix.external.classad.Value;
+
+public class ValuePool extends Pool<Value> {
+    @Override
+    public Value newInstance() {
+        return new Value();
+    }
+
+    @Override
+    protected void reset(Value obj) {
+        obj.clear();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdFunctionalTest.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdFunctionalTest.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdFunctionalTest.java
new file mode 100644
index 0000000..2f23684
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdFunctionalTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.asterix.external.classad.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class ClassAdFunctionalTest extends TestCase {
+    /**
+     * Create the test case
+     *
+     * @param testName
+     *            name of the test case
+     */
+    public ClassAdFunctionalTest(String testName) {
+        super(testName);
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite() {
+        return new TestSuite(ClassAdFunctionalTest.class);
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp() {
+
+        String[] args = { "", "-d", "-v", getClass().getResource("/functional_tests.txt").getPath() };
+        try {
+            FunctionalTester.test(args.length, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        assertTrue(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdParserTest.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdParserTest.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdParserTest.java
new file mode 100644
index 0000000..b0e0925
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/ClassAdParserTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.asterix.external.classad.test;
+
+import java.io.BufferedReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.apache.asterix.external.classad.ClassAd;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class ClassAdParserTest extends TestCase {
+    /**
+     * Create the test case
+     *
+     * @param testName
+     *            name of the test case
+     */
+    public ClassAdParserTest(String testName) {
+        super(testName);
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite() {
+        return new TestSuite(ClassAdParserTest.class);
+    }
+
+    /**
+     *
+     */
+    public void testApp() {
+        try {
+            // test here
+            ClassAd pAd = new ClassAd();
+            String szInput;
+            String[] files = new String[] { "/testdata.txt" };
+            BufferedReader infile = null;
+            for (String path : files) {
+                infile = Files.newBufferedReader(Paths.get(getClass().getResource(path).getPath()),
+                        StandardCharsets.UTF_8);
+                szInput = infile.readLine();
+                while (szInput != null) {
+                    if (szInput.trim().length() == 0) {
+                        // ClassAdChain completed
+                        pAd.clear();
+                    } else if (!pAd.insert(szInput)) {
+                        // Problem
+                        System.out.println("BARFED ON:" + szInput);
+                        assert (false);
+                    }
+                    szInput = infile.readLine();
+                }
+                infile.close();
+            }
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+        assertTrue(true);
+    }
+}