public void incorporateData(WrapInfo wi)
 {
     foreach (WrapItem item in wi.mWrapItems)
     {
         if (!wi.isNewLevel())
             item.setDepth(mBaseLevel);
         mWrapItems.Add(item);
     }
     //mWrapItems.addAll(wi.mWrapItems);
 }
 private void findWrapItemsAndAdjustChildIndent(WrapInfo wi, WrapItem info, List<WrapItem> wrapItems) 
 {
     bool seenFirstItemAtDepth=false;
     for (int i=0;i<wi.mWrapItems.Count;i++)
     {
         WrapItem testItem = wi.mWrapItems[i];
         //only the same if the same type, depth, AND if the first parm pos is the same.  Otherwise, two arg lists at the same level would appear the same
         if (info.getBreakType()==testItem.getBreakType() && info.getDepth()==testItem.getDepth() && info.getFirstParmPos()==testItem.getFirstParmPos())
         {
             seenFirstItemAtDepth=true;
             wrapItems.Add(testItem);
         }
         else if (!testItem.isBreakUsed() && testItem.getDepth()>info.getDepth())
         {
             testItem.setIndent(info.getIndent()+getTabSize());
         }
         //quit if we have seen the first item at the proper scope and now we have 
         //unwound and seen the end of that item's scope
         if (seenFirstItemAtDepth && testItem.getDepth()<info.getDepth())
             break;
     }
 }
 private void addInternalSpaces(WrapInfo wi, List<WrapItem> wrapItems, int[] maxItemWidths) 
 {
     int itemsPerLine=maxItemWidths.Length;
     for (int i=0;i<wrapItems.Count;i++)
     {
         WrapItem item = wrapItems[i];
         if (item.isBreakUsed() && i>0)
         {
             int columnIndex=(i%itemsPerLine);
             if (columnIndex>0) //we don't want to add spaces after last column of items
             {
                 WrapItem previousItem = wrapItems[i-1];
                 int newSpaces=maxItemWidths[columnIndex-1]-(item.getNextItemPos()-previousItem.getNextItemPos());
                 if (newSpaces>0)
                 {
                     mOutputBuffer.Insert(item.getStartPos()+1, ASFormatter.generateIndent(newSpaces, false, 0));
                     wi.incrementPositions(item.getStartPos()+1, newSpaces);
                 }
             }
         }
     }
 }
        private void wrapArrayOrObjectItems(WrapInfo wi, List<WrapItem> wrapItems, WrapItem info, bool wrapFirstItem, bool wrapItemsAlignStart, bool isArray) 
        {
            wrapItems.Clear();
        
            //we're taking over wrapping, so now we need to figure out where all the items are going to
            //go
    //      wrappingFirstParm=mWrapFirstObjectItem;
            //put in entry for first item to make things easier for alignment code and if the
            //first item needs to be wrapped.
            WrapItem firstItem=new WrapItem(null, info.getDepth(), info.getFirstParmPos(), info.getBreakType(), true, info.getIndent());
            firstItem.setNextItemPos(info.getFirstParmPos());
            wrapItems.Add(firstItem);
            int alignmentOffset=updateEarlyWrapPoint(firstItem, isArray);
        
            int itemIndent=info.getIndent();
            if ((!wrapFirstItem || isFirstItemOnLine(firstItem.getStartPos())) && info.getFirstParmPos()>0)
            {
                itemIndent=getColumnForPosition(firstItem.getStartPos());
                wrapFirstItem=false;
            }

    //      itemIndent-=alignmentOffset; //to adjust for the open brace/bracket and spaces
    //      if (!wrapFirstItem)
    //          itemIndent=getColumnForPosition(firstItem.getStartPos());
        
            findWrapItemsAndAdjustChildIndent(wi, info, wrapItems);
        
            //find the first text pos for each item
            foreach (WrapItem item in wrapItems) 
            {
                if (item.getNextItemPos()<0)
                {
                    //update item pos by finding the next non-whitespace char after the comma pos
                    int location=item.getStartPos()+1;
                    for (;location<mOutputBuffer.Length;location++)
                    {
                        if (!AntlrUtilities.isASWhitespace(mOutputBuffer[location]))
                            break;
                    }
                    item.setNextItemPos(location);
                }
            }                       
        
    //      if (mWrapObjectItemsPerLine>0) //predetermined how many to do per line (usually one)
    //      {
    //          //remove items that aren't used, and mark them 'used' so that they won't break again
    //          
    //          int[] maxItemWidths=new int[mWrapObjectItemsPerLine];
    //          findMaxItemWidths(wrapItems, maxItemWidths);
    //          setUsedItems(wrapItems, itemIndent, itemsPerLine);
    //          
    //          //determine (and add) extra spaces before removing items from list
    //          if (mWrapObjectItemsAlignStart)
    //          {
    //              addInternalSpaces(wi, wrapItems, maxItemWidths);                    
    //          }
    //          
    //          //remove items that won't receive breaks
    //          removeUsedItems(wrapItems);
    //      }
    //      else
            {
                if (wrapItemsAlignStart)
                {
                    if (wrapFirstItem && !isFirstItemOnLine(firstItem.getStartPos()))
                    {
                    }
                    else
                    {
                        firstItem.setBreakUsed(true);
                    }
                

                    //start with max items, then work down as I find a line that's tool long 
                    //because of the aligned columns.
                    int itemsPerLine=wrapItems.Count;
                
                    //decrement itemsPerLine as we try to find a fit
                    int[] maxItemWidths=new int[itemsPerLine];
                    while (itemsPerLine>1)
                    {
                        //find the max widths of items based on the given items per line
                        maxItemWidths=new int[itemsPerLine];
                        findMaxItemWidths(wrapItems, maxItemWidths);
                    
                        //now, check the max widths and see if this number of items will work for all lines
                        int column=itemIndent;
                        for (int i=0;i<itemsPerLine;i++)
                        {
                            column+=maxItemWidths[i];
                        }
                        if (column<=mMaxLineLength)
                            break;
                    
                        itemsPerLine--;
                    }
                
                    //mark the items as 'used' if we're not going to have to break them further
                    setUsedItems(wrapItems, itemIndent, itemsPerLine, wrapFirstItem, wrapFirstItem ? alignmentOffset : 0);
                
                    //I've picked a correct number of items per line--now, increment the positions where necessary.
                    addInternalSpaces(wi, wrapItems, maxItemWidths);
                
                    //remove items that won't receive breaks
                    removeUsedItems(wrapItems);
                }
                else //just wrapping items to line length, no alignment
                {
                    //determine each wrap item and remove the others
                    int originalIndent=info.getIndent();
                    int currentIndent=itemIndent;
                    int currentItemStartPos=firstItem.getStartPos();
                    if (wrapFirstItem && firstItem.getAlternateFirstItemWrapPoint()>=0)
                        currentItemStartPos=firstItem.getAlternateFirstItemWrapPoint();
                    int itemsSinceLastWrap=0;
                    for (int i=0;i<wrapItems.Count;i++)
                    {
                        WrapItem item=wrapItems[i];
                        int nextStartPos = mOutputBuffer.ToString().IndexOf('\n', item.getStartPos());
                        if (nextStartPos<0)
                            nextStartPos=mOutputBuffer.Length;
                        if (i+1<wrapItems.Count)
                        {
                            WrapItem nextItem = wrapItems[i+1];
                            nextStartPos=nextItem.getStartPos();
                        }
                    
                        int testLength=nextStartPos-currentItemStartPos+currentIndent+1;
    //                  String testString=mOutputBuffer.Substring(currentItemStartPos, nextStartPos);
    //                  int testLength=currentIndent+getColumnLength(0, testString, 0, testString.Length);  
                        if (testLength>mMaxLineLength && itemsSinceLastWrap>0 && !isFirstItemOnLine(item.getStartPos()))
                        {
                            currentItemStartPos=item.getNextItemPos();
                            if (!info.isIndentToFirstParm()) //switch indent if we are not indenting to first item
                            {
                                currentIndent=originalIndent+alignmentOffset;
                            }
                            itemsSinceLastWrap=1;
                        }
                        else
                        {
                            if (i>0 || !wrapFirstItem || isFirstItemOnLine(item.getStartPos()))
                                item.setBreakUsed(true); //don't need to break here
                        
                            if (item.isBreakUsed() || i==0) //1st item is special because it doesn't matter if it's wrapped or not, it's still an item on the line
                                itemsSinceLastWrap++;
                            else
                                itemsSinceLastWrap=1; //to account for case where already on a line by itself
                        }
                    }
                
                    for (int i=1;i<wrapItems.Count;i++) //start at 1 to skip the first item
                    {
                        WrapItem item = wrapItems[i];
                        item.setIndent(originalIndent+alignmentOffset);
                    }
                
                    //remove items that won't receive breaks
                    removeUsedItems(wrapItems);
                }
            }
        }
        private int possiblyWrap(WrapInfo wi, WrapItem info, int infoIndex, int lineStart, String restOfText, int depth, bool forceWrap, int maxLineLength)
        {
            if (info.isBreakUsed())
                return -1;
            if ((depth<0 || (depth==info.mDepth)) && (forceWrap || (info.getBreakType() & getAdvancedWrappingElements())!=0) || info.getBreakType()==Break_XML_code)
            {
                //TODO: handle before/after calculation and processing
                int[] splitPointInfo=new int[2];
                findSplitPoint(info, restOfText, lineStart, splitPointInfo);
                int splitPoint=splitPointInfo[0];
                int lengthAtSplit=splitPointInfo[1];

                //TODO: need to split lines even if no split would satisfy the line length.  It appears as well that
                //my current algorithm should force a split if the alternative is not splitting at all.
                if (lengthAtSplit<=maxLineLength) // || wrapAllArgsOrParms || wrapAllObjectDef || wrapAllArrayDef)
                {
                    //at this point, we need to check to see if the current wrap point is for a comma in one of the special
                    //wrapping modes.  If so, we want to walk up to lower depths to find the highest level item of one of 
                    //these special wrap types.
                
                    bool wrapAllObjectDef=isWrapAllObject(info);
                    bool wrapAllArgsOrParms=isWrapAllArgsAndParms(info);
                    bool wrapAllArrayDef=isWrapAllArray(info);
    //              if (wrapAllArgsOrParms || wrapAllObjectDef || wrapAllArrayDef)
                    {
                        int workingDepth=info.getDepth();
                        WrapItem higherItem=info;
                        //search for higher level items further down the list
                        for (int i=infoIndex+1;i<wi.mWrapItems.Count;i++)
                        {
                            WrapItem testItem=wi.mWrapItems[i];
                            if (testItem.getDepth()<workingDepth)
                            {
                                workingDepth=testItem.getDepth();
                                if (!testItem.isBreakUsed())
                                {
                                    if (isWrapAllArgsAndParms(testItem) || isWrapAllObject(testItem) || isWrapAllArray(testItem))
                                    {
                                        higherItem=testItem;
                                    }
                                }
                            }
                        }
                    
                        if (higherItem!=info)
                        {
                            info=higherItem;
                            wrapAllObjectDef=isWrapAllObject(info);
                            wrapAllArgsOrParms=isWrapAllArgsAndParms(info);
                            wrapAllArrayDef=isWrapAllArray(info);
                        
                        }
                    }
                
                    List<WrapItem> wrapItems=new List<WrapItem>();
                    wrapItems.Add(info);
                
                    int returnedInsertPos=(-1); //want to return the first insert pos if we split multiple args in this one pass, because within an arg, the line could violate the length.
                
                    //arg/parm wrapping (if all items are to be wrapped)
                    bool wrappingFirstParm=wrapAllArgsOrParms && ((mWrapFirstArgument && info.getCommaContextType()==Break_SubType_Arguments) ||
                            (mWrapFirstParameter && info.getCommaContextType()==Break_SubType_Parameters));
                    if (wrapAllArgsOrParms)
                    {
                        wrapItems.Clear();
                        if (wrappingFirstParm && info.getFirstParmPos()>=0)
                        {
                            WrapItem firstItem=new WrapItem(null, info.getDepth(), info.getFirstParmPos(), info.getBreakType(), true, info.getIndent());
                            wrapItems.Add(firstItem);
                        }
                        findWrapItemsAndAdjustChildIndent(wi, info, wrapItems);
                        returnedInsertPos=info.getFirstParmPos();
                    }
                
                    //////////////////////////////////////////////////////////////////////////////
                    //object item wrapping
                    //////////////////////////////////////////////////////////////////////////////
                    if (wrapAllObjectDef)
                    {
                        wrapArrayOrObjectItems(wi, wrapItems, info, mWrapFirstObjectItem, mWrapObjectItemsAlignStart, false);
                        returnedInsertPos=info.getFirstParmPos();
                    }

                    ///////////////////////////////////////////////////////////////////////////////
                    //array wrapping
                    ///////////////////////////////////////////////////////////////////////////////
                    if (wrapAllArrayDef)
                    {
                        wrapArrayOrObjectItems(wi, wrapItems, info, mWrapFirstArrayItem, mWrapArrayItemsAlignStart, true);
                        returnedInsertPos=info.getFirstParmPos();
                    }


                    foreach (WrapItem wrapItem in wrapItems) 
                    {
                        restOfText = mOutputBuffer.ToString().Substring(lineStart);
                        findSplitPoint(wrapItem, restOfText, lineStart, splitPointInfo);
                        splitPoint=splitPointInfo[0];
                        lengthAtSplit=splitPointInfo[1];
                    
                        int insertPos=splitPoint;
                        if (wrapItem.isBreakBefore())
                        {
                            //nothing to do.
                        }
                        else
                        {
                            //move the split point past the operator/split token
                            insertPos+=wrapItem.getText().Length;
                        }
                    
                        //remove whitespace at insert point, because we will be starting a new line
                        int loopSafety=0;
                        while (insertPos<mOutputBuffer.Length)
                        {
                            char testChar=mOutputBuffer[insertPos];
                            if (testChar==' ' || testChar=='\t')
                            {
                                mOutputBuffer.Remove(insertPos, insertPos+1);
                                wi.incrementPositions(insertPos, -1);
                            }
                            else
                                break;
                            if (loopSafety++ > 1000) //kick out if I seem to be stuck
                                break;
                        }
                    
                        //handle hanging indent
                        int indentAmount=wrapItem.getIndent();
                        if (wrapItem.getFirstParmPos()>=0 && wrapItem.isIndentToFirstParm() && !wrappingFirstParm)
                        {
                            indentAmount=getColumnForPosition(wrapItem.getFirstParmPos());
                        }
                        String indentWS=generateIndent(indentAmount);
                    
                        mOutputBuffer.Insert(insertPos, "\n"+indentWS);
                        wrapItem.setBreakUsed(true);
                    
                        //adjust other positions based on the characters we've inserted
                        wi.incrementPositions(insertPos+1, 1+indentWS.Length);
                    
                        if (returnedInsertPos<0)
                        {
                            //return the position just after the \n
                            returnedInsertPos=(insertPos+1);
                        }
                    }
                
                    return returnedInsertPos;
    //              return insertPos+1;
                }
            }
            return -1;
        }
 private int findWrapPoint(WrapInfo wi, int lineStart, int lineEnd, int depth, bool forceWrap, bool ignoreMax)
 {
     String restOfText = mOutputBuffer.ToString().Substring(lineStart);
     for (int i=wi.mWrapItems.Count-1;i>=0;i--)
     {
         WrapItem info=wi.mWrapItems[i];
         if (info.mStartPos<lineEnd && info.mStartPos>lineStart)
         {
             int nextLineIndex=possiblyWrap(wi, info, i, lineStart, restOfText, depth, forceWrap, getMaxLineLength());
             if (nextLineIndex>=0)
                 return nextLineIndex;
         }
     }
 
     {
         for (int i=0;i<wi.mWrapItems.Count;i++)
         {
             WrapItem info=wi.mWrapItems[i];
             if (info.mStartPos<lineEnd && info.mStartPos>lineStart)
             {
                 int nextLineIndex=possiblyWrap(wi, info, i, lineStart, restOfText, depth, forceWrap, ignoreMax ? Int32.MaxValue : getMaxLineLength()+getAdvancedWrappingGraceColumns());
                 if (nextLineIndex>=0)
                     return nextLineIndex;
             }               
         }
     }
 
     return -1;
 }