private void checkSemiColon() {
    fAppendSemiColon = false;

    ITextRegion targetRegion = fContext.getTargetRegion();
    if (targetRegion != null
        && targetRegion.getType() != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
      // find trailing ":" or ";"
      // if ":" before ";" is found, add ";"
      RegionIterator iterator = fContext.getRegionIterator();
      IStructuredDocumentRegion container = iterator.getStructuredDocumentRegion();
      while (iterator.hasNext()) {
        ITextRegion region = iterator.next();
        if (iterator.getStructuredDocumentRegion() != container) {
          break;
        }
        if (region.getType() == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
          fAppendSemiColon = true;
          break;
        }
      }
      if (!fAppendSemiColon) {
        // second chance:
        // leading IStructuredDocumentRegion is not ";"
        IStructuredDocumentRegion nextStructuredDocumentRegion =
            CSSUtil.findNextSignificantNode(container);
        if (CSSUtil.getStructuredDocumentRegionType(nextStructuredDocumentRegion)
            != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
          fAppendSemiColon = true;
        }
      }
    }
  }
  private void addSemiColon(List candidates) {
    ICSSNode targetNode = fContext.getTargetNode();
    if (targetNode instanceof ICSSStyleDeclItem) {
      ICSSNode firstChild = targetNode.getFirstChild();
      if (firstChild == null) {
        return;
      }
      if (firstChild instanceof IndexedRegion) {
        int startOffset = ((IndexedRegion) firstChild).getStartOffset();
        if (fContext.getCursorPos() <= startOffset) {
          return;
        }
      }
    }

    boolean bAddCloser = false;

    ITextRegion targetRegion = fContext.getTargetRegion();
    if (targetRegion != null
        && targetRegion.getType() != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
      // find trailing ":" or ";"
      // if ":" before ";" is found, add ";"
      RegionIterator iterator = fContext.getRegionIterator();
      IStructuredDocumentRegion container = iterator.getStructuredDocumentRegion();
      while (iterator.hasNext()) {
        ITextRegion region = iterator.next();
        if (iterator.getStructuredDocumentRegion() != container) {
          break;
        }
        if (region.getType() == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
          bAddCloser = true;
          break;
        }
      }
      if (!bAddCloser) {
        // second chance:
        // leading IStructuredDocumentRegion is not ";"
        IStructuredDocumentRegion nextStructuredDocumentRegion =
            CSSUtil.findNextSignificantNode(container);
        if (CSSUtil.getStructuredDocumentRegionType(nextStructuredDocumentRegion)
            != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
          bAddCloser = true;
        }
      }
    }

    if (bAddCloser) {
      CSSCACandidate item = new CSSCACandidate();
      String text = fContext.getTextToReplace() + ";"; // $NON-NLS-1$
      item.setReplacementString(text);
      item.setCursorPosition(text.length());
      item.setDisplayString(";"); // $NON-NLS-1$
      item.setImageType(null);
      candidates.add(item);
    }
  }
 private CSSPrimitiveValueImpl createStringValue(String text, String type) {
   short valueType = getStringValueType(text, type);
   CSSPrimitiveValueImpl value = getCSSPrimitiveValue(valueType);
   if (value != null) {
     if (valueType == CSSPrimitiveValue.CSS_URI) {
       text = CSSUtil.extractUriContents(text);
     } else if (valueType == CSSPrimitiveValue.CSS_STRING) {
       text = CSSUtil.extractStringContents(text);
     }
     value.setValue(text);
   }
   return value;
 }
  CSSStyleDeclItemImpl setupDeclarationItem(IStructuredDocumentRegion flatNode) {
    if (flatNode == null) {
      return null;
    }
    if (!hasColonSeparator(flatNode)) {
      return null;
    }

    fParentRegion = flatNode;

    ITextRegionList nodeRegions = new TextRegionListImpl(flatNode.getRegions()); // make
    // copy
    CSSStyleDeclItemImpl newItem = createDeclarationItem(nodeRegions);
    if (newItem == null) {
      return null;
    }
    if (!fTempStructuredDocument && flatNode != null) {
      newItem.setRangeStructuredDocumentRegion(flatNode, flatNode);
    }

    CSSUtil.stripSurroundingSpace(nodeRegions);
    // Now, nodeRegions just has regions for value.
    setupValues(newItem, nodeRegions, null);
    return newItem;
  }
 private String getPropertyName(ITextRegionList nodeRegions) {
   ITextRegionList nameRegions = new TextRegionListImpl();
   String name = null;
   while (!nodeRegions.isEmpty()) {
     ITextRegion region = nodeRegions.remove(0);
     if (region == null) {
       continue;
     }
     String type = region.getType();
     if (type == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
       CSSUtil.stripSurroundingSpace(nameRegions);
       name = makeString(nameRegions);
       break;
     } else {
       nameRegions.add(region);
     }
   }
   return name;
 }
  private CSSPrimitiveValueImpl createPrimitiveValue(ITextRegionList regions) {
    CSSPrimitiveValueImpl value = null;
    CSSUtil.stripSurroundingSpace(regions);
    if (regions.isEmpty()) {
      return null;
    }
    ITextRegion region = regions.get(0);
    if (region == null) {
      return null;
    }
    String type = region.getType();
    if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) {
      String text = getText(region).toLowerCase();
      if (text.equals("rgb(")) { // $NON-NLS-1$
        value = createRgbValue(regions);
      } else if (text.equals("counter(")) { // $NON-NLS-1$
        value = createCounterValue(regions);
      } else if (text.equals("counters(")) { // $NON-NLS-1$
        value = createCountersValue(regions);
      } else if (text.equals("attr(")) { // $NON-NLS-1$
        value = createAttrValue(regions);
      } else if (text.equals("format(")) { // $NON-NLS-1$
        value = createFormatValue(regions);
      } else if (text.equals("local(")) { // $NON-NLS-1$
        value = createLocalValue(regions);
      } else if (text.equals("rect(")) { // $NON-NLS-1$
        value = createRectValue(regions);
      }
      if (value == null) {
        value = createStringValue(regions);
      }
    } else {
      value = createStringValue(regions);
    }

    if (!fTempStructuredDocument && value != null) {
      value.setRangeRegion(fParentRegion, regions.get(0), regions.get(regions.size() - 1));
    }

    return value;
  }
  private CSSPrimitiveValueImpl createLocalValue(ITextRegionList regions) {
    String funcName = getFunctionName(regions);
    if (funcName == null || !funcName.toLowerCase().equals("local")) { // $NON-NLS-1$
      return null;
    }
    String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_STRING};
    ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
    if (valueRegions.size() != 1) {
      return null;
    }

    CSSPrimitiveValueImpl value = getCSSPrimitiveValue(ICSSPrimitiveValue.CSS_LOCAL);
    if (value == null) {
      return null;
    }

    ITextRegion region = valueRegions.get(0);
    value.setValue(CSSUtil.extractStringContents(getText(region)));

    return value;
  }
  protected String decoratedRegion(CompoundRegion region, int type, CSSCleanupStrategy stgy) {
    if (isFormat()) return region.getText();

    Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();

    String text = null;
    if (!stgy.isFormatSource()) text = region.getFullText();
    else text = region.getText();

    String regionType = region.getType();
    if (regionType == CSSRegionContexts.CSS_URI
        || regionType == CSSRegionContexts.CSS_DECLARATION_VALUE_URI) {
      String uri = CSSLinkConverter.stripFunc(text);

      boolean prefIsUpper =
          preferences.getInt(CSSCorePreferenceNames.CASE_IDENTIFIER)
              == CSSCorePreferenceNames.UPPER;
      boolean upper =
          (type == 0)
              ? prefIsUpper
              : ((type == 1)
                  ? preferences.getInt(CSSCorePreferenceNames.CASE_PROPERTY_NAME)
                      == CSSCorePreferenceNames.UPPER
                  : preferences.getInt(CSSCorePreferenceNames.CASE_PROPERTY_VALUE)
                      == CSSCorePreferenceNames.UPPER);
      String func = text.substring(0, 4);
      if (isCleanup()) {
        upper =
            ((type == 0)
                    ? stgy.getIdentCase()
                    : ((type == 1) ? stgy.getPropNameCase() : stgy.getPropValueCase()))
                == CSSCleanupStrategy.UPPER;
        func =
            ((type == 0)
                        ? stgy.getIdentCase()
                        : ((type == 1) ? stgy.getPropNameCase() : stgy.getPropValueCase()))
                    == CSSCleanupStrategy.ASIS
                ? text.substring(0, 4)
                : (upper ? "URL(" : "url("); // $NON-NLS-2$//$NON-NLS-1$
      }
      if ((!isCleanup() && preferences.getBoolean(CSSCorePreferenceNames.FORMAT_QUOTE_IN_URI))
          || (isCleanup() && stgy.isQuoteValues())) {
        String quote = preferences.getString(CSSCorePreferenceNames.FORMAT_QUOTE);
        quote = CSSUtil.detectQuote(uri, quote);
        text = func + quote + uri + quote + ")"; // $NON-NLS-1$
      } else if (isCleanup() && !stgy.isQuoteValues()) {
        text = func + CSSLinkConverter.removeFunc(text) + ")"; // $NON-NLS-1$
      } else {
        text = func + uri + ")"; // $NON-NLS-1$
      }
    } else if (region.getType() == CSSRegionContexts.CSS_STRING
        && (!isCleanup() || stgy.isQuoteValues())) {
      String quote = preferences.getString(CSSCorePreferenceNames.FORMAT_QUOTE);
      // begginning
      if (!text.startsWith(quote)) {
        if (text.startsWith("\"") || text.startsWith("\'")) // $NON-NLS-1$ //$NON-NLS-2$
        text = quote + text.substring(1);
        else text = quote + text;
      }
      // ending
      if (!text.endsWith(quote)) {
        if (text.endsWith("\"") || text.endsWith("\'")) // $NON-NLS-1$ //$NON-NLS-2$
        text = text.substring(0, text.length() - 1) + quote;
        else text = text + quote;
      }
    }
    return text;
  }