new utility method that checks that the order of the pair in the XML alignment is correct and flips the direction if needed

@param xml
@param name1
@param name1
@param ca1
@param ca2
@return
19976
public static AFPChain fromXML(String xml, String name1, String name2, Atom[] ca1, Atom[] ca2) throws IOException, StructureException{
			AFPChain[] afps = parseMultiXML( xml);
			if ( afps.length > 0 ) {

				AFPChain afpChain = afps[0];

				String n1 = afpChain.getName1();
				String n2 = afpChain.getName2();

				if ( n1 == null )
					n1 = "";
				if ( n2 == null)
					n2 = "";

				//System.out.println("from AFPCHAIN: " + n1 + " " + n2);
				if ( n1.equals(name2) && n2.equals(name1)){
					// flipped order
					//System.out.println("AfpChain in wrong order, flipping...");
					afpChain  = AFPChainFlipper.flipChain(afpChain);
				}
				rebuildAFPChain(afpChain, ca1, ca2);

				return afpChain;
			}
			return null;

	 }
1331024
private static void permuteOptAln(AFPChain afpChain, int cp)
	{
		int ca2len = afpChain.getCa2Length();

		if( ca2len <= 0) {
			throw new IllegalArgumentException("No Ca2Length specified in "+afpChain);
		}

		// Allow negative cp points for convenience.
		if(cp == 0) {
			return;
		}
		if(cp <= -ca2len || cp >= ca2len) {
			// could just take cp%ca2len, but probably its a bug if abs(cp)>=ca2len
			throw new ArrayIndexOutOfBoundsException( String.format(
					"Permutation point %d must be between %d and %d for %s",
					cp, 1-ca2len,ca2len-1, afpChain.getName2() ) );
		}
		if(cp < 0) {
			cp = cp + ca2len;
		}

		// the unprocessed alignment
		int[][][] optAln = afpChain.getOptAln();
		int[] optLen = afpChain.getOptLen();

		// the processed alignment
		List<List<List<Integer>>> blocks = new ArrayList<List<List<Integer>>>(afpChain.getBlockNum()*2);

		//Update residue indices
		// newi = (oldi-cp) % N
		for(int block = 0; block < afpChain.getBlockNum(); block++) {
			if(optLen[block]<1)
				continue;

			// set up storage for the current block
			List<List<Integer>> currBlock = new ArrayList<List<Integer>>(2);
			currBlock.add( new ArrayList<Integer>());
			currBlock.add( new ArrayList<Integer>());
			blocks.add(currBlock);

			// pos = 0 case
			currBlock.get(0).add( optAln[block][0][0] );
			currBlock.get(1).add( (optAln[block][1][0]+cp ) % ca2len);

			for(int pos = 1; pos < optLen[block]; pos++) {
				//check if we need to start a new block
				//this happens when the new alignment crosses the protein terminus
				if( optAln[block][1][pos-1]+cp<ca2len &&
						optAln[block][1][pos]+cp >= ca2len) {
					currBlock = new ArrayList<List<Integer>>(2);
					currBlock.add( new ArrayList<Integer>());
					currBlock.add( new ArrayList<Integer>());
					blocks.add(currBlock);
				}
				currBlock.get(0).add( optAln[block][0][pos] );
				currBlock.get(1).add( (optAln[block][1][pos]+cp ) % ca2len);
			}
		}

		// save permuted blocks to afpChain
		assignOptAln(afpChain,blocks);
	}
950088
public static boolean areElementEquals(Element element1, Element element2) {
		for (Mask mask1 : element1.getMask()) {
			if (!areBooleanEquals(element1.isNegated(), element2.isNegated())) {
				// Negated.
				return false;
			}
			for (Mask mask2 : element2.getMask()) {
				if (!areStringEquals(mask1.getLexemeMask(), mask2.getLexemeMask())) {
					// LexemeMask.
					return false;
				} else if (!areStringEquals(mask1.getPrimitiveMask(), mask2.getPrimitiveMask())) {
					// PrimitiveMask.
					return false;
				} else if (!areTagMaskEquals(mask1.getTagMask(), mask2.getTagMask())) {
					// TagMask.
					return false;
				}
			}
		}
		return true;
	}
190
private AFPChain alignRight(Atom[] ca1, Atom[] ca2, CECPParameters cpparams)
			throws StructureException {
		long startTime = System.currentTimeMillis();

		Atom[] ca2m = StructureTools.duplicateCA2(ca2);

		if(debug) {
			System.out.format("Duplicating ca2 took %s ms\n",System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}

		// Do alignment
		AFPChain afpChain = super.align(ca1, ca2m,params);

		// since the process of creating ca2m strips the name info away, set it explicitely
		try {
			afpChain.setName2(ca2[0].getGroup().getChain().getStructure().getName());
		} catch( Exception e) {}

		if(debug) {
			System.out.format("Running %dx2*%d alignment took %s ms\n",ca1.length,ca2.length,System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}
		afpChain = postProcessAlignment(afpChain, ca1, ca2m, calculator, cpparams);

		if(debug) {
			System.out.format("Finding CP point took %s ms\n",System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}

		return afpChain;
	}
1187145
public static boolean isXML11ValidNCName(String ncName) {
        int length = ncName.length();
        if (length == 0)
            return false;
        int i = 1;
        char ch = ncName.charAt(0);
        if( !isXML11NCNameStart(ch) ) {
            if ( length > 1 && isXML11NameHighSurrogate(ch) ) {
                char ch2 = ncName.charAt(1);
                if ( !XMLChar.isLowSurrogate(ch2) || 
                     !isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) {
                    return false;
                }
                i = 2;
            }
            else {
                return false;
            }
        }
        while (i < length) {
            ch = ncName.charAt(i);
            if ( !isXML11NCName(ch) ) {
                if ( ++i < length && isXML11NameHighSurrogate(ch) ) {
                    char ch2 = ncName.charAt(i);
                    if ( !XMLChar.isLowSurrogate(ch2) || 
                         !isXML11NCName(XMLChar.supplemental(ch, ch2)) ) {
                        return false;
                    }
                }
                else {
                    return false;
                }
            }
            ++i;
        }
        return true;
    }
403518
protected final char skipEquals(String name, String eofMsg)
        throws XMLStreamException
    {
        char c = getNextInCurrAfterWS(eofMsg);
        if (c != '=') {
            throwUnexpectedChar(c, " in xml declaration; expected '=' to follow pseudo-attribute '"+name+"'");
        }
        // trailing space?
        return getNextInCurrAfterWS(eofMsg);
    }
948662
public static boolean isValidXMLName(String s) {

		// Catch the empty string or null.
		if (s == null || "".equals(s)) {
			return false;
		}

		// Since the string isn't empty, check that the first character is a
		// valid starting character.
		if (!isXMLNameStart(s.codePointAt(0))) {
			return false;
		}

		// Loop through the string by UNICODE codepoints. This is NOT equivalent
		// to looping through the characters because some UNICODE codepoints can
		// occupy more than one character.
		int length = s.length();
		int index = 1;
		while (index < length) {
			int codePoint = s.codePointAt(index);
			if (!isXMLNamePart(codePoint)) {
				return false;
			}
			index += Character.charCount(codePoint);
		}

		// Names that begin with "xml" with letters in any case are reserved by
		// the XML specification.
		if (s.toLowerCase().startsWith("xml")) {
			return false;
		}

		// If we get here then all of the characters have been checked and are
		// valid. Unfortunately the usual case takes the longest to verify.
		return true;
	}
1095534
public static XmlOrderedResult nameDiffers(String originalElementName, String newElementName) {
        return new XmlOrderedResult(false, String.format("The xml element <%s> should be placed before <%s>",
                newElementName, originalElementName));
    }
859667
public static boolean isInvalidXMLNameStartChar (@Nonnull final EXMLSerializeVersion eXMLVersion, final int c)
  {
    switch (eXMLVersion)
    {
      case XML_10:
        return INVALID_NAME_START_CHAR_XML10.get (c);
      case XML_11:
        return INVALID_NAME_START_CHAR_XML11.get (c);
      case HTML:
        return INVALID_CHAR_HTML.get (c);
      default:
        throw new IllegalArgumentException ("Unsupported XML version " + eXMLVersion + "!");
    }
  }
1280659
public static XmlOrderedResult textContentDiffers(String name, String originalElementText, String newElementText) {
        return new XmlOrderedResult(false, String.format("The xml element <%s>%s</%s> should be placed before <%s>%s</%s>",
                name, newElementText, name, name, originalElementText, name));
    }
722764
public boolean compare(XObject obj2, Comparator comparator)
          throws javax.xml.transform.TransformerException
  {

    boolean result = false;
    int type = obj2.getType();

    if (XObject.CLASS_NODESET == type)
    {
      // %OPT% This should be XMLString based instead of string based...

      // From http://www.w3.org/TR/xpath: 
      // If both objects to be compared are node-sets, then the comparison 
      // will be true if and only if there is a node in the first node-set 
      // and a node in the second node-set such that the result of performing 
      // the comparison on the string-values of the two nodes is true.
      // Note this little gem from the draft:
      // NOTE: If $x is bound to a node-set, then $x="foo" 
      // does not mean the same as not($x!="foo"): the former 
      // is true if and only if some node in $x has the string-value 
      // foo; the latter is true if and only if all nodes in $x have 
      // the string-value foo.
      DTMIterator list1 = iterRaw();
      DTMIterator list2 = ((XNodeSet) obj2).iterRaw();
      int node1;
      java.util.Vector node2Strings = null;

      while (DTM.NULL != (node1 = list1.nextNode()))
      {
        XMLString s1 = getStringFromNode(node1);

        if (null == node2Strings)
        {
          int node2;

          while (DTM.NULL != (node2 = list2.nextNode()))
          {
            XMLString s2 = getStringFromNode(node2);

            if (comparator.compareStrings(s1, s2))
            {
              result = true;

              break;
            }

            if (null == node2Strings)
              node2Strings = new java.util.Vector();

            node2Strings.addElement(s2);
          }
        }
        else
        {
          int n = node2Strings.size();

          for (int i = 0; i < n; i++)
          {
            if (comparator.compareStrings(s1, (XMLString)node2Strings.elementAt(i)))
            {
              result = true;

              break;
            }
          }
        }
      }
      list1.reset();
      list2.reset();
    }
    else if (XObject.CLASS_BOOLEAN == type)
    {

      // From http://www.w3.org/TR/xpath: 
      // If one object to be compared is a node-set and the other is a boolean, 
      // then the comparison will be true if and only if the result of 
      // performing the comparison on the boolean and on the result of 
      // converting the node-set to a boolean using the boolean function 
      // is true.
      double num1 = bool() ? 1.0 : 0.0;
      double num2 = obj2.num();

      result = comparator.compareNumbers(num1, num2);
    }
    else if (XObject.CLASS_NUMBER == type)
    {

      // From http://www.w3.org/TR/xpath: 
      // If one object to be compared is a node-set and the other is a number, 
      // then the comparison will be true if and only if there is a 
      // node in the node-set such that the result of performing the 
      // comparison on the number to be compared and on the result of 
      // converting the string-value of that node to a number using 
      // the number function is true. 
      DTMIterator list1 = iterRaw();
      double num2 = obj2.num();
      int node;

      while (DTM.NULL != (node = list1.nextNode()))
      {
        double num1 = getNumberFromNode(node);

        if (comparator.compareNumbers(num1, num2))
        {
          result = true;

          break;
        }
      }
      list1.reset();
    }
    else if (XObject.CLASS_RTREEFRAG == type)
    {
      XMLString s2 = obj2.xstr();
      DTMIterator list1 = iterRaw();
      int node;

      while (DTM.NULL != (node = list1.nextNode()))
      {
        XMLString s1 = getStringFromNode(node);

        if (comparator.compareStrings(s1, s2))
        {
          result = true;

          break;
        }
      }
      list1.reset();
    }
    else if (XObject.CLASS_STRING == type)
    {

      // From http://www.w3.org/TR/xpath: 
      // If one object to be compared is a node-set and the other is a 
      // string, then the comparison will be true if and only if there 
      // is a node in the node-set such that the result of performing 
      // the comparison on the string-value of the node and the other 
      // string is true. 
      XMLString s2 = obj2.xstr();
      DTMIterator list1 = iterRaw();
      int node;

      while (DTM.NULL != (node = list1.nextNode()))
      {
        XMLString s1 = getStringFromNode(node);
        if (comparator.compareStrings(s1, s2))
        {
          result = true;

          break;
        }
      }
      list1.reset();
    }
    else
    {
      result = comparator.compareNumbers(this.num(), obj2.num());
    }

    return result;
  }
1035696
public static <S extends Sequence<S>> Alignment<S> alignGlobalAffine(AffineGapAlignmentScoring<S> scoring,
                                                                         S seq1, S seq2) {
        if (seq1.getAlphabet() != seq2.getAlphabet() || seq1.getAlphabet() != scoring.getAlphabet())
            throw new IllegalArgumentException("Different alphabets.");

        int
                length1 = seq1.size(),
                length2 = seq2.size(),
                size1 = length1 + 1,
                size2 = length2 + 1;
        Matrix
                gapIn1 = new Matrix(size1, size2),
                gapIn2 = new Matrix(size1, size2),
                matrix = new Matrix(size1, size2);

        int
                gapExtensionPenalty = scoring.getGapExtensionPenalty(),
                gapOpenPenalty = scoring.getGapOpenPenalty() - gapExtensionPenalty;

        int i, j;
        for (i = 1; i < size1; ++i) {
            matrix.set(i, 0, gapOpenPenalty + i * gapExtensionPenalty);
            gapIn2.set(i, 0, gapOpenPenalty + i * gapExtensionPenalty);
            gapIn1.set(i, 0, MIN_VALUE);

        }
        for (j = 1; j < size2; ++j) {
            matrix.set(0, j, gapOpenPenalty + j * gapExtensionPenalty);
            gapIn1.set(0, j, gapOpenPenalty + j * gapExtensionPenalty);
            gapIn2.set(0, j, MIN_VALUE);
        }

        matrix.set(0, 0, 0);
        gapIn1.set(0, 0, MIN_VALUE);
        gapIn2.set(0, 0, MIN_VALUE);

        for (i = 1; i <= length1; ++i) {
            for (j = 1; j <= length2; ++j) {
                gapIn1.set(i, j, max(
                        matrix.get(i, j - 1) + gapOpenPenalty + gapExtensionPenalty,
                        gapIn1.get(i, j - 1) + gapExtensionPenalty));

                gapIn2.set(i, j, max(
                        matrix.get(i - 1, j) + gapOpenPenalty + gapExtensionPenalty,
                        gapIn2.get(i - 1, j) + gapExtensionPenalty));

                matrix.set(i, j, max(
                        matrix.get(i - 1, j - 1) +
                                scoring.getScore(seq1.codeAt(i - 1), seq2.codeAt(j - 1)),
                        gapIn2.get(i, j),
                        gapIn1.get(i, j)));
            }
        }

        i = length1;
        j = length2;

        MutationsBuilder<S> mutations = new MutationsBuilder<>(seq1.getAlphabet(), true);
        int score = matrix.get(length1, length2);
        boolean inGap1 = false, inGap2 = false;
        while (i > 0 || j > 0) {
            assert !inGap1 || !inGap2;
            if (!inGap2 && (inGap1 || (j > 0 && score == gapIn1.get(i, j)))) {
                inGap1 = false;
                if (score == gapIn1.get(i, j - 1) + gapExtensionPenalty) {
                    inGap1 = true;
                    score = gapIn1.get(i, j - 1);
                } else
                    score = matrix.get(i, j - 1);


                mutations.appendInsertion(i, seq2.codeAt(j - 1));
                j--;
            } else if (inGap2 || (i > 0 && score == gapIn2.get(i, j))) {
                inGap2 = false;
                if (score == gapIn2.get(i - 1, j) + gapExtensionPenalty) {
                    inGap2 = true;
                    score = gapIn2.get(i - 1, j);
                } else
                    score = matrix.get(i - 1, j);


                mutations.appendDeletion(i - 1, seq1.codeAt(i - 1));
                i--;
            } else if (i > 0 && j > 0
                    && score == matrix.get(i - 1, j - 1)
                    + scoring.getScore(seq1.codeAt(i - 1), seq2.codeAt(j - 1))) {
                score = matrix.get(i - 1, j - 1);
                if (seq1.codeAt(i - 1) != seq2.codeAt(j - 1))
                    mutations.appendSubstitution(i - 1, seq1.codeAt(i - 1), seq2.codeAt(j - 1));

                --i;
                --j;
            } else
                throw new RuntimeException();
        }

        return new Alignment<>(seq1, mutations.createAndDestroy(),
                new Range(0, seq1.size()), new Range(0, seq2.size()), matrix.get(length1, length2));
    }
311875
private static String getAttribute(String name, Element firstElement, Element secondElement) {
        String val = firstElement.getAttribute(name);
        if (val.length() == 0 && secondElement != null) {
            val = secondElement.getAttribute(name);
        }
        return val;
    }
669470
public final int compareTo(byte[] name2) {
    if (name == name2)
      return 0;
    int len1 = (name == null ? 0 : name.length);
    int len2 = (name2 == null ? 0 : name2.length);
    int n = Math.min(len1, len2);
    byte b1, b2;
    for (int i = 0; i < n; i++) {
      b1 = name[i];
      b2 = name2[i];
      if (b1 != b2)
        return b1 - b2;
    }
    return len1 - len2;
  }
455899
@Override
    public int compare(String o1, String o2) {
        if (C_ELEMENT_SYMBOL.equals(o1)) {
            if (C_ELEMENT_SYMBOL.equals(o2)) {
                return 0;
            } else {
                return -1;
            }
        } else if (H_ELEMENT_SYMBOL.equals(o1)) {
            if (C_ELEMENT_SYMBOL.equals(o2)) {
                return 1;
            } else if (H_ELEMENT_SYMBOL.equals(o2)) {
                return 0;
            } else {
                return -1;
            }
        } else {
            if (C_ELEMENT_SYMBOL.equals(o2) || H_ELEMENT_SYMBOL.equals(o2)) {
                return 1;
            } else {
                return ((String) o1).compareTo((String) o2);
            }
        }
    }
642498
public static void checkAssignability(Class<?> c1, Class<?> c2) {
		COMPARISON_TYPE ct1 = COMPARISON_TYPE.fromClass(c1);
		COMPARISON_TYPE ct2 = COMPARISON_TYPE.fromClass(c2);
		try {
			COMPARISON_TYPE.fromOperands(ct1, ct2);
		} catch (Exception e) {
			throw DBLogger.newUser("Cannot assign " + c2 + " to " + c1, e);
		}
	}
901570
def _sorter(n1,n2):
    ''''''

    i = cmp(n1.namespaceURI, n2.namespaceURI)
    if i: return i
    return cmp(n1.localName, n2.localName)