// Path: src/main/java/com/netflix/nfgraph/NFGraphModelHolder.java
// public class NFGraphModelHolder implements Iterable<String> {
// 
//     public static final String CONNECTION_MODEL_GLOBAL = "global";
// 
//     private OrdinalMap<String> modelMap;
// 	
// 	public NFGraphModelHolder() {
// 	    modelMap = new OrdinalMap<String>();
// 	    modelMap.add(CONNECTION_MODEL_GLOBAL);
// 	}
// 	
// 	public int size() {
// 		return modelMap.size();
// 	}
// 	
// 	public int getModelIndex(String connectionModel) {
// 	    return modelMap.add(connectionModel);
// 	}
// 	
// 	public String getModel(int modelIndex) {
// 	    return modelMap.get(modelIndex);
// 	}
// 	
// 	public Iterator<String> iterator() {
// 	    return modelMap.iterator();
// 	}
// 
// }
// 
// Path: src/main/java/com/netflix/nfgraph/spec/NFGraphSpec.java
// public class NFGraphSpec implements Iterable<NFNodeSpec> {
//     
//     private final Map<String, NFNodeSpec> nodeSpecs;
// 
//     /**
//      * Instantiate a graph specification with no {@link NFNodeSpec}s.
//      */
//     public NFGraphSpec() {
//         this.nodeSpecs = new HashMap<String, NFNodeSpec>();
//     }
//     
//     /**
//      * Instantiate a graph specification with the given {@link NFNodeSpec}. 
//      */
//     public NFGraphSpec(NFNodeSpec... nodeTypes) {
//         this();
//         
//         for(NFNodeSpec spec : nodeTypes) {
//             addNodeSpec(spec);
//         }
//     }
// 
//     /**
//      * @return the {@link NFNodeSpec} for the specified node type.
//      */
//     public NFNodeSpec getNodeSpec(String nodeType) {
//         NFNodeSpec spec = nodeSpecs.get(nodeType);
//         if(spec == null)
//             throw new NFGraphException("Node spec " + nodeType + " is undefined");
//         return spec;
//     }
//     
//     /**
//      * Add a node type to this graph specification. 
//      */
//     public void addNodeSpec(NFNodeSpec nodeSpec) {
//         nodeSpecs.put(nodeSpec.getNodeTypeName(), nodeSpec);
//     }
//     
//     /**
//      * @return the number of node types defined by this graph specification.
//      */
//     public int size() {
//         return nodeSpecs.size();
//     }
//     
//     /**
//      * @return a {@link List} containing the names of each of the node types.
//      */
//     public List<String> getNodeTypes() {
//     	return new ArrayList<String>(nodeSpecs.keySet());
//     }
// 
//     /**
//      * Returns an {@link Iterator} over the {@link NFNodeSpec}s contained in this graph specification.
//      */
//     @Override
//     public Iterator<NFNodeSpec> iterator() {
//         return nodeSpecs.values().iterator();
//     }
//     
// }
// 
// Path: src/main/java/com/netflix/nfgraph/spec/NFNodeSpec.java
// public class NFNodeSpec implements Iterable<NFPropertySpec> {
// 
// 	private final String nodeTypeName;
//     private final NFPropertySpec propertySpecs[];
//     
//     private final int numSingleProperties;
//     private final int numMultipleProperties;
// 
//     /**
//      * The constructor for an <code>NFNodeSpec</code>.
//      * 
//      * @param nodeTypeName the name of the node type
//      * @param propertySpecs a complete listing of the properties available for this node type.
//      */
//     public NFNodeSpec(String nodeTypeName, NFPropertySpec... propertySpecs) {
//     	this.nodeTypeName = nodeTypeName;
//         this.propertySpecs = propertySpecs;
//         
//         int numSingleProperties = 0;
//         int numMultipleProperties = 0;
//         
//         for(NFPropertySpec propertySpec : propertySpecs) {
//         	propertySpec.setPropertyIndex(propertySpec.isSingle() ? numSingleProperties++ : numMultipleProperties++);
//         }
//         
//         this.numSingleProperties = numSingleProperties;
//         this.numMultipleProperties = numMultipleProperties;
//     }
//     
//     public String getNodeTypeName() {
//     	return nodeTypeName;
//     }
// 
//     public NFPropertySpec[] getPropertySpecs() {
//         return propertySpecs;
//     }
//     
//     public NFPropertySpec getPropertySpec(String propertyName) {
//         for(NFPropertySpec spec : propertySpecs) {
//             if(spec.getName().equals(propertyName))
//                 return spec;
//         }
//         throw new NFGraphException("Property " + propertyName + " is undefined for node type " + nodeTypeName);
//     }
//     
//     public int getNumSingleProperties() {
//     	return numSingleProperties;
//     }
//     
//     public int getNumMultipleProperties() {
//     	return numMultipleProperties;
//     }
// 
//     @Override
//     public Iterator<NFPropertySpec> iterator() {
//         return new ArrayIterator<NFPropertySpec>(propertySpecs);
//     }
//     
// }


import java.util.HashMap;
import java.util.Map;
import com.netflix.nfgraph.NFGraphModelHolder;
import com.netflix.nfgraph.spec.NFGraphSpec;
import com.netflix.nfgraph.spec.NFNodeSpec;
/*
 *  Copyright 2013 Netflix, Inc.
 *
 *     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 com.netflix.nfgraph.build;



public class NFBuildGraphNodeCache {

	private final NFGraphSpec graphSpec;
	private final NFGraphModelHolder buildGraphModelHolder;
    private final Map<String,NFBuildGraphNodeList> nodesByOrdinal;

    NFBuildGraphNodeCache(NFGraphSpec graphSpec, NFGraphModelHolder modelHolder) {
        this.nodesByOrdinal = new HashMap<String, NFBuildGraphNodeList>();
        this.graphSpec = graphSpec;
        this.buildGraphModelHolder = modelHolder;
    }

    NFBuildGraphNode getNode(String nodeType, int ordinal) {
        NFBuildGraphNodeList nodes = getNodes(nodeType);
// Path: src/main/java/com/netflix/nfgraph/NFGraphModelHolder.java
// public class NFGraphModelHolder implements Iterable<String> {
// 
//     public static final String CONNECTION_MODEL_GLOBAL = "global";
// 
//     private OrdinalMap<String> modelMap;
// 	
// 	public NFGraphModelHolder() {
// 	    modelMap = new OrdinalMap<String>();
// 	    modelMap.add(CONNECTION_MODEL_GLOBAL);
// 	}
// 	
// 	public int size() {
// 		return modelMap.size();
// 	}
// 	
// 	public int getModelIndex(String connectionModel) {
// 	    return modelMap.add(connectionModel);
// 	}
// 	
// 	public String getModel(int modelIndex) {
// 	    return modelMap.get(modelIndex);
// 	}
// 	
// 	public Iterator<String> iterator() {
// 	    return modelMap.iterator();
// 	}
// 
// }
// 
// Path: src/main/java/com/netflix/nfgraph/spec/NFGraphSpec.java
// public class NFGraphSpec implements Iterable<NFNodeSpec> {
//     
//     private final Map<String, NFNodeSpec> nodeSpecs;
// 
//     /**
//      * Instantiate a graph specification with no {@link NFNodeSpec}s.
//      */
//     public NFGraphSpec() {
//         this.nodeSpecs = new HashMap<String, NFNodeSpec>();
//     }
//     
//     /**
//      * Instantiate a graph specification with the given {@link NFNodeSpec}. 
//      */
//     public NFGraphSpec(NFNodeSpec... nodeTypes) {
//         this();
//         
//         for(NFNodeSpec spec : nodeTypes) {
//             addNodeSpec(spec);
//         }
//     }
// 
//     /**
//      * @return the {@link NFNodeSpec} for the specified node type.
//      */
//     public NFNodeSpec getNodeSpec(String nodeType) {
//         NFNodeSpec spec = nodeSpecs.get(nodeType);
//         if(spec == null)
//             throw new NFGraphException("Node spec " + nodeType + " is undefined");
//         return spec;
//     }
//     
//     /**
//      * Add a node type to this graph specification. 
//      */
//     public void addNodeSpec(NFNodeSpec nodeSpec) {
//         nodeSpecs.put(nodeSpec.getNodeTypeName(), nodeSpec);
//     }
//     
//     /**
//      * @return the number of node types defined by this graph specification.
//      */
//     public int size() {
//         return nodeSpecs.size();
//     }
//     
//     /**
//      * @return a {@link List} containing the names of each of the node types.
//      */
//     public List<String> getNodeTypes() {
//     	return new ArrayList<String>(nodeSpecs.keySet());
//     }
// 
//     /**
//      * Returns an {@link Iterator} over the {@link NFNodeSpec}s contained in this graph specification.
//      */
//     @Override
//     public Iterator<NFNodeSpec> iterator() {
//         return nodeSpecs.values().iterator();
//     }
//     
// }
// 
// Path: src/main/java/com/netflix/nfgraph/spec/NFNodeSpec.java
// public class NFNodeSpec implements Iterable<NFPropertySpec> {
// 
// 	private final String nodeTypeName;
//     private final NFPropertySpec propertySpecs[];
//     
//     private final int numSingleProperties;
//     private final int numMultipleProperties;
// 
//     /**
//      * The constructor for an <code>NFNodeSpec</code>.
//      * 
//      * @param nodeTypeName the name of the node type
//      * @param propertySpecs a complete listing of the properties available for this node type.
//      */
//     public NFNodeSpec(String nodeTypeName, NFPropertySpec... propertySpecs) {
//     	this.nodeTypeName = nodeTypeName;
//         this.propertySpecs = propertySpecs;
//         
//         int numSingleProperties = 0;
//         int numMultipleProperties = 0;
//         
//         for(NFPropertySpec propertySpec : propertySpecs) {
//         	propertySpec.setPropertyIndex(propertySpec.isSingle() ? numSingleProperties++ : numMultipleProperties++);
//         }
//         
//         this.numSingleProperties = numSingleProperties;
//         this.numMultipleProperties = numMultipleProperties;
//     }
//     
//     public String getNodeTypeName() {
//     	return nodeTypeName;
//     }
// 
//     public NFPropertySpec[] getPropertySpecs() {
//         return propertySpecs;
//     }
//     
//     public NFPropertySpec getPropertySpec(String propertyName) {
//         for(NFPropertySpec spec : propertySpecs) {
//             if(spec.getName().equals(propertyName))
//                 return spec;
//         }
//         throw new NFGraphException("Property " + propertyName + " is undefined for node type " + nodeTypeName);
//     }
//     
//     public int getNumSingleProperties() {
//     	return numSingleProperties;
//     }
//     
//     public int getNumMultipleProperties() {
//     	return numMultipleProperties;
//     }
// 
//     @Override
//     public Iterator<NFPropertySpec> iterator() {
//         return new ArrayIterator<NFPropertySpec>(propertySpecs);
//     }
//     
// }


// Path: src/main/java/com/netflix/nfgraph/build/NFBuildGraphNodeCache.java
import java.util.HashMap;
import java.util.Map;
import com.netflix.nfgraph.NFGraphModelHolder;
import com.netflix.nfgraph.spec.NFGraphSpec;
import com.netflix.nfgraph.spec.NFNodeSpec;

/*
 *  Copyright 2013 Netflix, Inc.
 *
 *     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 com.netflix.nfgraph.build;



public class NFBuildGraphNodeCache {

	private final NFGraphSpec graphSpec;
	private final NFGraphModelHolder buildGraphModelHolder;
    private final Map<String,NFBuildGraphNodeList> nodesByOrdinal;

    NFBuildGraphNodeCache(NFGraphSpec graphSpec, NFGraphModelHolder modelHolder) {
        this.nodesByOrdinal = new HashMap<String, NFBuildGraphNodeList>();
        this.graphSpec = graphSpec;
        this.buildGraphModelHolder = modelHolder;
    }

    NFBuildGraphNode getNode(String nodeType, int ordinal) {
        NFBuildGraphNodeList nodes = getNodes(nodeType);
        NFNodeSpec nodeSpec = graphSpec.getNodeSpec(nodeType);