Example usage for java.util StringTokenizer countTokens

List of usage examples for java.util StringTokenizer countTokens

Introduction

In this page you can find the example usage for java.util StringTokenizer countTokens.

Prototype

public int countTokens() 

Source Link

Document

Calculates the number of times that this tokenizer's nextToken method can be called before it generates an exception.

Usage

From source file:com.silverpeas.workflowdesigner.control.WorkflowDesignerSessionController.java

/**
* Returns a list of comparison operators as configured in the properties,
*
* @param fNone if <code>true</code> the 'none' option shall be included
* @return an array of operators/*w w  w.j  a v  a 2s .  c  o  m*/
*/
public String[] retrieveOperators(boolean fNone) {
    StringTokenizer strtok = new StringTokenizer(getSettings().getString("operators"), ",");
    List<String> list = new ArrayList<String>(strtok.countTokens() + 1);

    if (fNone) {
        list.add("");
    }

    while (strtok.hasMoreTokens()) {
        list.add(strtok.nextToken());
    }

    return list.toArray(new String[list.size()]);
}

From source file:com.silverpeas.workflowdesigner.control.WorkflowDesignerSessionController.java

/**
* Returns the input displayer type codes as configured in the properties
*
* @return an array of codes//  w  w  w  .java2  s. c o  m
*/
public String[] retrieveDisplayerNames() {
    StringTokenizer strtok = new StringTokenizer(getSettings().getString("displayerNames"), ",");
    List<String> list = new ArrayList<String>(strtok.countTokens() + 1);
    list.add("");
    while (strtok.hasMoreTokens()) {
        list.add(strtok.nextToken());
    }
    return list.toArray(new String[list.size()]);
}

From source file:fs.MainWindow.java

public void Correlation() {
    try {//from  w ww . j  a  v a2  s.co m
        String features = JOptionPane.showInputDialog(
                "Select features" + " (columns) to calculate correlation coeficient:", "0 1 2");
        if (features != null) {
            StringTokenizer s = new StringTokenizer(features);
            int nrfeatures = s.countTokens();
            int[] selectedfeatures = new int[nrfeatures];
            for (int n = 0; n < nrfeatures; n++) {
                selectedfeatures[n] = Integer.valueOf(s.nextToken());
            }

            //correlation coeficient among classes or among features.
            if (jCB_HasLabels.isSelected()) {
                String[] titles = getClasses();
                GenerateTable(MathRoutines.getCorrelationCoeficientClasses(Mo, selectedfeatures),
                        "Correlation coeficients among classes", "Correlation coeficients among classes using "
                                + "the average values of the features: " + features,
                        titles);
            } else {
                String[] titles = new String[selectedfeatures.length];
                for (int i = 0; i < selectedfeatures.length; i++) {
                    titles[i] = String.valueOf(selectedfeatures[i]);
                }
                GenerateTable(MathRoutines.getCorrelationCoeficientFeatures(Mo, selectedfeatures),
                        "Correlation coeficients among features",
                        "Correlation coeficients among features: " + features, titles);
            }
        }
    } catch (Exception error) {
        throw new FSException("Error on select features to correlation" + " coeficient. " + error, false);
    }
}

From source file:com.silverpeas.workflowdesigner.control.WorkflowDesignerSessionController.java

/**
* Returns names of available languages as configured in the properties, localised for the current
* user/*  w  w w  .java  2s  .  c  o  m*/
*
* @param fDefault if <code>true</code> the 'default' option shall be included
* @return an array of language names
*/
public String[] retrieveLanguageNames(boolean fDefault) {
    StringTokenizer strtok = new StringTokenizer(getSettings().getString("languages"), ",");
    Locale locale = new Locale(getLanguage());
    List<String> list = new ArrayList<String>(strtok.countTokens() + 1);
    if (fDefault) {
        list.add(getString("workflowDesigner.default"));
    }
    while (strtok.hasMoreTokens()) {
        Locale inLocale = new Locale(strtok.nextToken());

        list.add(inLocale.getDisplayLanguage(locale));
    }
    return list.toArray(new String[list.size()]);
}

From source file:com.alkacon.opencms.formgenerator.CmsForm.java

/**
 * Initializes the field objects of the form.<p>
 * /*www . j a v  a2  s  .  c  o m*/
 * @param xPath the xPath of the input field to initialize
 * @param content the XML configuration content
 * @param jsp the initialized CmsJspActionElement to access the OpenCms API
 * @param locale the currently active Locale
 * @param messages the localized messages
 * @param fieldTexts the optional field texts
 * @param subFieldPaths the optional sub field xPaths
 * @param fileUploads the uploaded files
 * @param subFieldNameSuffix the suffix for the sub field name used to create the HTML code and request parameter names
 * @param initial if true, field values are filled with values specified in the XML configuration, otherwise values are read from the request
 * @param subField indicates if a sub field should be created
 * 
 * @return an initialized input field
 * 
 * @throws CmsConfigurationException if parsing the configuration fails 
 */
private I_CmsField createInputField(String xPath, CmsXmlContent content, CmsJspActionElement jsp, Locale locale,
        CmsMessages messages, Map<String, CmsFieldText> fieldTexts, Map<String, List<String>> subFieldPaths,
        Map<String, FileItem> fileUploads, String subFieldNameSuffix, boolean initial, boolean subField)
        throws CmsConfigurationException {

    CmsObject cms = jsp.getCmsObject();

    // create the xPath prefix
    String inputFieldPath = xPath + "/";

    // get the field from the factory for the specified type
    // important: we don't use getContentStringValue, since the path comes directly from the input field
    String stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDTYPE, locale);
    I_CmsField field = getField(stringValue);

    // get the field labels
    stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDLABEL, locale);

    String locLabel = getConfigurationValue(stringValue, "");
    String dbLabel = locLabel;
    boolean useDbLabel = false;
    int pos = locLabel.indexOf('|');
    if (pos > -1) {
        locLabel = locLabel.substring(0, pos);
        if ((pos + 1) < dbLabel.length()) {
            dbLabel = dbLabel.substring(pos + 1);
            useDbLabel = true;
        }
    }
    field.setLabel(locLabel);
    field.setDbLabel(dbLabel);

    // create the field name
    String fieldName = xPath;
    // cut off the XML content index ("[number]") 
    int indexStart = fieldName.lastIndexOf('[') + 1;
    String index = fieldName.substring(indexStart, fieldName.length() - 1);
    if (useDbLabel) {
        // set field name to db label
        fieldName = dbLabel;
        field.setName(fieldName);
    } else {
        // set the field name to generic value "InputField-number"
        // replace the index ("[number]") of the xmlcontent field by "-number":
        fieldName = new StringBuffer(fieldName.substring(0, indexStart - 1)).append('-').append(index)
                .toString();
        // cut off initial path all but the last path segments
        // (make sure there is a slash in the string first).
        fieldName = "/" + fieldName;
        int slashIndex = fieldName.lastIndexOf("/");
        fieldName = fieldName.substring(slashIndex + 1);
        field.setName(fieldName + subFieldNameSuffix);
    }

    // get the optional text that is shown below the field
    CmsFieldText fieldText = fieldTexts.get(dbLabel);
    if (fieldText != null) {
        field.setText(fieldText);
    }

    // get the optional subfields
    if (!subField) {
        List<String> subFieldPathList = subFieldPaths.get(dbLabel);
        if (subFieldPathList != null) {
            // there are sub fields defined for this input field
            for (Iterator<String> i = subFieldPathList.iterator(); i.hasNext();) {
                String subPath = i.next() + "/";
                String fieldValue = content.getStringValue(cms, subPath + NODE_VALUE, locale);
                if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(fieldValue)) {
                    // a field value is specified, add the sub fields for the value
                    String suffix = new StringBuffer("-").append(index).append("-")
                            .append(fieldValue.hashCode()).toString();
                    List<I_CmsXmlContentValue> fieldValues = content.getValues(subPath + NODE_INPUTFIELD,
                            locale);
                    for (Iterator<I_CmsXmlContentValue> k = fieldValues.iterator(); k.hasNext();) {
                        field.addSubField(fieldValue, createInputField(k.next().getPath(), content, jsp, locale,
                                messages, fieldTexts, subFieldPaths, fileUploads, suffix, initial, true));
                    }
                }
            }
        }
    } else {
        // mark this field as sub field
        field.setSubField(subField);
    }

    // get the field parameters
    stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDPARAMS, locale);
    field.setParameters(stringValue);

    // validation error message
    stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDERRORMESSAGE, locale);
    field.setErrorMessage(stringValue);

    // fill object members in case this is no hidden field
    if (!CmsHiddenField.class.isAssignableFrom(field.getClass())) {
        // get the field validation regular expression
        stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDVALIDATION, locale);
        if (CmsEmailField.class.isAssignableFrom(field.getClass()) && CmsStringUtil.isEmpty(stringValue)) {
            // set default email validation expression for confirmation email address input field
            field.setValidationExpression(CmsEmailField.VALIDATION_REGEX);
        } else {
            field.setValidationExpression(getConfigurationValue(stringValue, ""));
        }
        if (CmsFileUploadField.class.isAssignableFrom(field.getClass())) {
            if (fileUploads != null) {
                FileItem attachment = fileUploads.get(field.getName());
                if (attachment != null) {
                    ((CmsFileUploadField) field).setFileSize(attachment.get().length);
                }
            }
        }

        // get the field mandatory flag
        stringValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDMANDATORY, locale);
        boolean isMandatory = Boolean.valueOf(stringValue).booleanValue();
        field.setMandatory(isMandatory);
        if (isMandatory) {
            // set flag that determines if mandatory fields are present
            setHasMandatoryFields(true);
        }

        // special case by table fields 
        if (CmsTableField.class.isAssignableFrom(field.getClass())) {
            CmsTableField tableField = (CmsTableField) field;
            String fieldValue = content.getStringValue(

                    cms, inputFieldPath + NODE_FIELDDEFAULTVALUE, locale);
            tableField.parseDefault(fieldValue, m_parameterMap);
        }

        if (field.needsItems()) {
            // create items for checkboxes, radio buttons and selectboxes
            String fieldValue = content.getStringValue(

                    cms, inputFieldPath + NODE_FIELDDEFAULTVALUE, locale);
            if (CmsStringUtil.isNotEmpty(fieldValue)) {
                // get items from String 
                boolean showInRow = false;
                if (fieldValue.startsWith(MACRO_SHOW_ITEMS_IN_ROW)) {
                    showInRow = true;
                    fieldValue = fieldValue.substring(MACRO_SHOW_ITEMS_IN_ROW.length());
                }
                StringTokenizer T = new StringTokenizer(fieldValue, "|");
                List<CmsFieldItem> items = new ArrayList<CmsFieldItem>(T.countTokens());
                while (T.hasMoreTokens()) {
                    String part = T.nextToken();
                    // check pre selection of current item
                    boolean isPreselected = part.indexOf('*') != -1;
                    String value = "";
                    String label = "";
                    String selected = "";
                    int delimPos = part.indexOf(':');
                    if (delimPos != -1) {
                        // a special label text is given
                        value = part.substring(0, delimPos);
                        label = part.substring(delimPos + 1);
                    } else {
                        // no special label text present, use complete String
                        value = part;
                        label = value;
                    }

                    if (isPreselected) {
                        // remove preselected flag marker from Strings
                        value = CmsStringUtil.substitute(value, "*", "");
                        label = CmsStringUtil.substitute(label, "*", "");
                    }

                    if (initial) {
                        // only fill in values from configuration file if called initially
                        if (isPreselected) {
                            selected = Boolean.toString(true);
                        }
                    } else {
                        // get selected flag from request for current item
                        selected = readSelectedFromRequest(field, value);
                    }

                    // add new item object
                    items.add(new CmsFieldItem(value, label, Boolean.valueOf(selected).booleanValue(),
                            showInRow));

                }
                field.setItems(items);
            } else {
                // no items specified for checkbox, radio button or selectbox
                throw new CmsConfigurationException(Messages.get().container(
                        Messages.ERR_INIT_INPUT_FIELD_MISSING_ITEM_2, field.getName(), field.getType()));
            }
        }
    }
    // get the field value
    if (initial && CmsStringUtil.isEmpty(getParameter(field.getName()))
            && !CmsTableField.class.isAssignableFrom(field.getClass())) {
        // only fill in values from configuration file if called initially
        if (!field.needsItems()) {
            if (CmsDisplayField.class.isAssignableFrom(field.getClass())
                    || CmsHiddenDisplayField.class.isAssignableFrom(field.getClass())) {
                String fieldValue = getDynamicFieldValue((CmsDynamicField) field);
                field.setValue(fieldValue);
            } else {
                String fieldValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDDEFAULTVALUE,
                        locale);
                if (CmsStringUtil.isNotEmpty(fieldValue)) {
                    CmsMacroResolver resolver = CmsMacroResolver.newInstance().setCmsObject(cms)
                            .setJspPageContext(jsp.getJspContext());
                    fieldValue = resolver.resolveMacros(fieldValue);
                    field.setValue(fieldValue.trim());
                }
            }
        } else {
            // for field that needs items, 
            // the default value is used to set the items and not really a value
            field.setValue(null);
        }
    } else if (CmsFileUploadField.class.isAssignableFrom(field.getClass())) {
        // specific handling for file upload fields, because if they are filled out
        // they also shall be filled out if there are empty because there was an
        // other mandatory field not filled out or there was browsed through
        // different pages with the "prev" and the "next" buttons
        // here are also used hidden fields on the current page, that is why
        // it is possible that there are tow fields with the same name, one field
        // is the file upload field, the second one is the hidden field
        // the file upload field is the first one, the hidden field is the second one
        String[] parameterValues = m_parameterMap.get(field.getName());
        StringBuffer value = new StringBuffer();
        if (parameterValues != null) {
            if (parameterValues.length == 1) {
                // there file upload field value is empty, so take the hidden field value
                value.append(parameterValues[0]);
            } else {
                // there are two fields with the same name
                if (parameterValues[0].isEmpty()) {
                    // the file upload field is empty, so take the hidden field value
                    value.append(parameterValues[1]);
                } else {
                    // the file upload field is not empty, so take this value, because
                    // so the user choosed another file than before (in the hidden field)
                    value.append(parameterValues[0]);
                }
            }
        }
        field.setValue(value.toString());
    } else if (CmsDisplayField.class.isAssignableFrom(field.getClass())
            || CmsDisplayField.class.isAssignableFrom(field.getClass())) {
        String fieldValue = getDynamicFieldValue((CmsDynamicField) field);
        if (CmsStringUtil.isEmpty(fieldValue)) {
            // get field value from request for standard fields
            String[] parameterValues = m_parameterMap.get(field.getName());
            if (parameterValues != null) {
                fieldValue = parameterValues[0];
            }
        }
        field.setValue(fieldValue);
    } else if (CmsEmptyField.class.isAssignableFrom(field.getClass())) {
        String fieldValue = content.getStringValue(cms, inputFieldPath + NODE_FIELDDEFAULTVALUE, locale);
        field.setValue(fieldValue);
    } else if (!CmsTableField.class.isAssignableFrom(field.getClass())) {
        // get field value from request for standard fields
        String[] parameterValues = m_parameterMap.get(field.getName());
        StringBuffer value = new StringBuffer();
        if (parameterValues != null) {
            for (int j = 0; j < parameterValues.length; j++) {
                if (j != 0) {
                    value.append(", ");
                }
                value.append(parameterValues[j]);
            }
        }
        field.setValue(value.toString());
    }
    return field;
}

From source file:io.manasobi.utils.StringUtils.java

/**
 * ? ??  token?    arraylist  <br><br>
 *
 * StringUtils.getStringArray("Anyframe/Java/Test", "/")
 *
 * @param str ?/*from w w  w  .j ava 2 s.co  m*/
 * @param strToken  token
 * @return token?  ? arraylist
 */
public static String[] getStringArray(String str, String strToken) {
    if (str.indexOf(strToken) != -1) {
        StringTokenizer st = new StringTokenizer(str, strToken);
        String[] stringArray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++) {
            stringArray[i] = st.nextToken();
        }
        return stringArray;
    }
    return new String[] { str };
}

From source file:org.adl.validator.contentpackage.CPValidator.java

/**
 * This method retrieves the directory location of the test subject by
 * truncating the filename off of the URL passed in.
 * /*from   w w w . j  av a 2 s  . co  m*/
 * @param iFileName
 *            The absolute path of the test subject file
 * @return String - the directory that the file is located
 */
private String getPathOfFile(String iFileName) {
    mLogger.debug("CPValidator getPathOfFile()");

    String result = "";
    String tmp = "";

    try {
        StringTokenizer token = new StringTokenizer(iFileName, File.separator, true);

        int numTokens = token.countTokens();

        // We want all but the last token added
        numTokens--;

        for (int i = 0; i < numTokens; i++) {
            tmp = token.nextToken();

            mLogger.debug("token = " + tmp);

            result = result + tmp;
        }
    } catch (NullPointerException npe) {
        npe.printStackTrace();
    }

    mLogger.debug("CPValidator getPathOfFile()");

    return result;
}

From source file:net.pms.encoders.MEncoderVideo.java

@Override
public ProcessWrapper launchTranscode(DLNAResource dlna, DLNAMediaInfo media, OutputParams params)
        throws IOException {
    params.manageFastStart();/* w  ww.j  a  v  a 2 s  .  co m*/

    boolean avisynth = avisynth();

    final String filename = dlna.getSystemName();
    setAudioAndSubs(filename, media, params, configuration);
    String externalSubtitlesFileName = null;

    if (params.sid != null && params.sid.isExternal()) {
        if (params.sid.isExternalFileUtf16()) {
            // convert UTF-16 -> UTF-8
            File convertedSubtitles = new File(PMS.getConfiguration().getTempFolder(),
                    "utf8_" + params.sid.getExternalFile().getName());
            FileUtil.convertFileFromUtf16ToUtf8(params.sid.getExternalFile(), convertedSubtitles);
            externalSubtitlesFileName = ProcessUtil
                    .getShortFileNameIfWideChars(convertedSubtitles.getAbsolutePath());
        } else {
            externalSubtitlesFileName = ProcessUtil
                    .getShortFileNameIfWideChars(params.sid.getExternalFile().getAbsolutePath());
        }
    }

    InputFile newInput = new InputFile();
    newInput.setFilename(filename);
    newInput.setPush(params.stdin);

    dvd = false;

    if (media != null && media.getDvdtrack() > 0) {
        dvd = true;
    }

    ovccopy = false;
    pcm = false;
    ac3Remux = false;
    dtsRemux = false;
    wmv = false;

    int intOCW = 0;
    int intOCH = 0;

    try {
        intOCW = Integer.parseInt(configuration.getMencoderOverscanCompensationWidth());
    } catch (NumberFormatException e) {
        logger.error("Cannot parse configured MEncoder overscan compensation width: \"{}\"",
                configuration.getMencoderOverscanCompensationWidth());
    }

    try {
        intOCH = Integer.parseInt(configuration.getMencoderOverscanCompensationHeight());
    } catch (NumberFormatException e) {
        logger.error("Cannot parse configured MEncoder overscan compensation height: \"{}\"",
                configuration.getMencoderOverscanCompensationHeight());
    }

    if (params.sid == null && dvd && configuration.isMencoderRemuxMPEG2()
            && params.mediaRenderer.isMpeg2Supported()) {
        String expertOptions[] = getSpecificCodecOptions(configuration.getMencoderCodecSpecificConfig(), media,
                params, filename, externalSubtitlesFileName, configuration.isMencoderIntelligentSync(), false);

        boolean nomux = false;

        for (String s : expertOptions) {
            if (s.equals("-nomux")) {
                nomux = true;
            }
        }

        if (!nomux) {
            ovccopy = true;
        }
    }

    String vcodec = "mpeg2video";

    if (params.mediaRenderer.isTranscodeToWMV()) {
        wmv = true;
        vcodec = "wmv2"; // http://wiki.megaframe.org/wiki/Ubuntu_XBOX_360#MEncoder not usable in streaming
    }

    mpegts = params.mediaRenderer.isTranscodeToMPEGTSAC3();

    /*
     Disable AC-3 remux for stereo tracks with 384 kbits bitrate and PS3 renderer (PS3 FW bug?)
     TODO check new firmwares
     Commented out until we can find a way to detect when a video has an audio track that switches from 2 to 6 channels
     because MEncoder can't handle those files, which are very common these days.
    */
    // final boolean ps3_and_stereo_and_384_kbits = params.aid != null
    //   && (params.mediaRenderer.isPS3() && params.aid.getAudioProperties().getNumberOfChannels() == 2)
    //   && (params.aid.getBitRate() > 370000 && params.aid.getBitRate() < 400000);
    final boolean ps3_and_stereo_and_384_kbits = false;

    final boolean isTSMuxerVideoEngineEnabled = PMS.getConfiguration().getEnginesAsList()
            .contains(TsMuxeRVideo.ID);
    final boolean mencoderAC3RemuxAudioDelayBug = (params.aid != null)
            && (params.aid.getAudioProperties().getAudioDelay() != 0) && (params.timeseek == 0);
    if (!mencoderAC3RemuxAudioDelayBug && configuration.isAudioRemuxAC3() && params.aid != null
            && params.aid.isAC3() && !ps3_and_stereo_and_384_kbits && !avisynth()
            && params.mediaRenderer.isTranscodeToAC3()) {
        // AC3 remux takes priority
        ac3Remux = true;
    } else {
        // now check for DTS remux and LPCM streaming
        dtsRemux = isTSMuxerVideoEngineEnabled && configuration.isAudioEmbedDtsInPcm()
                && (!dvd || configuration.isMencoderRemuxMPEG2()) && params.aid != null && params.aid.isDTS()
                && !avisynth() && params.mediaRenderer.isDTSPlayable();
        pcm = isTSMuxerVideoEngineEnabled && configuration.isAudioUsePCM()
                && (!dvd || configuration.isMencoderRemuxMPEG2())
                // disable LPCM transcoding for MP4 container with non-H264 video as workaround for mencoder's A/V sync bug
                && !(media.getContainer().equals("mp4") && !media.getCodecV().equals("h264"))
                && params.aid != null
                && ((params.aid.isDTS() && params.aid.getAudioProperties().getNumberOfChannels() <= 6) || // disable 7.1 DTS-HD => LPCM because of channels mapping bug
                        params.aid.isLossless() || params.aid.isTrueHD()
                        || (!configuration.isMencoderUsePcmForHQAudioOnly() && (params.aid.isAC3()
                                || params.aid.isMP3() || params.aid.isAAC() || params.aid.isVorbis() ||
                                // disable WMA to LPCM transcoding because of mencoder's channel mapping bug
                                // (see CodecUtil.getMixerOutput)
                                // params.aid.isWMA() ||
                                params.aid.isMpegAudio())))
                && params.mediaRenderer.isLPCMPlayable();
    }

    if (dtsRemux || pcm) {
        params.losslessaudio = true;
        params.forceFps = media.getValidFps(false);
    }

    // mpeg2 remux still buggy with mencoder :\
    // TODO when we can still use it?
    ovccopy = false;

    if (pcm && avisynth()) {
        params.avidemux = true;
    }

    int channels;
    if (ac3Remux) {
        channels = params.aid.getAudioProperties().getNumberOfChannels(); // ac3 remux
    } else if (dtsRemux || wmv) {
        channels = 2;
    } else if (pcm) {
        channels = params.aid.getAudioProperties().getNumberOfChannels();
    } else {
        channels = configuration.getAudioChannelCount(); // 5.1 max for ac3 encoding
    }

    logger.trace("channels=" + channels);

    String add = "";
    String rendererMencoderOptions = params.mediaRenderer.getCustomMencoderOptions(); // default: empty string
    String globalMencoderOptions = configuration.getMencoderCustomOptions(); // default: empty string

    if (params.mediaRenderer.isPadVideoWithBlackBordersTo169AR()) {
        rendererMencoderOptions += " -vf softskip,expand=::::1:16/9:4";
    }

    String combinedCustomOptions = defaultString(globalMencoderOptions) + " "
            + defaultString(rendererMencoderOptions);

    if (!combinedCustomOptions.contains("-lavdopts")) {
        add = " -lavdopts debug=0";
    }

    if (isNotBlank(rendererMencoderOptions)) {
        // don't use the renderer-specific options if they break DVD streaming
        // XXX we should weed out the unused/unwanted settings and keep the rest
        // (see sanitizeArgs()) rather than ignoring the options entirely
        if (dvd && rendererMencoderOptions.contains("expand=")) {
            logger.warn("renderer MEncoder options are incompatible with DVD streaming; ignoring: "
                    + rendererMencoderOptions);
            rendererMencoderOptions = null;
        }
    }

    StringTokenizer st = new StringTokenizer(
            "-channels " + channels + (isNotBlank(globalMencoderOptions) ? " " + globalMencoderOptions : "")
                    + (isNotBlank(rendererMencoderOptions) ? " " + rendererMencoderOptions : "") + add,
            " ");

    // XXX why does this field (which is used to populate the array returned by args(),
    // called below) store the renderer-specific (i.e. not global) MEncoder options?
    overriddenMainArgs = new String[st.countTokens()];

    {
        int nThreads = (dvd || filename.toLowerCase().endsWith("dvr-ms")) ? 1
                : configuration.getMencoderMaxThreads();
        boolean handleToken = false;
        int i = 0;

        while (st.hasMoreTokens()) {
            String token = st.nextToken().trim();

            if (handleToken) {
                token += ":threads=" + nThreads;

                if (configuration.getSkipLoopFilterEnabled() && !avisynth()) {
                    token += ":skiploopfilter=all";
                }

                handleToken = false;
            }

            if (token.toLowerCase().contains("lavdopts")) {
                handleToken = true;
            }

            overriddenMainArgs[i++] = token;
        }
    }

    if (configuration.getMPEG2MainSettings() != null) {
        String mpeg2Options = configuration.getMPEG2MainSettings();
        String mpeg2OptionsRenderer = params.mediaRenderer.getCustomMEncoderMPEG2Options();

        // Renderer settings take priority over user settings
        if (isNotBlank(mpeg2OptionsRenderer)) {
            mpeg2Options = mpeg2OptionsRenderer;
        } else {
            // Remove comment from the value
            if (mpeg2Options.contains("/*")) {
                mpeg2Options = mpeg2Options.substring(mpeg2Options.indexOf("/*"));
            }

            // Find out the maximum bandwidth we are supposed to use
            int defaultMaxBitrates[] = getVideoBitrateConfig(configuration.getMaximumBitrate());
            int rendererMaxBitrates[] = new int[2];

            if (params.mediaRenderer.getMaxVideoBitrate() != null) {
                rendererMaxBitrates = getVideoBitrateConfig(params.mediaRenderer.getMaxVideoBitrate());
            }

            if ((rendererMaxBitrates[0] > 0) && (rendererMaxBitrates[0] < defaultMaxBitrates[0])) {
                defaultMaxBitrates = rendererMaxBitrates;
            }

            int maximumBitrate = defaultMaxBitrates[0];

            // Determine a good quality setting based on video attributes
            if (mpeg2Options.contains("Automatic")) {
                mpeg2Options = "keyint=5:vqscale=1:vqmin=2:vqmax=3";

                // It has been reported that non-PS3 renderers prefer keyint 5 but prefer it for PS3 because it lowers the average bitrate
                if (params.mediaRenderer.isPS3()) {
                    mpeg2Options = "keyint=25:vqscale=1:vqmin=2:vqmax=3";
                }

                if (mpeg2Options.contains("Wireless") || maximumBitrate < 70) {
                    // Lower quality for 720p+ content
                    if (media.getWidth() > 1280) {
                        mpeg2Options = "keyint=25:vqmax=7:vqmin=2";
                    } else if (media.getWidth() > 720) {
                        mpeg2Options = "keyint=25:vqmax=5:vqmin=2";
                    }
                }
            }
        }

        // Ditlew - WDTV Live (+ other byte asking clients), CBR. This probably ought to be placed in addMaximumBitrateConstraints(..)
        int cbr_bitrate = params.mediaRenderer.getCBRVideoBitrate();
        String cbr_settings = (cbr_bitrate > 0)
                ? ":vrc_buf_size=5000:vrc_minrate=" + cbr_bitrate + ":vrc_maxrate=" + cbr_bitrate + ":vbitrate="
                        + ((cbr_bitrate > 16000) ? cbr_bitrate * 1000 : cbr_bitrate)
                : "";

        String encodeSettings = "-lavcopts autoaspect=1:vcodec=" + vcodec
                + (wmv && !params.mediaRenderer.isXBOX() ? ":acodec=wmav2:abitrate=448"
                        : (cbr_settings + ":acodec="
                                + (configuration.isMencoderAc3Fixed() ? "ac3_fixed" : "ac3") + ":abitrate="
                                + CodecUtil.getAC3Bitrate(configuration, params.aid)))
                + ":threads="
                + (wmv && !params.mediaRenderer.isXBOX() ? 1 : configuration.getMencoderMaxThreads())
                + ("".equals(mpeg2Options) ? "" : ":" + mpeg2Options);

        String audioType = "ac3";
        if (dtsRemux) {
            audioType = "dts";
        } else if (pcm) {
            audioType = "pcm";
        }

        encodeSettings = addMaximumBitrateConstraints(encodeSettings, media, mpeg2Options, params.mediaRenderer,
                audioType);
        st = new StringTokenizer(encodeSettings, " ");

        {
            int i = overriddenMainArgs.length; // Old length
            overriddenMainArgs = Arrays.copyOf(overriddenMainArgs,
                    overriddenMainArgs.length + st.countTokens());

            while (st.hasMoreTokens()) {
                overriddenMainArgs[i++] = st.nextToken();
            }
        }
    }

    boolean foundNoassParam = false;

    if (media != null) {
        String expertOptions[] = getSpecificCodecOptions(configuration.getMencoderCodecSpecificConfig(), media,
                params, filename, externalSubtitlesFileName, configuration.isMencoderIntelligentSync(), false);

        for (String s : expertOptions) {
            if (s.equals("-noass")) {
                foundNoassParam = true;
            }
        }
    }

    StringBuilder sb = new StringBuilder();
    // Set subtitles options
    if (!configuration.isDisableSubtitles() && !avisynth() && params.sid != null) {
        int subtitleMargin = 0;
        int userMargin = 0;

        // Use ASS flag (and therefore ASS font styles) for all subtitled files except vobsub, PGS and dvd
        boolean apply_ass_styling = params.sid.getType() != SubtitleType.VOBSUB
                && params.sid.getType() != SubtitleType.PGS && configuration.isMencoderAss() && // GUI: enable subtitles formating
                !foundNoassParam && // GUI: codec specific options
                !dvd;

        if (apply_ass_styling) {
            sb.append("-ass ");

            // GUI: Override ASS subtitles style if requested (always for SRT and TX3G subtitles)
            boolean override_ass_style = !configuration.isMencoderAssDefaultStyle()
                    || params.sid.getType() == SubtitleType.SUBRIP || params.sid.getType() == SubtitleType.TX3G;

            if (override_ass_style) {
                String assSubColor = "ffffff00";
                if (configuration.getSubsColor() != 0) {
                    assSubColor = Integer.toHexString(configuration.getSubsColor());
                    if (assSubColor.length() > 2) {
                        assSubColor = assSubColor.substring(2) + "00";
                    }
                }

                sb.append("-ass-color ").append(assSubColor)
                        .append(" -ass-border-color 00000000 -ass-font-scale ")
                        .append(configuration.getAssScale());

                // set subtitles font
                if (configuration.getFont() != null && configuration.getFont().length() > 0) {
                    // set font with -font option, workaround for
                    // https://github.com/Happy-Neko/ps3mediaserver/commit/52e62203ea12c40628de1869882994ce1065446a#commitcomment-990156 bug
                    sb.append(" -font ").append(configuration.getFont()).append(" ");
                    sb.append(" -ass-force-style FontName=").append(configuration.getFont()).append(",");
                } else {
                    String font = CodecUtil.getDefaultFontPath();
                    if (isNotBlank(font)) {
                        // Variable "font" contains a font path instead of a font name.
                        // Does "-ass-force-style" support font paths? In tests on OS X
                        // the font path is ignored (Outline, Shadow and MarginV are
                        // used, though) and the "-font" definition is used instead.
                        // See: https://github.com/ps3mediaserver/ps3mediaserver/pull/14
                        sb.append(" -font ").append(font).append(" ");
                        sb.append(" -ass-force-style FontName=").append(font).append(",");
                    } else {
                        sb.append(" -font Arial ");
                        sb.append(" -ass-force-style FontName=Arial,");
                    }
                }

                // Add to the subtitle margin if overscan compensation is being used
                // This keeps the subtitle text inside the frame instead of in the border
                if (intOCH > 0) {
                    subtitleMargin = (media.getHeight() / 100) * intOCH;
                }

                sb.append("Outline=").append(configuration.getAssOutline()).append(",Shadow=")
                        .append(configuration.getAssShadow());

                try {
                    userMargin = Integer.parseInt(configuration.getAssMargin());
                } catch (NumberFormatException n) {
                    logger.debug("Could not parse SSA margin from \"" + configuration.getAssMargin() + "\"");
                }

                subtitleMargin = subtitleMargin + userMargin;

                sb.append(",MarginV=").append(subtitleMargin).append(" ");
            } else if (intOCH > 0) {
                sb.append("-ass-force-style MarginV=").append(subtitleMargin).append(" ");
            }

            // MEncoder is not compiled with fontconfig on Mac OS X, therefore
            // use of the "-ass" option also requires the "-font" option.
            if (Platform.isMac() && sb.toString().indexOf(" -font ") < 0) {
                String font = CodecUtil.getDefaultFontPath();

                if (isNotBlank(font)) {
                    sb.append("-font ").append(font).append(" ");
                }
            }

            // Workaround for MPlayer #2041, remove when that bug is fixed
            if (!params.sid.isEmbedded()) {
                sb.append("-noflip-hebrew ");
            }
            // use PLAINTEXT formating
        } else {
            // set subtitles font
            if (configuration.getFont() != null && configuration.getFont().length() > 0) {
                sb.append(" -font ").append(configuration.getFont()).append(" ");
            } else {
                String font = CodecUtil.getDefaultFontPath();
                if (isNotBlank(font)) {
                    sb.append(" -font ").append(font).append(" ");
                }
            }

            sb.append(" -subfont-text-scale ").append(configuration.getMencoderNoAssScale());
            sb.append(" -subfont-outline ").append(configuration.getMencoderNoAssOutline());
            sb.append(" -subfont-blur ").append(configuration.getMencoderNoAssBlur());

            // Add to the subtitle margin if overscan compensation is being used
            // This keeps the subtitle text inside the frame instead of in the border
            if (intOCH > 0) {
                subtitleMargin = intOCH;
            }

            try {
                userMargin = Integer.parseInt(configuration.getMencoderNoAssSubPos());
            } catch (NumberFormatException n) {
                logger.debug("Could not parse subpos from \"" + configuration.getMencoderNoAssSubPos() + "\"");
            }

            subtitleMargin = subtitleMargin + userMargin;

            sb.append(" -subpos ").append(100 - subtitleMargin).append(" ");
        }

        // Common subtitle options

        // MEncoder on Mac OS X is compiled without fontconfig support.
        // Appending the flag will break execution, so skip it on Mac OS X.
        if (!Platform.isMac()) {
            // Use fontconfig if enabled
            sb.append("-").append(configuration.isMencoderFontConfig() ? "" : "no").append("fontconfig ");
        }
        // Apply DVD/VOBSUB subtitle quality
        if (params.sid.getType() == SubtitleType.VOBSUB
                && configuration.getMencoderVobsubSubtitleQuality() != null) {
            String subtitleQuality = configuration.getMencoderVobsubSubtitleQuality();

            sb.append("-spuaa ").append(subtitleQuality).append(" ");
        }

        // external subtitles file
        if (params.sid.isExternal()) {
            if (!params.sid.isExternalFileUtf()) {
                String subcp = null;

                // append -subcp option for non UTF external subtitles
                if (isNotBlank(configuration.getSubtitlesCodepage())) {
                    // manual setting
                    subcp = configuration.getSubtitlesCodepage();
                } else if (isNotBlank(SubtitleUtils.getSubCpOptionForMencoder(params.sid))) {
                    // autodetect charset (blank mencoder_subcp config option)
                    subcp = SubtitleUtils.getSubCpOptionForMencoder(params.sid);
                }

                if (isNotBlank(subcp)) {
                    sb.append("-subcp ").append(subcp).append(" ");
                    if (configuration.isMencoderSubFribidi()) {
                        sb.append("-fribidi-charset ").append(subcp).append(" ");
                    }
                }
            }
        }
    }

    st = new StringTokenizer(sb.toString(), " ");

    {
        int i = overriddenMainArgs.length; // old length
        overriddenMainArgs = Arrays.copyOf(overriddenMainArgs, overriddenMainArgs.length + st.countTokens());
        boolean handleToken = false;

        while (st.hasMoreTokens()) {
            String s = st.nextToken();

            if (handleToken) {
                s = "-quiet";
                handleToken = false;
            }

            if ((!configuration.isMencoderAss() || dvd) && s.contains("-ass")) {
                s = "-quiet";
                handleToken = true;
            }

            overriddenMainArgs[i++] = s;
        }
    }

    List<String> cmdList = new ArrayList<String>();

    cmdList.add(executable());

    // timeseek
    // XXX -ss 0 is is included for parity with the old (cmdArray) code: it may be possible to omit it
    cmdList.add("-ss");
    cmdList.add((params.timeseek > 0) ? "" + params.timeseek : "0");

    if (dvd) {
        cmdList.add("-dvd-device");
    }

    // input filename
    if (avisynth && !filename.toLowerCase().endsWith(".iso")) {
        File avsFile = FFmpegAviSynthVideo.getAVSScript(filename, params.sid, params.fromFrame, params.toFrame);
        cmdList.add(ProcessUtil.getShortFileNameIfWideChars(avsFile.getAbsolutePath()));
    } else {
        if (params.stdin != null) {
            cmdList.add("-");
        } else {
            cmdList.add(filename);
        }
    }

    if (dvd) {
        cmdList.add("dvd://" + media.getDvdtrack());
    }

    for (String arg : args()) {
        if (arg.contains("format=mpeg2") && media.getAspect() != null && media.getValidAspect(true) != null) {
            cmdList.add(arg + ":vaspect=" + media.getValidAspect(true));
        } else {
            cmdList.add(arg);
        }
    }

    if (!dtsRemux && !pcm && !avisynth() && params.aid != null && media.getAudioTracksList().size() > 1) {
        cmdList.add("-aid");
        boolean lavf = false; // TODO Need to add support for LAVF demuxing
        cmdList.add("" + (lavf ? params.aid.getId() + 1 : params.aid.getId()));
    }

    /*
     * handle subtitles
     *
     * try to reconcile the fact that the handling of "Disable subtitles" is spread out
     * over net.pms.encoders.Player.setAudioAndSubs and here by setting both of MEncoder's "disable
     * subs" options if any of the internal conditions for disabling subtitles are met.
     */
    if (isDisableSubtitles(params)) {
        // Ensure that internal subtitles are not automatically loaded
        // MKV: in some circumstances, MEncoder automatically selects an internal sub unless we explicitly disable (internal) subtitles
        // http://www.ps3mediaserver.org/forum/viewtopic.php?f=14&t=15891
        cmdList.add("-nosub");
        // Ensure that external subtitles are not automatically loaded
        cmdList.add("-noautosub");
    } else {
        // note: isEmbedded() and isExternal() are mutually exclusive
        if (params.sid.isEmbedded()) { // internal (embedded) subs
            // Ensure that external subtitles are not automatically loaded
            cmdList.add("-noautosub");
            // Specify which internal subtitle we want
            cmdList.add("-sid");
            cmdList.add("" + params.sid.getId());
        } else if (externalSubtitlesFileName != null) { // external subtitles
            assert params.sid.isExternal(); // confirm the mutual exclusion

            // Ensure that internal subtitles are not automatically loaded
            cmdList.add("-nosub");

            if (params.sid.getType() == SubtitleType.VOBSUB) {
                cmdList.add("-vobsub");
                cmdList.add(externalSubtitlesFileName.substring(0, externalSubtitlesFileName.length() - 4));
                cmdList.add("-slang");
                cmdList.add("" + params.sid.getLang());
            } else {
                cmdList.add("-sub");
                cmdList.add(externalSubtitlesFileName.replace(",", "\\,")); // Commas in MEncoder separate multiple subtitle files

                if (params.sid.isExternalFileUtf()) {
                    // append -utf8 option for UTF-8 external subtitles
                    cmdList.add("-utf8");
                }
            }
        }
    }

    // -ofps
    String validFramerate = (media != null) ? media.getValidFps(true) : null; // optional input framerate: may be null
    String framerate = (validFramerate != null) ? validFramerate : "24000/1001"; // where a framerate is required, use the input framerate or 24000/1001
    String ofps = framerate;

    // optional -fps or -mc
    if (configuration.isMencoderForceFps()) {
        if (!configuration.isFix25FPSAvMismatch()) {
            cmdList.add("-fps");
            cmdList.add(framerate);
        } else if (validFramerate != null) { // XXX not sure why this "fix" requires the input to have a valid framerate, but that's the logic in the old (cmdArray) code
            cmdList.add("-mc");
            cmdList.add("0.005");
            ofps = "25";
        }
    }

    cmdList.add("-ofps");
    cmdList.add(ofps);

    /*
     * TODO: Move the following block up with the rest of the
     * subtitle stuff
     */
    // external subtitles file
    if (!configuration.isDisableSubtitles() && !avisynth() && params.sid != null && params.sid.isExternal()) {
        if (params.sid.getType() == SubtitleType.VOBSUB) {
            cmdList.add("-vobsub");
            cmdList.add(externalSubtitlesFileName.substring(0, externalSubtitlesFileName.length() - 4));
            cmdList.add("-slang");
            cmdList.add("" + params.sid.getLang());
        } else {
            cmdList.add("-sub");
            cmdList.add(externalSubtitlesFileName.replace(",", "\\,")); // Commas in MEncoder separate multiple subtitle files

            if (params.sid.isExternalFileUtf()) {
                // append -utf8 option for UTF-8 external subtitles
                cmdList.add("-utf8");
            }
        }
    }

    if (filename.toLowerCase().endsWith(".evo")) {
        cmdList.add("-psprobe");
        cmdList.add("10000");
    }

    boolean deinterlace = configuration.isMencoderYadif();

    // Check if the media renderer supports this resolution
    boolean isResolutionTooHighForRenderer = params.mediaRenderer.isVideoRescale() && media != null
            && ((media.getWidth() > params.mediaRenderer.getMaxVideoWidth())
                    || (media.getHeight() > params.mediaRenderer.getMaxVideoHeight()));

    // Video scaler and overscan compensation
    boolean scaleBool = isResolutionTooHighForRenderer
            || (configuration.isMencoderScaler()
                    && (configuration.getMencoderScaleX() != 0 || configuration.getMencoderScaleY() != 0))
            || (intOCW > 0 || intOCH > 0);

    if ((deinterlace || scaleBool) && !avisynth()) {
        StringBuilder vfValueOverscanPrepend = new StringBuilder();
        StringBuilder vfValueOverscanMiddle = new StringBuilder();
        StringBuilder vfValueVS = new StringBuilder();
        StringBuilder vfValueComplete = new StringBuilder();

        String deinterlaceComma = "";
        int scaleWidth = 0;
        int scaleHeight = 0;
        double rendererAspectRatio;

        // Set defaults
        if (media != null && media.getWidth() > 0 && media.getHeight() > 0) {
            scaleWidth = media.getWidth();
            scaleHeight = media.getHeight();
        }

        /*
         * Implement overscan compensation settings
         *
         * This feature takes into account aspect ratio,
         * making it less blunt than the Video Scaler option
         */
        if (intOCW > 0 || intOCH > 0) {
            int intOCWPixels = (media.getWidth() / 100) * intOCW;
            int intOCHPixels = (media.getHeight() / 100) * intOCH;

            scaleWidth = scaleWidth + intOCWPixels;
            scaleHeight = scaleHeight + intOCHPixels;

            // See if the video needs to be scaled down
            if (params.mediaRenderer.isVideoRescale() && ((scaleWidth > params.mediaRenderer.getMaxVideoWidth())
                    || (scaleHeight > params.mediaRenderer.getMaxVideoHeight()))) {
                double overscannedAspectRatio = scaleWidth / scaleHeight;
                rendererAspectRatio = params.mediaRenderer.getMaxVideoWidth()
                        / params.mediaRenderer.getMaxVideoHeight();

                if (overscannedAspectRatio > rendererAspectRatio) {
                    // Limit video by width
                    scaleWidth = params.mediaRenderer.getMaxVideoWidth();
                    scaleHeight = (int) Math
                            .round(params.mediaRenderer.getMaxVideoWidth() / overscannedAspectRatio);
                } else {
                    // Limit video by height
                    scaleWidth = (int) Math
                            .round(params.mediaRenderer.getMaxVideoHeight() * overscannedAspectRatio);
                    scaleHeight = params.mediaRenderer.getMaxVideoHeight();
                }
            }

            vfValueOverscanPrepend.append("softskip,expand=-").append(intOCWPixels).append(":-")
                    .append(intOCHPixels);
            vfValueOverscanMiddle.append(",scale=").append(scaleWidth).append(":").append(scaleHeight);
        }

        /*
         * Video Scaler and renderer-specific resolution-limiter
         */
        if (configuration.isMencoderScaler()) {
            // Use the manual, user-controlled scaler
            if (configuration.getMencoderScaleX() != 0) {
                if (configuration.getMencoderScaleX() <= params.mediaRenderer.getMaxVideoWidth()) {
                    scaleWidth = configuration.getMencoderScaleX();
                } else {
                    scaleWidth = params.mediaRenderer.getMaxVideoWidth();
                }
            }

            if (configuration.getMencoderScaleY() != 0) {
                if (configuration.getMencoderScaleY() <= params.mediaRenderer.getMaxVideoHeight()) {
                    scaleHeight = configuration.getMencoderScaleY();
                } else {
                    scaleHeight = params.mediaRenderer.getMaxVideoHeight();
                }
            }

            logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight
                    + ", your Video Scaler setting");

            vfValueVS.append("scale=").append(scaleWidth).append(":").append(scaleHeight);

            /*
             * The video resolution is too big for the renderer so we need to scale it down
             */
        } else if (media != null && media.getWidth() > 0 && media.getHeight() > 0
                && (media.getWidth() > params.mediaRenderer.getMaxVideoWidth()
                        || media.getHeight() > params.mediaRenderer.getMaxVideoHeight())) {
            double videoAspectRatio = (double) media.getWidth() / (double) media.getHeight();
            rendererAspectRatio = (double) params.mediaRenderer.getMaxVideoWidth()
                    / (double) params.mediaRenderer.getMaxVideoHeight();

            /*
             * First we deal with some exceptions, then if they are not matched we will
             * let the renderer limits work.
             *
             * This is so, for example, we can still define a maximum resolution of
             * 1920x1080 in the renderer config file but still support 1920x1088 when
             * it's needed, otherwise we would either resize 1088 to 1080, meaning the
             * ugly (unused) bottom 8 pixels would be displayed, or we would limit all
             * videos to 1088 causing the bottom 8 meaningful pixels to be cut off.
             */
            if (media.getWidth() == 3840 && media.getHeight() == 1080) {
                // Full-SBS
                scaleWidth = 1920;
                scaleHeight = 1080;
            } else if (media.getWidth() == 1920 && media.getHeight() == 2160) {
                // Full-OU
                scaleWidth = 1920;
                scaleHeight = 1080;
            } else if (media.getWidth() == 1920 && media.getHeight() == 1088) {
                // SAT capture
                scaleWidth = 1920;
                scaleHeight = 1088;
            } else {
                // Passed the exceptions, now we allow the renderer to define the limits
                if (videoAspectRatio > rendererAspectRatio) {
                    scaleWidth = params.mediaRenderer.getMaxVideoWidth();
                    scaleHeight = (int) Math.round(params.mediaRenderer.getMaxVideoWidth() / videoAspectRatio);
                } else {
                    scaleWidth = (int) Math.round(params.mediaRenderer.getMaxVideoHeight() * videoAspectRatio);
                    scaleHeight = params.mediaRenderer.getMaxVideoHeight();
                }
            }

            logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight
                    + ", the maximum your renderer supports");

            vfValueVS.append("scale=").append(scaleWidth).append(":").append(scaleHeight);
        }

        // Put the string together taking into account overscan compensation and video scaler
        if (intOCW > 0 || intOCH > 0) {
            vfValueComplete.append(vfValueOverscanPrepend).append(vfValueOverscanMiddle).append(",harddup");
            logger.info("Setting video resolution to: " + scaleWidth + "x" + scaleHeight
                    + ", to fit your overscan compensation");
        } else {
            vfValueComplete.append(vfValueVS);
        }

        if (deinterlace) {
            deinterlaceComma = ",";
        }

        String vfValue = (deinterlace ? "yadif" : "") + (scaleBool ? deinterlaceComma + vfValueComplete : "");

        if (isNotBlank(vfValue)) {
            cmdList.add("-vf");
            cmdList.add(vfValue);
        }
    }

    /*
     * The PS3 and possibly other renderers display videos incorrectly
     * if the dimensions aren't divisible by 4, so if that is the
     * case we scale it down to the nearest 4.
     * This fixes the long-time bug of videos displaying in black and
     * white with diagonal strips of colour, weird one.
     *
     * TODO: Integrate this with the other stuff so that "scale" only
     * ever appears once in the MEncoder CMD.
     */
    if (media != null && (media.getWidth() % 4 != 0) || media.getHeight() % 4 != 0) {
        int newWidth;
        int newHeight;

        newWidth = (media.getWidth() / 4) * 4;
        newHeight = (media.getHeight() / 4) * 4;

        cmdList.add("-vf");
        cmdList.add("softskip,expand=" + newWidth + ":" + newHeight);
    }

    if (configuration.getMencoderMT() && !avisynth && !dvd && !(startsWith(media.getCodecV(), "mpeg2"))) {
        cmdList.add("-lavdopts");
        cmdList.add("fast");
    }

    boolean disableMc0AndNoskip = false;

    // Process the options for this file in Transcoding Settings -> Mencoder -> Expert Settings: Codec-specific parameters
    // TODO this is better handled by a plugin with scripting support and will be removed
    if (media != null) {
        String expertOptions[] = getSpecificCodecOptions(configuration.getMencoderCodecSpecificConfig(), media,
                params, filename, externalSubtitlesFileName, configuration.isMencoderIntelligentSync(), false);

        // the parameters (expertOptions) are processed in 3 passes
        // 1) process expertOptions
        // 2) process cmdList
        // 3) append expertOptions to cmdList

        if (expertOptions != null && expertOptions.length > 0) {
            // remove this option (key) from the cmdList in pass 2.
            // if the boolean value is true, also remove the option's corresponding value
            Map<String, Boolean> removeCmdListOption = new HashMap<String, Boolean>();

            // if this option (key) is defined in cmdList, merge this string value into the
            // option's value in pass 2. the value is a string format template into which the
            // cmdList option value is injected
            Map<String, String> mergeCmdListOption = new HashMap<String, String>();

            // merges that are performed in pass 2 are logged in this map; the key (string) is
            // the option name and the value is a boolean indicating whether the option was merged
            // or not. the map is populated after pass 1 with the options from mergeCmdListOption
            // and all values initialised to false. if an option was merged, it is not appended
            // to cmdList
            Map<String, Boolean> mergedCmdListOption = new HashMap<String, Boolean>();

            // pass 1: process expertOptions
            for (int i = 0; i < expertOptions.length; ++i) {
                if (expertOptions[i].equals("-noass")) {
                    // remove -ass from cmdList in pass 2.
                    // -ass won't have been added in this method (getSpecificCodecOptions
                    // has been called multiple times above to check for -noass and -nomux)
                    // but it may have been added via the renderer or global MEncoder options.
                    // XXX: there are currently 10 other -ass options (-ass-color, -ass-border-color &c.).
                    // technically, they should all be removed...
                    removeCmdListOption.put("-ass", false); // false: option does not have a corresponding value
                    // remove -noass from expertOptions in pass 3
                    expertOptions[i] = REMOVE_OPTION;
                } else if (expertOptions[i].equals("-nomux")) {
                    expertOptions[i] = REMOVE_OPTION;
                } else if (expertOptions[i].equals("-mt")) {
                    // not an MEncoder option so remove it from exportOptions.
                    // multi-threaded MEncoder is used by default, so this is obsolete (TODO: Remove it from the description)
                    expertOptions[i] = REMOVE_OPTION;
                } else if (expertOptions[i].equals("-ofps")) {
                    // replace the cmdList version with the expertOptions version i.e. remove the former
                    removeCmdListOption.put("-ofps", true);
                    // skip (i.e. leave unchanged) the exportOptions value
                    ++i;
                } else if (expertOptions[i].equals("-fps")) {
                    removeCmdListOption.put("-fps", true);
                    ++i;
                } else if (expertOptions[i].equals("-ovc")) {
                    removeCmdListOption.put("-ovc", true);
                    ++i;
                } else if (expertOptions[i].equals("-channels")) {
                    removeCmdListOption.put("-channels", true);
                    ++i;
                } else if (expertOptions[i].equals("-oac")) {
                    removeCmdListOption.put("-oac", true);
                    ++i;
                } else if (expertOptions[i].equals("-quality")) {
                    // XXX like the old (cmdArray) code, this clobbers the old -lavcopts value
                    String lavcopts = String.format(
                            "autoaspect=1:vcodec=%s:acodec=%s:abitrate=%s:threads=%d:%s", vcodec,
                            (configuration.isMencoderAc3Fixed() ? "ac3_fixed" : "ac3"),
                            CodecUtil.getAC3Bitrate(configuration, params.aid),
                            configuration.getMencoderMaxThreads(), expertOptions[i + 1]);

                    // append bitrate-limiting options if configured
                    lavcopts = addMaximumBitrateConstraints(lavcopts, media, lavcopts, params.mediaRenderer,
                            "");

                    // a string format with no placeholders, so the cmdList option value is ignored.
                    // note: we protect "%" from being interpreted as a format by converting it to "%%",
                    // which is then turned back into "%" when the format is processed
                    mergeCmdListOption.put("-lavcopts", lavcopts.replace("%", "%%"));
                    // remove -quality <value>
                    expertOptions[i] = expertOptions[i + 1] = REMOVE_OPTION;
                    ++i;
                } else if (expertOptions[i].equals("-mpegopts")) {
                    mergeCmdListOption.put("-mpegopts", "%s:" + expertOptions[i + 1].replace("%", "%%"));
                    // merge if cmdList already contains -mpegopts, but don't append if it doesn't (parity with the old (cmdArray) version)
                    expertOptions[i] = expertOptions[i + 1] = REMOVE_OPTION;
                    ++i;
                } else if (expertOptions[i].equals("-vf")) {
                    mergeCmdListOption.put("-vf", "%s," + expertOptions[i + 1].replace("%", "%%"));
                    ++i;
                } else if (expertOptions[i].equals("-af")) {
                    mergeCmdListOption.put("-af", "%s," + expertOptions[i + 1].replace("%", "%%"));
                    ++i;
                } else if (expertOptions[i].equals("-nosync")) {
                    disableMc0AndNoskip = true;
                    expertOptions[i] = REMOVE_OPTION;
                } else if (expertOptions[i].equals("-mc")) {
                    disableMc0AndNoskip = true;
                }
            }

            for (String key : mergeCmdListOption.keySet()) {
                mergedCmdListOption.put(key, false);
            }

            // pass 2: process cmdList
            List<String> transformedCmdList = new ArrayList<String>();

            for (int i = 0; i < cmdList.size(); ++i) {
                String option = cmdList.get(i);

                // we remove an option by *not* adding it to transformedCmdList
                if (removeCmdListOption.containsKey(option)) {
                    if (isTrue(removeCmdListOption.get(option))) { // true: remove (i.e. don't add) the corresponding value
                        ++i;
                    }
                } else {
                    transformedCmdList.add(option);

                    if (mergeCmdListOption.containsKey(option)) {
                        String format = mergeCmdListOption.get(option);
                        String value = String.format(format, cmdList.get(i + 1));
                        // record the fact that an expertOption value has been merged into this cmdList value
                        mergedCmdListOption.put(option, true);
                        transformedCmdList.add(value);
                        ++i;
                    }
                }
            }

            cmdList = transformedCmdList;

            // pass 3: append expertOptions to cmdList
            for (int i = 0; i < expertOptions.length; ++i) {
                String option = expertOptions[i];

                if (option != REMOVE_OPTION) {
                    if (isTrue(mergedCmdListOption.get(option))) { // true: this option and its value have already been merged into existing cmdList options
                        ++i; // skip the value
                    } else {
                        cmdList.add(option);
                    }
                }
            }
        }
    }

    if ((pcm || dtsRemux || ac3Remux) || (configuration.isMencoderNoOutOfSync() && !disableMc0AndNoskip)) {
        if (configuration.isFix25FPSAvMismatch()) {
            cmdList.add("-mc");
            cmdList.add("0.005");
        } else {
            cmdList.add("-mc");
            cmdList.add("0");
            cmdList.add("-noskip");
        }
    }

    if (params.timeend > 0) {
        cmdList.add("-endpos");
        cmdList.add("" + params.timeend);
    }

    String rate = "48000";
    if (params.mediaRenderer.isXBOX()) {
        rate = "44100";
    }

    // force srate -> cause ac3's mencoder doesn't like anything other than 48khz
    if (media != null && !pcm && !dtsRemux && !ac3Remux) {
        cmdList.add("-af");
        cmdList.add("lavcresample=" + rate);
        cmdList.add("-srate");
        cmdList.add(rate);
    }

    // add a -cache option for piped media (e.g. rar/zip file entries):
    // https://code.google.com/p/ps3mediaserver/issues/detail?id=911
    if (params.stdin != null) {
        cmdList.add("-cache");
        cmdList.add("8192");
    }

    PipeProcess pipe = null;

    ProcessWrapperImpl pw = null;

    if (pcm || dtsRemux) {
        // transcode video, demux audio, remux with tsmuxer
        boolean channels_filter_present = false;

        for (String s : cmdList) {
            if (isNotBlank(s) && s.startsWith("channels")) {
                channels_filter_present = true;
                break;
            }
        }

        if (params.avidemux) {
            pipe = new PipeProcess("mencoder" + System.currentTimeMillis(),
                    (pcm || dtsRemux || ac3Remux) ? null : params);
            params.input_pipes[0] = pipe;

            cmdList.add("-o");
            cmdList.add(pipe.getInputPipe());

            if (pcm && !channels_filter_present && params.aid != null) {
                String mixer = getLPCMChannelMappingForMencoder(params.aid);
                if (isNotBlank(mixer)) {
                    cmdList.add("-af");
                    cmdList.add(mixer);
                }
            }

            String[] cmdArray = new String[cmdList.size()];
            cmdList.toArray(cmdArray);
            pw = new ProcessWrapperImpl(cmdArray, params);

            PipeProcess videoPipe = new PipeProcess("videoPipe" + System.currentTimeMillis(), "out",
                    "reconnect");
            PipeProcess audioPipe = new PipeProcess("audioPipe" + System.currentTimeMillis(), "out",
                    "reconnect");

            ProcessWrapper videoPipeProcess = videoPipe.getPipeProcess();
            ProcessWrapper audioPipeProcess = audioPipe.getPipeProcess();

            params.output_pipes[0] = videoPipe;
            params.output_pipes[1] = audioPipe;

            pw.attachProcess(videoPipeProcess);
            pw.attachProcess(audioPipeProcess);
            videoPipeProcess.runInNewThread();
            audioPipeProcess.runInNewThread();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }
            videoPipe.deleteLater();
            audioPipe.deleteLater();
        } else {
            // remove the -oac switch, otherwise the "too many video packets" errors appear again
            for (ListIterator<String> it = cmdList.listIterator(); it.hasNext();) {
                String option = it.next();

                if (option.equals("-oac")) {
                    it.set("-nosound");

                    if (it.hasNext()) {
                        it.next();
                        it.remove();
                    }

                    break;
                }
            }

            pipe = new PipeProcess(System.currentTimeMillis() + "tsmuxerout.ts");

            TsMuxeRVideo ts = new TsMuxeRVideo(configuration);
            File f = new File(configuration.getTempFolder(), "pms-tsmuxer.meta");
            String cmd[] = new String[] { ts.executable(), f.getAbsolutePath(), pipe.getInputPipe() };
            pw = new ProcessWrapperImpl(cmd, params);

            PipeIPCProcess ffVideoPipe = new PipeIPCProcess(System.currentTimeMillis() + "ffmpegvideo",
                    System.currentTimeMillis() + "videoout", false, true);

            cmdList.add("-o");
            cmdList.add(ffVideoPipe.getInputPipe());

            OutputParams ffparams = new OutputParams(configuration);
            ffparams.maxBufferSize = 1;
            ffparams.stdin = params.stdin;

            String[] cmdArray = new String[cmdList.size()];
            cmdList.toArray(cmdArray);
            ProcessWrapperImpl ffVideo = new ProcessWrapperImpl(cmdArray, ffparams);

            ProcessWrapper ff_video_pipe_process = ffVideoPipe.getPipeProcess();
            pw.attachProcess(ff_video_pipe_process);
            ff_video_pipe_process.runInNewThread();
            ffVideoPipe.deleteLater();

            pw.attachProcess(ffVideo);
            ffVideo.runInNewThread();

            String aid = null;
            if (media != null && media.getAudioTracksList().size() > 1 && params.aid != null) {
                if (media.getContainer() != null && (media.getContainer().equals(FormatConfiguration.AVI)
                        || media.getContainer().equals(FormatConfiguration.FLV))) {
                    // TODO confirm (MP4s, OGMs and MOVs already tested: first aid is 0; AVIs: first aid is 1)
                    // for AVIs, FLVs and MOVs mencoder starts audio tracks numbering from 1
                    aid = "" + (params.aid.getId() + 1);
                } else {
                    // everything else from 0
                    aid = "" + params.aid.getId();
                }
            }

            PipeIPCProcess ffAudioPipe = new PipeIPCProcess(System.currentTimeMillis() + "ffmpegaudio01",
                    System.currentTimeMillis() + "audioout", false, true);
            StreamModifier sm = new StreamModifier();
            sm.setPcm(pcm);
            sm.setDtsEmbed(dtsRemux);
            sm.setSampleFrequency(48000);
            sm.setBitsPerSample(16);

            String mixer = null;
            if (pcm && !dtsRemux) {
                mixer = getLPCMChannelMappingForMencoder(params.aid); // LPCM always outputs 5.1/7.1 for multichannel tracks. Downmix with player if needed!
            }

            sm.setNbChannels(channels);

            // it seems the -really-quiet prevents mencoder to stop the pipe output after some time...
            // -mc 0.1 make the DTS-HD extraction works better with latest mencoder builds, and makes no impact on the regular DTS one
            String ffmpegLPCMextract[] = new String[] { executable(), "-ss", "0", filename, "-really-quiet",
                    "-msglevel", "statusline=2", "-channels", "" + channels, "-ovc", "copy", "-of", "rawaudio",
                    "-mc", dtsRemux ? "0.1" : "0", "-noskip", (aid == null) ? "-quiet" : "-aid",
                    (aid == null) ? "-quiet" : aid, "-oac", (ac3Remux || dtsRemux) ? "copy" : "pcm",
                    (isNotBlank(mixer) && !channels_filter_present) ? "-af" : "-quiet",
                    (isNotBlank(mixer) && !channels_filter_present) ? mixer : "-quiet", "-srate", "48000", "-o",
                    ffAudioPipe.getInputPipe() };

            if (!params.mediaRenderer.isMuxDTSToMpeg()) { // no need to use the PCM trick when media renderer supports DTS
                ffAudioPipe.setModifier(sm);
            }

            if (media != null && media.getDvdtrack() > 0) {
                ffmpegLPCMextract[3] = "-dvd-device";
                ffmpegLPCMextract[4] = filename;
                ffmpegLPCMextract[5] = "dvd://" + media.getDvdtrack();
            } else if (params.stdin != null) {
                ffmpegLPCMextract[3] = "-";
            }

            if (filename.toLowerCase().endsWith(".evo")) {
                ffmpegLPCMextract[4] = "-psprobe";
                ffmpegLPCMextract[5] = "1000000";
            }

            if (params.timeseek > 0) {
                ffmpegLPCMextract[2] = "" + params.timeseek;
            }

            OutputParams ffaudioparams = new OutputParams(configuration);
            ffaudioparams.maxBufferSize = 1;
            ffaudioparams.stdin = params.stdin;
            ProcessWrapperImpl ffAudio = new ProcessWrapperImpl(ffmpegLPCMextract, ffaudioparams);

            params.stdin = null;

            PrintWriter pwMux = new PrintWriter(f);
            pwMux.println("MUXOPT --no-pcr-on-video-pid --no-asyncio --new-audio-pes --vbr --vbv-len=500");
            String videoType = "V_MPEG-2";

            if (params.no_videoencode && params.forceType != null) {
                videoType = params.forceType;
            }

            String fps = "";
            if (params.forceFps != null) {
                fps = "fps=" + params.forceFps + ", ";
            }

            String audioType;
            if (ac3Remux) {
                audioType = "A_AC3";
            } else if (dtsRemux) {
                if (params.mediaRenderer.isMuxDTSToMpeg()) {
                    //renderer can play proper DTS track
                    audioType = "A_DTS";
                } else {
                    // DTS padded in LPCM trick
                    audioType = "A_LPCM";
                }
            } else {
                // PCM
                audioType = "A_LPCM";
            }

            // mencoder bug (confirmed with mencoder r35003 + ffmpeg 0.11.1):
            // audio delay is ignored when playing from file start (-ss 0)
            // override with tsmuxer.meta setting
            String timeshift = "";
            if (mencoderAC3RemuxAudioDelayBug) {
                timeshift = "timeshift=" + params.aid.getAudioProperties().getAudioDelay() + "ms, ";
            }

            pwMux.println(videoType + ", \"" + ffVideoPipe.getOutputPipe() + "\", " + fps
                    + "level=4.1, insertSEI, contSPS, track=1");
            pwMux.println(audioType + ", \"" + ffAudioPipe.getOutputPipe() + "\", " + timeshift + "track=2");
            pwMux.close();

            ProcessWrapper pipe_process = pipe.getPipeProcess();
            pw.attachProcess(pipe_process);
            pipe_process.runInNewThread();

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }

            pipe.deleteLater();
            params.input_pipes[0] = pipe;

            ProcessWrapper ff_pipe_process = ffAudioPipe.getPipeProcess();
            pw.attachProcess(ff_pipe_process);
            ff_pipe_process.runInNewThread();

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }

            ffAudioPipe.deleteLater();
            pw.attachProcess(ffAudio);
            ffAudio.runInNewThread();
        }
    } else {
        boolean directpipe = Platform.isMac() || Platform.isFreeBSD();

        if (directpipe) {
            cmdList.add("-o");
            cmdList.add("-");
            cmdList.add("-really-quiet");
            cmdList.add("-msglevel");
            cmdList.add("statusline=2");
            params.input_pipes = new PipeProcess[2];
        } else {
            pipe = new PipeProcess("mencoder" + System.currentTimeMillis(), (pcm || dtsRemux) ? null : params);
            params.input_pipes[0] = pipe;
            cmdList.add("-o");
            cmdList.add(pipe.getInputPipe());
        }

        String[] cmdArray = new String[cmdList.size()];
        cmdList.toArray(cmdArray);

        cmdArray = finalizeTranscoderArgs(filename, dlna, media, params, cmdArray);

        pw = new ProcessWrapperImpl(cmdArray, params);

        if (!directpipe) {
            ProcessWrapper mkfifo_process = pipe.getPipeProcess();
            pw.attachProcess(mkfifo_process);
            mkfifo_process.runInNewThread();

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }

            pipe.deleteLater();
        }
    }

    pw.runInNewThread();

    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
    }

    return pw;
}

From source file:de.tor.tribes.ui.windows.TribeTribeAttackFrame.java

private void attackToBBAction() {
    try {/*  w  w  w.ja  v  a2s  . com*/
        List<Attack> attacks = getSelectedResults();
        if (attacks.isEmpty()) {
            showInfo("Keine Angriffe ausgewhlt", true);
            return;
        }
        boolean extended = (JOptionPaneHelper.showQuestionConfirmBox(jResultFrame,
                "Erweiterte BB-Codes verwenden (nur fr Forum und Notizen geeignet)?", "Erweiterter BB-Code",
                "Nein", "Ja") == JOptionPane.YES_OPTION);

        StringBuilder buffer = new StringBuilder();
        if (extended) {
            buffer.append("[u][size=12]Angriffsplan[/size][/u]\n\n");
        } else {
            buffer.append("[u]Angriffsplan[/u]\n\n");
        }

        buffer.append(new AttackListFormatter().formatElements(attacks, extended));

        if (extended) {
            buffer.append("\n[size=8]Erstellt am ");
            buffer.append(
                    new SimpleDateFormat("dd.MM.yy 'um' HH:mm:ss").format(Calendar.getInstance().getTime()));
            buffer.append(" mit DS Workbench ");
            buffer.append(Constants.VERSION).append(Constants.VERSION_ADDITION + "[/size]\n");
        } else {
            buffer.append("\nErstellt am ");
            buffer.append(
                    new SimpleDateFormat("dd.MM.yy 'um' HH:mm:ss").format(Calendar.getInstance().getTime()));
            buffer.append(" mit DS Workbench ");
            buffer.append(Constants.VERSION).append(Constants.VERSION_ADDITION + "\n");
        }

        String b = buffer.toString();
        StringTokenizer t = new StringTokenizer(b, "[");
        int cnt = t.countTokens();
        if (cnt > 1000) {
            if (JOptionPaneHelper.showQuestionConfirmBox(jResultFrame,
                    "Die ausgewhlten Angriffe bentigen mehr als 1000 BB-Codes\n"
                            + "und knnen daher im Spiel (Forum/IGM/Notizen) nicht auf einmal dargestellt werden.\nTrotzdem exportieren?",
                    "Zu viele BB-Codes", "Nein", "Ja") == JOptionPane.NO_OPTION) {
                return;
            }
        }

        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(b), null);
        showInfo("BB-Codes in Zwischenablage kopiert", true);
    } catch (Exception e) {
        logger.error("Failed to copy data to clipboard", e);
        showError("Fehler beim Kopieren in die Zwischenablage", true);
    }
}

From source file:com.l2jfree.gameserver.handler.admincommands.AdminEditNpc.java

@Override
public boolean useAdminCommand(String command, L2Player activeChar) {
    if (command.startsWith("admin_showShop ")) {
        String[] args = command.split(" ");
        if (args.length > 1)
            showShop(activeChar, Integer.parseInt(command.split(" ")[1]));
    } else if (command.startsWith("admin_showCustomShop ")) {
        String[] args = command.split(" ");
        if (args.length > 1)
            showCustomShop(activeChar, Integer.parseInt(command.split(" ")[1]));
    } else if (command.startsWith("admin_showShopList ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            showShopList(activeChar, Integer.parseInt(command.split(" ")[1]),
                    Integer.parseInt(command.split(" ")[2]));
    } else if (command.startsWith("admin_showCustomShopList ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            showCustomShopList(activeChar, Integer.parseInt(command.split(" ")[1]),
                    Integer.parseInt(command.split(" ")[2]));
    } else if (command.startsWith("admin_edit_npc ")) {
        try {//from  www  .j  a va2  s  .  c  o  m
            String[] commandSplit = command.split(" ");
            int npcId = Integer.parseInt(commandSplit[1]);
            int pageId = 1;

            try {
                pageId = Integer.parseInt(commandSplit[2]);
            } catch (Exception e) {
            }

            L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcId);
            Show_Npc_Property(activeChar, npc, pageId);
        } catch (Exception e) {
            activeChar.sendMessage("Wrong usage: //edit_npc <npcId> [<pageId>]");
        }
    } else if (command.startsWith("admin_load_npc")) {
        StringTokenizer st = new StringTokenizer(command);
        st.nextToken();
        int id = 0;
        try {
            id = Integer.parseInt(st.nextToken());
        } catch (Exception e) {
            activeChar.sendMessage("Usage: //load_npc <id>");
        }
        if (id > 0) {
            if (NpcTable.getInstance().reloadNpc(id))
                activeChar.sendMessage("Loaded NPC " + id);
            else
                activeChar.sendMessage("Error while loading NPC " + id);
        }
    } else if (command.startsWith("admin_show_droplist ")) {
        int npcId = 0;
        try {
            npcId = Integer.parseInt(command.substring(20).trim());
        } catch (Exception e) {
        }

        if (npcId > 0) {
            showNpcDropList(activeChar, npcId);
        } else {
            activeChar.sendMessage("Usage: //show_droplist <npc_id>");
        }
    } else if (command.startsWith("admin_addShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 1)
            addShopItem(activeChar, args);
    } else if (command.startsWith("admin_delShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            delShopItem(activeChar, args);
    } else if (command.startsWith("admin_editShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            editShopItem(activeChar, args);
    } else if (command.startsWith("admin_addCustomShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 1)
            addCustomShopItem(activeChar, args);
    } else if (command.startsWith("admin_delCustomShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            delCustomShopItem(activeChar, args);
    } else if (command.startsWith("admin_editCustomShopItem ")) {
        String[] args = command.split(" ");
        if (args.length > 2)
            editCustomShopItem(activeChar, args);
    } else if (command.startsWith("admin_save_npc ")) {
        try {
            save_npc_property(activeChar, command);
        } catch (StringIndexOutOfBoundsException e) {
        }
    } else if (command.startsWith("admin_show_skilllist_npc ")) // L2J_JP ADD
    {
        StringTokenizer st = new StringTokenizer(command.substring(25), " ");
        try {
            int npcId = -1;
            int page = 0;
            if (st.countTokens() <= 2) {
                if (st.hasMoreTokens())
                    npcId = Integer.parseInt(st.nextToken());
                if (st.hasMoreTokens())
                    page = Integer.parseInt(st.nextToken());
            }

            if (npcId > 0) {
                showNpcSkillList(activeChar, npcId, page);
            } else
                activeChar.sendMessage("Usage: //show_skilllist_npc <npc_id> <page>");
        } catch (Exception e) {
            activeChar.sendMessage("Usage: //show_skilllist_npc <npc_id> <page>");
        }
    } else if (command.startsWith("admin_edit_skill_npc ")) // L2J_JP ADD
    {
        int npcId = -1, skillId = -1;
        try {
            StringTokenizer st = new StringTokenizer(command.substring(21).trim(), " ");
            if (st.countTokens() == 2) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    skillId = Integer.parseInt(st.nextToken());
                    showNpcSkillEdit(activeChar, npcId, skillId);
                } catch (Exception e) {
                }
            } else if (st.countTokens() == 3) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    skillId = Integer.parseInt(st.nextToken());
                    int level = Integer.parseInt(st.nextToken());

                    updateNpcSkillData(activeChar, npcId, skillId, level);
                } catch (Exception e) {
                    _log.warn("admin_edit_skill_npc parements error: " + command);
                }
            } else {
                activeChar.sendMessage("Usage: //edit_skill_npc <npc_id> <item_id> [<level>]");
            }
        } catch (StringIndexOutOfBoundsException e) {
            activeChar.sendMessage("Usage: //edit_skill_npc <npc_id> <item_id> [<level>]");
        }
    } else if (command.startsWith("admin_add_skill_npc ")) // L2J_JP ADD
    {
        int npcId = -1, skillId = -1;
        try {
            StringTokenizer st = new StringTokenizer(command.substring(20).trim(), " ");
            if (st.countTokens() == 1) {
                try {
                    String[] input = command.substring(20).split(" ");
                    if (input.length < 1)
                        return true;
                    npcId = Integer.parseInt(input[0]);
                } catch (Exception e) {
                }

                if (npcId > 0) {
                    L2NpcTemplate npcData = NpcTable.getInstance().getTemplate(npcId);
                    showNpcSkillAdd(activeChar, npcData);
                }
            } else if (st.countTokens() == 3) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    skillId = Integer.parseInt(st.nextToken());
                    int level = Integer.parseInt(st.nextToken());

                    addNpcSkillData(activeChar, npcId, skillId, level);
                } catch (Exception e) {
                    _log.warn("admin_add_skill_npc parements error: " + command);
                }
            } else {
                activeChar.sendMessage("Usage: //add_skill_npc <npc_id> [<level>]");
            }
        } catch (StringIndexOutOfBoundsException e) {
            activeChar.sendMessage("Usage: //add_skill_npc <npc_id> [<level>]");
        }
    } else if (command.startsWith("admin_del_skill_npc ")) // [L2J_JP ADD]
    {
        int npcId = -1, skillId = -1;
        try {
            String[] input = command.substring(20).split(" ");
            if (input.length >= 2) {
                npcId = Integer.parseInt(input[0]);
                skillId = Integer.parseInt(input[1]);
            }
        } catch (Exception e) {
        }

        if (npcId > 0) {
            deleteNpcSkillData(activeChar, npcId, skillId);
        } else {
            activeChar.sendMessage("Usage: //del_skill_npc <npc_id> <skill_id>");
        }
    } else if (command.startsWith("admin_edit_drop ")) {
        int npcId = -1, itemId = 0, category = -1000;
        try {
            StringTokenizer st = new StringTokenizer(command.substring(16).trim());
            if (st.countTokens() == 3) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    itemId = Integer.parseInt(st.nextToken());
                    category = Integer.parseInt(st.nextToken());
                    showEditDropData(activeChar, npcId, itemId, category);
                } catch (Exception e) {
                }
            } else if (st.countTokens() == 6) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    itemId = Integer.parseInt(st.nextToken());
                    category = Integer.parseInt(st.nextToken());
                    int min = Integer.parseInt(st.nextToken());
                    int max = Integer.parseInt(st.nextToken());
                    int chance = Integer.parseInt(st.nextToken());

                    updateDropData(activeChar, npcId, itemId, min, max, category, chance);
                } catch (Exception e) {
                    _log.debug("admin_edit_drop parements error: " + command);
                }
            } else
                activeChar
                        .sendMessage("Usage: //edit_drop <npc_id> <item_id> <category> [<min> <max> <chance>]");
        } catch (StringIndexOutOfBoundsException e) {
            activeChar.sendMessage("Usage: //edit_drop <npc_id> <item_id> <category> [<min> <max> <chance>]");
        }
    } else if (command.startsWith("admin_add_drop ")) {
        int npcId = -1;
        try {
            StringTokenizer st = new StringTokenizer(command.substring(15).trim());
            if (st.countTokens() == 1) {
                try {
                    String[] input = command.substring(15).split(" ");
                    if (input.length < 1)
                        return true;
                    npcId = Integer.parseInt(input[0]);
                } catch (Exception e) {
                }

                if (npcId > 0) {
                    L2NpcTemplate npcData = NpcTable.getInstance().getTemplate(npcId);
                    showAddDropData(activeChar, npcData);
                }
            } else if (st.countTokens() == 6) {
                try {
                    npcId = Integer.parseInt(st.nextToken());
                    int itemId = Integer.parseInt(st.nextToken());
                    int category = Integer.parseInt(st.nextToken());
                    int min = Integer.parseInt(st.nextToken());
                    int max = Integer.parseInt(st.nextToken());
                    int chance = Integer.parseInt(st.nextToken());

                    addDropData(activeChar, npcId, itemId, min, max, category, chance);
                } catch (Exception e) {
                    _log.debug("admin_add_drop parements error: " + command);
                }
            } else
                activeChar
                        .sendMessage("Usage: //add_drop <npc_id> [<item_id> <category> <min> <max> <chance>]");
        } catch (StringIndexOutOfBoundsException e) {
            activeChar.sendMessage("Usage: //add_drop <npc_id> [<item_id> <category> <min> <max> <chance>]");
        }
    } else if (command.startsWith("admin_del_drop ")) {
        int npcId = -1, itemId = -1, category = -1000;
        try {
            String[] input = command.substring(15).split(" ");
            if (input.length >= 3) {
                npcId = Integer.parseInt(input[0]);
                itemId = Integer.parseInt(input[1]);
                category = Integer.parseInt(input[2]);
            }
        } catch (Exception e) {
        }

        if (npcId > 0)
            deleteDropData(activeChar, npcId, itemId, category);
        else
            activeChar.sendMessage("Usage: //del_drop <npc_id> <item_id> <category>");
    }
    return true;
}