@Override
	public List<Node> neighbors(Node node) throws IOException {
		List<Node> nodes = new LinkedList<Node>();
		List<String> wayList = new ArrayList<String>();
		node.streets = new HashMap<Node,Node.Way>();
		double[] latlong = new double[2];
		bacon.reader.lock();
		boolean success = bacon.reader.nodeSearch(node.id, wayList, latlong);
		bacon.reader.unlock();
		if (success == false) {
			throw new IOException("ERROR: Missing node data.");
		}
		//set latitude longitude to correct values
		node.latitude = latlong[0];
		node.longitude = latlong[1];
		
		for (String wayID : wayList) {
			List<String> nodeList = new ArrayList<String>();
			bacon.reader.lock();
			String wayName = bacon.reader.waySearch(wayID, nodeList);
			bacon.reader.unlock();
			if (wayName == null) {
				throw new IOException("ERROR: Missing way data.");
			} else {
				// check each node
				for (String nodeID : nodeList) {
					if (!nodeID.equals(node.id)) { // avoid looking at self
						// create neighbor node
						List<String> dummyList = new ArrayList<String>(1);
						bacon.reader.lock();
						boolean exists = bacon.reader.nodeSearch(nodeID, dummyList, latlong);
						bacon.reader.unlock();
						if (exists == false) {
							throw new IOException("ERROR: Missing node data.");
						}
						Node neighbor = new Node(latlong[0],latlong[1],nodeID);
						// calculate edge weight
						Double edgeWeight = bacon.estDistCalc(node,neighbor);
						Double trafficVal;
						synchronized(trafficData) {
							trafficVal = trafficData.get(wayName);
						}
						if (trafficVal != null) {
							edgeWeight = edgeWeight * trafficVal;
						} else {
							trafficVal = 1.0;
						}
						
						// add to streets list and output list
						node.streets.put(neighbor, node.new Way(wayID, wayName, edgeWeight, trafficVal));
						nodes.add(neighbor);
					}
				}
			}
		}
		return nodes;
	}