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 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;
        }