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

import java.util.List;

import org.javersion.object.ReadContext;
import org.javersion.object.WriteContext;
import org.javersion.path.PropertyPath;
import org.javersion.path.PropertyPath.Index;
import org.javersion.path.PropertyTree;

import com.google.common.collect.Lists;

public class ListType implements ValueType {

    @Override
    public Object instantiate(PropertyTree propertyTree, Object value, ReadContext context) throws Exception {
        int size = (Integer) value;
        Object[] values = new Object[size];
        for (PropertyTree child : propertyTree.getChildren()) {
            int index = Integer.valueOf(((Index) child.path).index);
            Object element = context.getObject(child);
            values[index] = element;
        }
        return Lists.newArrayList(values);
    }

    @Override
    public void bind(PropertyTree propertyTree, Object object, ReadContext context) throws Exception {}

    @Override
    public void serialize(PropertyPath path, Object object, WriteContext context) {
        @SuppressWarnings("rawtypes")
        List list = (List) object;
        context.put(path, list.size());
        for (int i=0; i < list.size(); i++) {
            context.serialize(path.index(i), list.get(i));
        }
    }

    @Override
    public boolean isReference() {
        return false;
    }

}

@@ -637,22 +637,114 @@
 ort 
-java.util.List
+static java.lang.Integer.valueOf;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Ai
@@ -903,146 +903,111 @@
 erty
-Path.Index;%0Aimport org.javersion.path.PropertyTree;%0A%0Aimport com.google.common.collect.Lists;%0A%0Apublic class ListType implements ValueType %7B
+Tree;%0A%0Apublic class ListType implements ValueType %7B%0A%0A    private static final String CONSTANT = %22List%22;
 %0A%0A  
@@ -1141,34 +1141,74 @@
     
-int size = (Integer) value
+Map%3CString, PropertyTree%3E children = propertyTree.getChildrenMap()
 ;%0A  
@@ -1217,42 +1217,60 @@
     
+List%3C
 Object
-%5B%5D values = new Object%5B
+%3E list = new ArrayList%3C%3E(children.
 size
-%5D
+())
 ;%0A  
@@ -1284,156 +1284,349 @@
 or (
-PropertyTree child : propertyTree.getChildren()) %7B%0A            int index = Integer.valueOf(((Index) child.path).index);%0A            Object element =
+Map.Entry%3CString, PropertyTree%3E entry : children.entrySet()) %7B%0A            PropertyTree child = entry.getValue();%0A            int index = valueOf(entry.getKey());%0A            if (index %3E list.size()) %7B%0A                fill(list, index, children, context);%0A            %7D%0A            if (index == list.size()) %7B%0A                list.add(index,
  con
@@ -1646,16 +1646,17 @@
 t(child)
+)
 ;%0A      
@@ -1665,85 +1665,454 @@
     
-values%5Bindex%5D = element;%0A        %7D%0A        return Lists.newArrayList(values);
+%7D%0A        %7D%0A        return list;%0A    %7D%0A%0A    private void fill(List%3CObject%3E list, int targetSize, Map%3CString, PropertyTree%3E children, ReadContext context) %7B%0A        for (int i=list.size(); i %3C targetSize; i++) %7B%0A            PropertyTree child = children.get(Integer.toString(i));%0A            if (child == null) %7B%0A                list.add(i, null);%0A            %7D else %7B%0A                list.add(i, context.getObject(child));%0A            %7D%0A        %7D
 %0A   
@@ -2431,27 +2431,24 @@
 t(path, 
-list.size()
+CONSTANT
 );%0A     

Fix conflict prone root value from size to a constant "List"