class ComponentProcessor {

	static boolean removeAndMoveToAppropriateGroupIfSubtractivePrefix(Element substituent) throws ComponentGenerationException {
		List<Element> subtractivePrefixes = substituent.getChildElements(SUBTRACTIVEPREFIX_EL);
		if (subtractivePrefixes.size() > 0) {
			Element biochemicalGroup = null;//preferred
			Element standardGroup = null;
			final Element adjacentSubOrRootOrBracket = OpsinTools.getNextSibling(substituent);
			Element nextSubOrRootOrBracket = adjacentSubOrRootOrBracket;
			if (nextSubOrRootOrBracket == null){
				throw new ComponentGenerationException("Unable to find group for: " + subtractivePrefixes.get(0).getValue() +" to apply to!");
			}
			//prefer the nearest (unlocanted) biochemical group or the rightmost standard group
			while (nextSubOrRootOrBracket != null) {
				Element groupToConsider = nextSubOrRootOrBracket.getFirstChildElement(GROUP_EL);
				if (groupToConsider != null) {
					if (OpsinTools.isBiochemical(groupToConsider.getAttributeValue(TYPE_ATR), groupToConsider.getAttributeValue(SUBTYPE_ATR))){
						biochemicalGroup = groupToConsider;
						if (OpsinTools.getPreviousSiblingsOfType(biochemicalGroup, LOCANT_EL).size() == 0) {
							break;
						}
					}
					else {
						standardGroup = groupToConsider;
					}
				}
				nextSubOrRootOrBracket = OpsinTools.getNextSibling(nextSubOrRootOrBracket);
			}
			
			Element targetGroup = biochemicalGroup != null ? biochemicalGroup : standardGroup;
			if (targetGroup == null) {
				throw new ComponentGenerationException("Unable to find group for: " + subtractivePrefixes.get(0).getValue() +" to apply to!");
			}
			
			//move the children of the subtractivePrefix substituent
			List<Element> children = substituent.getChildElements();
			Element targetSubstituent = targetGroup.getParent();
			if (targetSubstituent.equals(adjacentSubOrRootOrBracket)) {
				for (int i = children.size()-1; i >=0 ; i--) {
					Element child =children.get(i);
					if (!child.getName().equals(HYPHEN_EL)){
						child.detach();
						targetSubstituent.insertChild(child, 0);
					}
				}
			}
			else {
				boolean inDetachablePrefix = true;
				for (int i = children.size()-1; i >=0 ; i--) {
					Element child = children.get(i);
					String elName = child.getName();
					if (elName.equals(HYPHEN_EL)) {
						continue;
					}
					else if (inDetachablePrefix && elName.equals(SUBTRACTIVEPREFIX_EL)) {
						child.detach();
						targetSubstituent.insertChild(child, 0);
					}
					else if (elName.equals(STEREOCHEMISTRY_EL)) {
						inDetachablePrefix = false;
						child.detach();
						adjacentSubOrRootOrBracket.insertChild(child, 0);
					}
					else {
						throw new ComponentGenerationException("Unexpected term found before detachable substractive prefix: " + child.getValue() );
					}
				}
			}
			substituent.detach();
			return true;
		}
		return false;
	}

	  ComponentProcessor(BuildState state, SuffixApplier suffixApplier);

}