private static  Attributes<Cell> attributesFrom(Node node, URI uri, ComplexCellModel cellModel, Predicate<String> attributeFilter) {
	if (!node.hasAttributes()) {	//	** base case **
		return new OrderedMap<Cell>(0);
	}
	if (cellModel.isSimple()) {
		log.error("CellModel '{}' does not allow attributes but the elem does", cellModel.getName());
		throw new RuntimeException("Element and model attribute mismatch", new IllegalArgumentException());
	}
	// 								** recursive case **
	OrderedMap<Cell> attributes = new OrderedMap<Cell>(node.getAttributes().getLength());
	NamedNodeMap elemAttributes = node.getAttributes();	// TODO: notice this is not ordered like the input ^^'
	for (int i=0; i<elemAttributes.getLength(); i++) {
		Node attribute = elemAttributes.item(i);
		String attributeName = attribute.getNodeName();
		URI childURI = cellURI(uri, cellModel, ATTRIBUTE_PREFIX+attributeName);
		// if we are looking for public attributes, they need to match with the attributes model, otherwise we just
		// point to the node cell model (IDEA: maybe in the future point to the internal model)
		CellModel attributeCellModel = findAttributeWithName(cellModel, attributeName);
		if (attributeFilter.test(attributeName)) {
			Cell attributeCell = DaggerCellComponent.builder()
														.withURI(childURI)
														.fromNode(attribute)
														.withCellModel(attributeCellModel)
														.build()
														.createCell();
			attributes.addChild(attributeName, attributeCell); 
			//System.err.println("\t\ta["+i+"]:"+attributeName+":"+attributeCell.getValue());
		} else  {
		}
	}
	return attributes;
}
private static  Attributes<Cell> attributesFrom(Node node, URI uri, ComplexCellModel cellModel, Predicate<String> attributeFilter) {
	if (!node.hasAttributes()) {
		return new OrderedMap<Cell>(0);
	}
	if (cellModel.isSimple()) {
		log.error("CellModel '{}' does not allow attributes but the elem does", cellModel.getName());
		throw new RuntimeException("Element and model attribute mismatch", new IllegalArgumentException());
	}

	OrderedMap<Cell> attributes = new OrderedMap<Cell>(node.getAttributes().getLength());
	NamedNodeMap elemAttributes = node.getAttributes();
	for (int i=0; i<elemAttributes.getLength(); i++) {
		Node attribute = elemAttributes.item(i);
		String attributeName = attribute.getNodeName();
		URI childURI = cellURI(uri, cellModel, ATTRIBUTE_PREFIX+attributeName);
	
	
		CellModel attributeCellModel = findAttributeWithName(cellModel, attributeName);
		if (attributeFilter.test(attributeName)) {
			Cell attributeCell = DaggerCellComponent.builder()
														.withURI(childURI)
														.fromNode(attribute)
														.withCellModel(attributeCellModel)
														.build()
														.createCell();
			attributes.addChild(attributeName, attributeCell); 
		
		} else  {
		}
	}
	return attributes;
}
private static attributes<cell> attributesfrom(node node, uri uri, complexcellmodel cellmodel, predicate<string> attributefilter) { if (!node.hasattributes()) { return new orderedmap<cell>(0); } if (cellmodel.issimple()) { log.error("cellmodel '{}' does not allow attributes but the elem does", cellmodel.getname()); throw new runtimeexception("element and model attribute mismatch", new illegalargumentexception()); } orderedmap<cell> attributes = new orderedmap<cell>(node.getattributes().getlength()); namednodemap elemattributes = node.getattributes(); for (int i=0; i<elemattributes.getlength(); i++) { node attribute = elemattributes.item(i); string attributename = attribute.getnodename(); uri childuri = celluri(uri, cellmodel, attribute_prefix+attributename); cellmodel attributecellmodel = findattributewithname(cellmodel, attributename); if (attributefilter.test(attributename)) { cell attributecell = daggercellcomponent.builder() .withuri(childuri) .fromnode(attribute) .withcellmodel(attributecellmodel) .build() .createcell(); attributes.addchild(attributename, attributecell); } else { } } return attributes; }