text:
import React, { Component } from 'react';
import { TreeNode } from './TreeNode'
import { StackViewerFilter } from './StackViewerFilter'
import { Link } from 'react-router-dom'
import base64url from 'base64url'
import './Callers.css';

export class Callers extends Component {
    static displayName = Callers.name;

    fetchData() {

        this.setState({ node: null, loading: true }); // HACK: Why is this required?

        fetch('/api/treenode?' + Callers.constructAPICacheKeyFromRouteKey(this.props.match.params.routeKey) + '&name=' + this.props.match.params.callTreeNodeId + '&subtree=' + this.props.match.params.subtree, { method: 'GET', headers: { 'Content-Type': 'application/json' } })
            .then(res => res.json())
            .then(data => {
                if (!this.ignoreLastFetch) {
                    data.hasChildren = true; // HACK: Because the api doesn't return this set true.
                    this.setState({ node: data, loading: false });
                }
        });
    }

    constructor(props) {
        super(props);
        this.state = { loading: true };
    }

    componentWillUnmount () {
        this.ignoreLastFetch = true
      }

    componentDidMount () {
        this.fetchData()
      }

    componentDidUpdate (prevProps) {
        let oldId = prevProps.match.params.callTreeNodeId
        let newId = this.props.match.params.callTreeNodeId
        if (newId !== oldId) {
            this.fetchData()
        }
    }

    static constructAPICacheKeyFromRouteKey(r) {
        var routeKey = JSON.parse(base64url.decode(r, "utf8"));
        return 'filename=' + routeKey.a + '&stackType=' + routeKey.b + '&pid=' + routeKey.c + '&start=' + base64url.encode(routeKey.d, "utf8") + '&end=' + base64url.encode(routeKey.e, "utf8") + '&groupPats=' + base64url.encode(routeKey.f, "utf8") + '&foldPats=' + base64url.encode(routeKey.g, "utf8") + '&incPats=' + base64url.encode(routeKey.h, "utf8") + '&excPats=' + base64url.encode(routeKey.i, "utf8") + '&foldPct=' + routeKey.j + '&drillIntoKey=' + routeKey.k;
    }

    static renderCallersTable(routeKey, callTreeNodeId, node) {
        return (

                        Name
                        Exclusive Metric %
                        Exclusive Count
                        Inclusive Metric %
                        Inclusive Count
                        Fold Count
                        When
                        First
                        Last

                    <TreeNode routeKey={routeKey} callTreeNodeId={callTreeNodeId} node={node} indent={0} />

        );
    }

    render() {
        let contents = this.state.loading ?
Loading...
 : Callers.renderCallersTable(this.props.match.params.routeKey, this.props.match.params.callTreeNodeId, this.state.node);

        return (

<Link to={`/ui/hotspots/${this.props.match.params.routeKey}`}>Hotspots</Link> >> Callers

                    <StackViewerFilter routeKey={this.props.match.params.routeKey}></StackViewerFilter>

                {contents}

        );
    }
}


text:
package com.telefonica.euro_iaas.commons.properties;

import java.io.Serializable;
import javax.persistence.Column;

/**
 * Primary key for a PropertyEntity.
 */
@SuppressWarnings("serial")
public class PersistentPropertyPK implements Serializable {

    public String namespace;

    @Column(name = "\"key\"")
    public String key;

    /**
     * @return the key
     */
    public String getKey() {
        return key;
    }

    /**
     * @param key
     *            the key to set
     */
    public void setKey(String key) {
        this.key = key;
    }

    /**
     * @return the namespace
     */
    public String getNamespace() {
        return namespace;
    }

    /**
     * @param namespace
     *            the namespace to set
     */
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((key == null) ? 0 : key.hashCode());
        result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PersistentPropertyPK other = (PersistentPropertyPK) obj;
        if (key == null) {
            if (other.key != null)
                return false;
        } else if (!key.equals(other.key))
            return false;
        if (namespace == null) {
            if (other.namespace != null)
                return false;
        } else if (!namespace.equals(other.namespace))
            return false;
        return true;
    }
}

redpajama_set_name: RedPajamaGithub


text:
package parser;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Any word that can be used by the {@link model.Player} to interact with the game.
 */
public class Word implements Serializable {
    private final Word thisWordInstance;
    private String word;
    private List<String> synonyms;
    private List<? extends Word> permittedWordClassesThatFollow;
    private final List<Word> permittedWordsThatFollow = new ArrayList<Word>() {
        @Override
        public void add(int index, Word word) {
            if (!thisWordInstance.isWordPermittedAsFollowingWord(word))
                throw new IllegalArgumentException("The word " + word.toString() + "is not permitted as a following word of " + thisWordInstance.toString());
            else
                super.add(index, word);
        }
    };

    public Word() {
        this(null);
    }

    public Word(String word) {
        this(word, null);
    }

    public Word(String word, List<String> synonyms) {
        this.word = word;
        this.synonyms = synonyms;
        thisWordInstance = this;
    }

    public String getWord() {
        return word;
    }

    @SuppressWarnings({"unused"})
    public void setWord(String word) {
        this.word = word;
    }

    public List<String> getSynonyms() {
        return synonyms;
    }

    @SuppressWarnings({"unused"})
    public void setSynonyms(List<String> synonyms) {
        this.synonyms = synonyms;
    }

    public List<? extends Word> getPermittedWordClassesThatFollow() {
        return permittedWordClassesThatFollow;
    }

    @SuppressWarnings({"unused"})
    public void setPermittedWordClassesThatFollow(List<? extends Word> permittedWordClassesThatFollow) {
        this.permittedWordClassesThatFollow = permittedWordClassesThatFollow;
    }

    public List<Word> getPermittedWordsThatFollow() {
        return permittedWordsThatFollow;
    }

    public boolean isWordPermittedAsFollowingWord(Word word) {
        //noinspection SuspiciousMethodCalls
        return this.getPermittedWordClassesThatFollow().contains(word.getClass()) && this.getPermittedWordsThatFollow().contains(word);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Word) {
            // obj is a word
            Word word = (Word) obj;

            if (!word.getWord().equals(this.getWord())) {
                return false;
            }
            if (!word.getSynonyms().equals(this.getSynonyms())) {
                return false;
            }
            if (!word.getPermittedWordClassesThatFollow().equals(this.getPermittedWordClassesThatFollow())) {
                return false;
            }
            if (!word.getPermittedWordsThatFollow().equals(this.getPermittedWordsThatFollow())) {
                return false;
            }

            // everything ok
            return true;

        } else {
            // Not the same class
            return false;
        }
    }

    @Override
    public String toString() {
        return this.getClass().getSimpleName() + "@" + this.getWord();
    }

    /**
     * Checks if {@code input} is equal to {@code this.}{@link #getWord()} or to one of the synonyms
     *
     * @param input The string to compare
     * @return {@code true} if {@code input} is equal to {@code this.}{@link #getWord()} or to one of the synonyms, {@code false} otherwise.
     */
    @SuppressWarnings({"unused"})
    public boolean equals(String input) {
        return (this.getWord().equals(input) || this.getSynonyms().contains(input));
    }
}


text:
package mcjty.rftools.blocks.storage.modules;

import mcjty.rftools.blocks.storage.sorters.CountItemSorter;
import mcjty.rftools.blocks.storage.sorters.ItemSorter;
import mcjty.rftools.blocks.storage.sorters.NameItemSorter;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;

public class DefaultTypeModule implements TypeModule {
    private List<ItemSorter> sorters = null;

    @Override
    public List<ItemSorter> getSorters() {
        if (sorters == null) {
            sorters = new ArrayList<>();
            sorters.add(new NameItemSorter());
            sorters.add(new CountItemSorter());
        }
        return sorters;
    }

    @Override
    public String getLongLabel(ItemStack stack) {
        return stack.getDisplayName();
    }

    @Override
    public String getShortLabel(ItemStack stack) {
        return stack.getDisplayName();
    }
}


text:
This sample app is a Node.js Web application for demonstrating the features of AT&T Enhanced WebRTC, and includes the following functionality:
* User management
* OAuth endpoint for Mobile Number authorization and callback
* Login and logout functionality for Virtual Number and Account ID users

## v1.0.0
December 7, 2014

* **New:** Step-by-step sample applications (Recipes) link in the main sample application.
This is a set of simple examples including code snippets. Just launch the main
NodeJS sample application and go to https://127.0.0.1:9001/recipes/

* **Features:**
  * RESTful API:
    * `/users` - User management
    * `/login` & `/logout` - Authentication (session management)
    * `/oauth/authorize` - Device authorization
    * `/oauth/callback` - Redirection to the sample app

### Known Issues

* Error Registering Users (HTTP 409) - `POST https://127.0.0.1:9001/users 409 (Conflict)`
  * **Workaround:** Delete the file `/node-sample/users.json` and restart the sample app.


text:
package org.apache.asterix.external.indexing.dataflow;

import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.ByteBuffer;

import org.apache.asterix.external.indexing.input.ILookupReader;
import org.apache.asterix.metadata.external.IndexingConstants;
import org.apache.asterix.om.base.AInt32;
import org.apache.asterix.om.base.AInt64;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.hyracks.api.comm.IFrameWriter;
import org.apache.hyracks.api.comm.VSizeFrame;
import org.apache.hyracks.api.context.IHyracksTaskContext;
import org.apache.hyracks.api.dataflow.value.INullWriter;
import org.apache.hyracks.api.dataflow.value.INullWriterFactory;
import org.apache.hyracks.api.dataflow.value.RecordDescriptor;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
import org.apache.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
import org.apache.hyracks.dataflow.common.comm.io.FrameTupleAppender;
import org.apache.hyracks.dataflow.common.comm.util.ByteBufferInputStream;
import org.apache.hyracks.dataflow.common.data.accessors.FrameTupleReference;

public class SeqOrTxtControlledTupleParser implements IControlledTupleParser {

    private ArrayTupleBuilder tb;
    private transient DataOutput dos;
    private final FrameTupleAppender appender;
    private boolean propagateInput;
    private int[] propagatedFields;
    private FrameTupleReference frameTuple;
    private IAsterixHDFSRecordParser parser;
    private ILookupReader reader;
    private int[] ridFields;
    private RecordDescriptor inRecDesc;
    private FrameTupleAccessor tupleAccessor;
    private ByteBufferInputStream bbis;
    private DataInputStream dis;
    private boolean retainNull;
    protected byte nullByte;
    protected ArrayTupleBuilder nullTupleBuild;

    public SeqOrTxtControlledTupleParser(IHyracksTaskContext ctx, IAsterixHDFSRecordParser parser,
            ILookupReader reader, boolean propagateInput, int[] propagatedFields, RecordDescriptor inRecDesc,
            int[] ridFields, boolean retainNull, INullWriterFactory iNullWriterFactory) throws HyracksDataException {
        appender = new FrameTupleAppender(new VSizeFrame(ctx));
        this.parser = parser;
        this.reader = reader;
        this.propagateInput = propagateInput;
        this.ridFields = ridFields;
        this.retainNull = retainNull;
        if (propagateInput) {
            tb = new ArrayTupleBuilder(propagatedFields.length + 1);
            frameTuple = new FrameTupleReference();
            this.propagatedFields = propagatedFields;
        } else {
            tb = new ArrayTupleBuilder(1);
        }
        dos = tb.getDataOutput();
        this.tupleAccessor = new FrameTupleAccessor(inRecDesc);
        bbis = new ByteBufferInputStream();
        dis = new DataInputStream(bbis);
        nullByte = ATypeTag.NULL.serialize();
        if (retainNull) {
            INullWriter nullWriter = iNullWriterFactory.createNullWriter();
            nullTupleBuild = new ArrayTupleBuilder(1);
            DataOutput out = nullTupleBuild.getDataOutput();
            try {
                nullWriter.writeNull(out);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            nullTupleBuild = null;
        }
    }

    @Override
    public void close(IFrameWriter writer) throws Exception {
        try {
            reader.close();
            appender.flush(writer, true);
        } catch (IOException ioe) {
            throw new HyracksDataException(ioe);
        }
    }

    @Override
    public void parseNext(IFrameWriter writer, ByteBuffer frameBuffer) throws HyracksDataException {
        try {
            int tupleCount = 0;
            int tupleIndex = 0;
            Object record;
            tupleAccessor.reset(frameBuffer);
            tupleCount = tupleAccessor.getTupleCount();
            int fieldSlotsLength = tupleAccessor.getFieldSlotsLength();
            // Loop over incoming tuples
            while (tupleIndex < tupleCount) {
                int tupleStartOffset = tupleAccessor.getTupleStartOffset(tupleIndex) + fieldSlotsLength;
                int fileNumberStartOffset = tupleAccessor.getFieldStartOffset(tupleIndex,
                        ridFields[IndexingConstants.FILE_NUMBER_FIELD_INDEX]);
                // Check if null <- for outer join ->
                if (frameBuffer.get(tupleStartOffset + fileNumberStartOffset) == nullByte) {
                    record = null;
                } else {
                    // Get file number
                    bbis.setByteBuffer(frameBuffer, tupleStartOffset + fileNumberStartOffset);
                    int fileNumber = ((AInt32) inRecDesc.getFields()[ridFields[IndexingConstants.FILE_NUMBER_FIELD_INDEX]]
                            .deserialize(dis)).getIntegerValue();
                    // Get record offset
                    bbis.setByteBuffer(
                            frameBuffer,
                            tupleStartOffset
                                    + tupleAccessor.getFieldStartOffset(tupleIndex,
                                            ridFields[IndexingConstants.RECORD_OFFSET_FIELD_INDEX]));
                    long recordOffset = ((AInt64) inRecDesc.getFields()[ridFields[IndexingConstants.RECORD_OFFSET_FIELD_INDEX]]
                            .deserialize(dis)).getLongValue();
                    // Read the record
                    record = reader.read(fileNumber, recordOffset);
                }
                if (record != null) {
                    tb.reset();
                    if (propagateInput) {
                        frameTuple.reset(tupleAccessor, tupleIndex);
                        for (int i = 0; i < propagatedFields.length; i++) {
                            dos.write(frameTuple.getFieldData(propagatedFields[i]),
                                    frameTuple.getFieldStart(propagatedFields[i]),
                                    frameTuple.getFieldLength(propagatedFields[i]));
                            tb.addFieldEndOffset();
                        }
                    }
                    // parse it
                    parser.parse(record, tb.getDataOutput());
                    tb.addFieldEndOffset();
                    addTupleToFrame(writer);
                } else if (propagateInput && retainNull) {
                    tb.reset();
                    frameTuple.reset(tupleAccessor, tupleIndex);
                    for (int i = 0; i < propagatedFields.length; i++) {
                        dos.write(frameTuple.getFieldData(propagatedFields[i]),
                                frameTuple.getFieldStart(propagatedFields[i]),
                                frameTuple.getFieldLength(propagatedFields[i]));
                        tb.addFieldEndOffset();
                    }
                    dos.write(nullTupleBuild.getByteArray());
                    tb.addFieldEndOffset();
                    addTupleToFrame(writer);
                }
                tupleIndex++;
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                reader.close();
            } catch (Exception e2) {
                e.addSuppressed(e2);
            }
            throw new HyracksDataException(e);
        }
    }

    private void addTupleToFrame(IFrameWriter writer) throws HyracksDataException {
        if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
            appender.flush(writer, true);
            if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
                throw new IllegalStateException();
            }
        }
    }

}


text:
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **int** | Unique ID | [optional]
**address_id** | **int** | Address ID asociated with this email address | [optional]
**country_code** | **string** | Phone number Country Code | [optional]
**phone_nr_type_name** | **string** | Phone number type name | [optional]
**nr** | **string** | Phone number | [optional]
**description** | **string** | Phone number description | [optional]
**primary** | **bool** | primary phone number | [optional]

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


text:
email = 'your email'
password = 'your password'


text:
package com.zimbra.bp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;

import com.zimbra.common.account.Key;
import com.zimbra.common.account.Key.DomainBy;
import com.zimbra.common.localconfig.LC;
import com.zimbra.common.mailbox.ContactConstants;
import com.zimbra.common.service.ServiceException;
import com.zimbra.common.soap.AdminExtConstants;
import com.zimbra.common.soap.Element;
import com.zimbra.common.util.EmailUtil;
import com.zimbra.common.util.StringUtil;
import com.zimbra.common.util.ZimbraLog;
import com.zimbra.cs.account.Account;
import com.zimbra.cs.account.AccountServiceException;
import com.zimbra.cs.account.Domain;
import com.zimbra.cs.account.GalContact;
import com.zimbra.cs.account.Provisioning;
import com.zimbra.cs.account.Provisioning.GalMode;
import com.zimbra.cs.account.Provisioning.SearchGalResult;
import com.zimbra.cs.account.accesscontrol.AdminRight;
import com.zimbra.cs.account.accesscontrol.PseudoTarget;
import com.zimbra.cs.account.accesscontrol.Rights.Admin;
import com.zimbra.cs.account.accesscontrol.TargetType;
import com.zimbra.cs.account.gal.GalOp;
import com.zimbra.cs.account.gal.GalParams;
import com.zimbra.cs.account.ldap.LdapGalMapRules;
import com.zimbra.cs.account.ldap.LdapGalSearch;
import com.zimbra.cs.ldap.LdapConstants;
import com.zimbra.cs.mailbox.ACL;
import com.zimbra.cs.mailbox.Folder;
import com.zimbra.cs.mailbox.MailItem;
import com.zimbra.cs.mailbox.MailServiceException;
import com.zimbra.cs.mailbox.Mailbox;
import com.zimbra.cs.mailbox.MailboxManager;
import com.zimbra.cs.service.FileUploadServlet;
import com.zimbra.cs.service.admin.AdminDocumentHandler;
import com.zimbra.cs.service.admin.AdminFileDownload;
import com.zimbra.cs.service.admin.AdminService;
import com.zimbra.soap.ZimbraSoapContext;
import com.zimbra.soap.admin.type.DataSourceType;

/**
 * @author Greg Solovyev
 */
public class BulkImportAccounts extends AdminDocumentHandler {

    public static final String ERROR_INVALID_ACCOUNT_NAME = "Invalid account name. ";
    private static final int DEFAULT_PWD_LENGTH = 8;

    @Override
    public Element handle(Element request, Map<String, Object> context) throws ServiceException {
        ZimbraSoapContext zsc = getZimbraSoapContext(context);
        Map attrs = AdminService.getAttrs(request, true);
        String op = request.getAttribute(AdminExtConstants.A_op);
        Element response = zsc.createElement(AdminExtConstants.BULK_IMPORT_ACCOUNTS_RESPONSE);
        Provisioning prov = Provisioning.getInstance();
        if (ZimbraBulkProvisionExt.OP_PREVIEW.equalsIgnoreCase(op) || ZimbraBulkProvisionExt.OP_START_IMPORT.equalsIgnoreCase(op)) {
            int totalAccounts = 0;
            int totalExistingAccounts = 0;
            String SMTPHost = "";
            String SMTPPort = "";
            String zimbraMailTransport = "";
            boolean createDomains = "TRUE".equalsIgnoreCase(request.getElement(AdminExtConstants.E_createDomains).getTextTrim());

            Element eSMTPHost = request.getOptionalElement(AdminExtConstants.E_SMTPHost);
            if (eSMTPHost != null) {
                SMTPHost = eSMTPHost.getTextTrim();
            }
            Element eSMTPPort = request.getOptionalElement(AdminExtConstants.E_SMTPPort);
            if (eSMTPPort != null) {
                SMTPPort = eSMTPPort.getTextTrim();
            }
            if (SMTPPort.length() > 0 && SMTPHost.length() > 0) {
                zimbraMailTransport = "smtp:" + SMTPHost + ":" + SMTPPort;
            }

            /**
             * list of entries found in the source (CSV file, XML file or directory)
             */
            List<Map<String, Object>> sourceEntries = new ArrayList<Map<String, Object>>();

            String sourceType = request.getElement(AdminExtConstants.A_sourceType).getTextTrim();
            if (sourceType.equalsIgnoreCase(AdminFileDownload.FILE_FORMAT_BULK_CSV)) {
                String aid = request.getElement(AdminExtConstants.E_attachmentID).getTextTrim();
                ZimbraLog.extensions.debug("Uploaded CSV file id = " + aid);
                // response.addElement(E_attachmentID).addText(aid);
                FileUploadServlet.Upload up = FileUploadServlet.fetchUpload(zsc.getAuthtokenAccountId(), aid, zsc.getAuthToken());
                if (up == null) {
                    throw ServiceException.FAILURE("Uploaded CSV file with id " + aid + " was not found.", null);
                }
                InputStream in = null;
                CSVReader reader = null;
                try {
                    in = up.getInputStream();
                    reader = new CSVReader(new InputStreamReader(in));
                    String[] nextLine;

                    List<String[]> allEntries = reader.readAll();
                    int totalNumberOfEntries = allEntries.size();

                    checkAccountLimits(allEntries, zsc, prov);

                    /**
                     * Iterate through records obtained from CSV file and add
                     * each record to sourceEntries
                     */
                    for (int i = 0; i < totalNumberOfEntries; i++) {
                        nextLine = allEntries.get(i);
                        boolean isValidEntry = false;
                        try {
                            isValidEntry = validEntry(nextLine, zsc);
                        } catch (ServiceException e) {
                            ZimbraLog.extensions.error(e);
                            throw e;
                        }

                        if (!isValidEntry) {
                            throw ServiceException.INVALID_REQUEST(String.format("Entry %d is not valid (%s %s %s %s %s %s)", i,
                                    nextLine[0], nextLine[1], nextLine[2], nextLine[3], nextLine[4], nextLine[5]), null);
                        }
                        String userEmail = nextLine[0].trim();
                        String parts[] = EmailUtil.getLocalPartAndDomain(userEmail);
                        if (parts == null) {
                            throw ServiceException.INVALID_REQUEST("must be valid email address: " + userEmail, null);
                        }

                        Domain domain = prov.getDomainByName(parts[1]);
                        if (domain != null) {
                            checkDomainRight(zsc, domain, Admin.R_createAccount);
                        } else if (createDomains) {
                            if (ZimbraBulkProvisionExt.OP_START_IMPORT.equalsIgnoreCase(op)) {
                                domain = createMissingDomain(parts[1], zsc, context);
                            }
                            checkDomainRight(zsc, domain, Admin.R_createAccount);
                        } else {
                            throw AccountServiceException.NO_SUCH_DOMAIN(parts[1]);
                        }
                        Account acct = Provisioning.getInstance().getAccountByName(userEmail);
                        if (acct != null) {
                            totalExistingAccounts++;
                        } else {
                            Map<String, Object> accAttrs = new HashMap<String, Object>();
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_displayName, nextLine[1].trim());
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_givenName, nextLine[2].trim());
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_sn, nextLine[3].trim());
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraPasswordMustChange, nextLine[5].trim());

                            checkSetAttrsOnCreate(zsc, TargetType.account, userEmail, accAttrs);

                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_mail, userEmail);
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_userPassword, nextLine[4].trim());
                            if (zimbraMailTransport.length() > 0) {
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraMailTransport, zimbraMailTransport);
                            }
                            sourceEntries.add(accAttrs);
                        }
                        totalAccounts++;
                    }

                    in.close();

                } catch (IOException e) {
                    throw ServiceException.FAILURE("", e);
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            ZimbraLog.extensions.error(e);
                        }
                    }
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            ZimbraLog.extensions.error(e);
                        }
                    }

                }
            } else if (sourceType.equalsIgnoreCase(AdminFileDownload.FILE_FORMAT_BULK_XML)) {
                String aid = request.getElement(AdminExtConstants.E_attachmentID).getTextTrim();
                ZimbraLog.extensions.debug("Uploaded XML file id = " + aid);
                FileUploadServlet.Upload up = FileUploadServlet.fetchUpload(zsc.getAuthtokenAccountId(), aid, zsc.getAuthToken());
                if (up == null) {
                    throw ServiceException.FAILURE("Uploaded CSV file with id " + aid + " was not found.", null);
                }
                SAXReader reader = new SAXReader();
                try {
                    Document doc = reader.read(up.getInputStream());
                    org.dom4j.Element root = doc.getRootElement();
                    if (!root.getName().equals(AdminExtConstants.E_ZCSImport)) {
                        throw new DocumentException("Bulk provisioning XML file's root element must be "
                                + AdminExtConstants.E_ZCSImport);
                    }
                    Iterator iter = root.elementIterator(AdminExtConstants.E_ImportUsers);
                    if (!iter.hasNext()) {
                        throw new DocumentException("Cannot find element " + AdminExtConstants.E_ImportUsers
                                + " in uploaded bulk provisioning XML file");
                    }

                    /**
                     * Settings from SOAP request take preference over settings in the XML file
                     */
                    if (SMTPHost.length() == 0) {
                        Iterator iterMTPHost = root.elementIterator(AdminExtConstants.E_SMTPHost);
                        if (iterMTPHost.hasNext()) {
                            org.dom4j.Element elSMTPHost = (org.dom4j.Element) iterMTPHost.next();
                            SMTPHost = elSMTPHost.getTextTrim();
                        }
                    }
                    if (SMTPPort.length() == 0) {
                        Iterator iterSMTPort = root.elementIterator(AdminExtConstants.E_SMTPPort);
                        if (iterSMTPort.hasNext()) {
                            org.dom4j.Element elSMTPPort = (org.dom4j.Element) iterSMTPort.next();
                            SMTPPort = elSMTPPort.getTextTrim();
                        }
                    }
                    if (zimbraMailTransport.length() == 0) {
                        if (SMTPPort.length() > 0 && SMTPHost.length() > 0) {
                            zimbraMailTransport = "smtp:" + SMTPHost + ":" + SMTPPort;
                        }
                    }
                    org.dom4j.Element elImportUsers = (org.dom4j.Element) iter.next();
                    for (Iterator userIter = elImportUsers.elementIterator(AdminExtConstants.E_User); userIter.hasNext();) {
                        org.dom4j.Element elUser = (org.dom4j.Element) userIter.next();
                        String userEmail = "";
                        String userFN = "";
                        String userLN = "";
                        String userDN = "";
                        String userPassword = "";
                        String userPwdMustChange = "FALSE";
                        for (Iterator userPropsIter = elUser.elementIterator(); userPropsIter.hasNext();) {
                            org.dom4j.Element el = (org.dom4j.Element) userPropsIter.next();
                            /*
                             * We support <ExchangeMail> element for
                             * compatibility with desktop based Exchange
                             * Migration utility <RemoteEmailAddress> takes
                             * prevalence over <ExchangeMail> element
                             */
                            if (userEmail == "" && AdminExtConstants.E_ExchangeMail.equalsIgnoreCase(el.getName())) {
                                userEmail = el.getTextTrim();
                            }
                            if (AdminExtConstants.E_remoteEmail.equalsIgnoreCase(el.getName())) {
                                userEmail = el.getTextTrim();
                            }
                            if (Provisioning.A_displayName.equalsIgnoreCase(el.getName())) {
                                userDN = el.getTextTrim();
                            }

                            if (Provisioning.A_givenName.equalsIgnoreCase(el.getName())) {
                                userFN = el.getTextTrim();
                            }

                            if (Provisioning.A_sn.equalsIgnoreCase(el.getName())) {
                                userLN = el.getTextTrim();
                            }

                            if (AdminExtConstants.A_password.equalsIgnoreCase(el.getName())) {
                                userPassword = el.getTextTrim();
                            }

                            if (Provisioning.A_zimbraPasswordMustChange.equalsIgnoreCase(el.getName())) {
                                userPwdMustChange = el.getTextTrim();
                            }
                        }
                        String parts[] = EmailUtil.getLocalPartAndDomain(userEmail);
                        if (parts == null) {
                            throw ServiceException.INVALID_REQUEST("must be valid email address: " + userEmail, null);
                        }

                        Domain domain = prov.getDomainByName(parts[1]);
                        if (domain != null) {
                            checkDomainRight(zsc, domain, Admin.R_createAccount);
                        } else if (createDomains) {
                            domain = createMissingDomain(parts[1], zsc, context);
                            checkDomainRight(zsc, domain, Admin.R_createAccount);
                        } else {
                            throw AccountServiceException.NO_SUCH_DOMAIN(parts[1]);
                        }

                        Account acct = Provisioning.getInstance().getAccountByName(userEmail);
                        if (acct != null) {
                            totalExistingAccounts++;
                        } else {
                            Map<String, Object> accAttrs = new HashMap<String, Object>();
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_givenName, userFN);
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_displayName, userDN);
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_sn, userLN);
                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraPasswordMustChange, userPwdMustChange);

                            checkSetAttrsOnCreate(zsc, TargetType.account, userEmail, accAttrs);

                            StringUtil.addToMultiMap(accAttrs, Provisioning.A_mail, userEmail);
                            if (userPassword != null) {
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_userPassword, userPassword);
                            }
                            if (zimbraMailTransport.length() > 0) {
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraMailTransport, zimbraMailTransport);
                            }
                            sourceEntries.add(accAttrs);
                        }
                        totalAccounts++;
                    }

                } catch (DocumentException e) {
                    throw ServiceException.FAILURE("Bulk provisioning failed to read uploaded XML document.", e);
                } catch (IOException e) {
                    throw ServiceException.FAILURE("Bulk provisioning failed to read uploaded XML document.", e);
                }
            } else if (sourceType.equalsIgnoreCase(ZimbraBulkProvisionExt.FILE_FORMAT_BULK_LDAP)) {
                GalParams.ExternalGalParams galParams = new GalParams.ExternalGalParams(attrs, GalOp.search);
                LdapGalMapRules rules = new LdapGalMapRules(Provisioning.getInstance().getConfig(), true);

                Element elPassword = request.getOptionalElement(AdminExtConstants.A_password);
                Element elPasswordLength = request.getOptionalElement(AdminExtConstants.A_genPasswordLength);

                String generatePwd = request.getElement(AdminExtConstants.A_generatePassword).getTextTrim();

                int genPwdLength = 0;
                if (generatePwd == null) {
                    generatePwd = "false";
                } else if (generatePwd.equalsIgnoreCase("true")) {
                    if (elPasswordLength != null) {
                        genPwdLength = Integer.valueOf(elPasswordLength.getTextTrim());
                    } else {
                        genPwdLength = DEFAULT_PWD_LENGTH;
                    }
                    if (genPwdLength < 1) {
                        genPwdLength = DEFAULT_PWD_LENGTH;
                    }
                }

                int maxResults = 0;
                Element elMaxResults = request.getOptionalElement(AdminExtConstants.A_maxResults);
                if (elMaxResults != null) {
                    maxResults = Integer.parseInt(elMaxResults.getTextTrim());
                }

                String password = null;
                if (elPassword != null) {
                    password = elPassword.getTextTrim();
                }
                String mustChangePassword = request.getElement(AdminExtConstants.E_mustChangePassword).getTextTrim();
                if (SMTPPort.length() > 0 && SMTPHost.length() > 0) {
                    zimbraMailTransport = "smtp:" + SMTPHost + ":" + SMTPPort;
                }
                try {
                    SearchGalResult result = LdapGalSearch.searchLdapGal(galParams, GalOp.search, "*", maxResults, rules, null,
                            null);
                    List<GalContact> entries = result.getMatches();

                    if (entries != null) {
                        for (GalContact entry : entries) {
                            String emailAddress = entry.getSingleAttr(ContactConstants.A_email);
                            if (emailAddress == null) {
                                continue;
                            }

                            String parts[] = EmailUtil.getLocalPartAndDomain(emailAddress);
                            if (parts == null) {
                                throw ServiceException.INVALID_REQUEST("must be valid email address: " + emailAddress, null);
                            }

                            Domain domain = prov.getDomainByName(parts[1]);
                            if (domain != null) {
                                checkDomainRight(zsc, domain, Admin.R_createAccount);
                            } else if (createDomains) {
                                if (ZimbraBulkProvisionExt.OP_START_IMPORT.equalsIgnoreCase(op)) {
                                    domain = createMissingDomain(parts[1], zsc, context);
                                }
                                checkDomainRight(zsc, domain, Admin.R_createAccount);
                            } else {
                                throw AccountServiceException.NO_SUCH_DOMAIN(parts[1]);
                            }
                            if (domain != null) {
                                checkDomainRight(zsc, domain, Admin.R_createAccount);
                            } else {
                                throw AccountServiceException.NO_SUCH_DOMAIN(parts[1]);
                            }
                            Account acct = Provisioning.getInstance().getAccountByName(emailAddress);
                            if (acct != null) {
                                totalExistingAccounts++;
                            } else {
                                Map<String, Object> accAttrs = new HashMap<String, Object>();
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_givenName,
                                        entry.getSingleAttr(ContactConstants.A_firstName));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_displayName,
                                        entry.getSingleAttr(ContactConstants.A_fullName));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_sn,
                                        entry.getSingleAttr(ContactConstants.A_lastName));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_initials,
                                        entry.getSingleAttr(ContactConstants.A_initials));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_description,
                                        entry.getSingleAttr(ContactConstants.A_notes));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_telephoneNumber,
                                        entry.getSingleAttr(ContactConstants.A_homePhone));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_mobile,
                                        entry.getSingleAttr(ContactConstants.A_mobilePhone));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_homePhone,
                                        entry.getSingleAttr(ContactConstants.A_homePhone));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_l,
                                        entry.getSingleAttr(ContactConstants.A_homeCity));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_st,
                                        entry.getSingleAttr(ContactConstants.A_homeState));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_co,
                                        entry.getSingleAttr(ContactConstants.A_homeCountry));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_postalCode,
                                        entry.getSingleAttr(ContactConstants.A_homePostalCode));
                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_street,
                                        entry.getSingleAttr(ContactConstants.A_homeAddress));
                                if (zimbraMailTransport.length() > 0) {
                                    StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraMailTransport, zimbraMailTransport);
                                }
                                if ("true".equalsIgnoreCase(mustChangePassword)) {
                                    StringUtil.addToMultiMap(accAttrs, Provisioning.A_zimbraPasswordMustChange, "TRUE");
                                }
                                checkSetAttrsOnCreate(zsc, TargetType.account, emailAddress, accAttrs);

                                StringUtil.addToMultiMap(accAttrs, Provisioning.A_mail,
                                        entry.getSingleAttr(ContactConstants.A_email));
                                if (password != null) {
                                    StringUtil.addToMultiMap(accAttrs, Provisioning.A_userPassword, password);
                                } else if (generatePwd.equalsIgnoreCase("true")) {
                                    StringUtil.addToMultiMap(accAttrs, Provisioning.A_userPassword,
                                            String.valueOf(generateStrongPassword(genPwdLength)));
                                }

                                sourceEntries.add(accAttrs);
                            }
                            totalAccounts++;
                        }

                    }
                } catch (ServiceException e) {
                    throw ServiceException.FAILURE("", e);
                }
            } else {
                throw ServiceException.INVALID_REQUEST(sourceType + " is not a valid value for parameter "
                        + AdminExtConstants.A_sourceType, null);
            }
            if (ZimbraBulkProvisionExt.OP_PREVIEW.equalsIgnoreCase(op)) {
                /*
                 * Do not start the import. Just generate a preview.
                 */
                response.addElement(AdminExtConstants.E_totalCount).setText(Integer.toString(totalAccounts));
                response.addElement(AdminExtConstants.E_skippedAccountCount).setText(Integer.toString(totalExistingAccounts));
                response.addElement(AdminExtConstants.E_SMTPHost).setText(SMTPHost);
                response.addElement(AdminExtConstants.E_SMTPPort).setText(SMTPPort);

            } else if (ZimbraBulkProvisionExt.OP_START_IMPORT.equalsIgnoreCase(op)) {
                /*
                 * Spin off a provisioning thread
                 */
                if (sourceEntries.size() > 0) {
                    BulkProvisioningThread thread = BulkProvisioningThread.getThreadInstance(zsc.getAuthtokenAccountId(), true);
                    int status = thread.getStatus();
                    if (status == BulkProvisioningThread.iSTATUS_FINISHED) {
                        BulkProvisioningThread.deleteThreadInstance(zsc.getAuthtokenAccountId());
                        thread = BulkProvisioningThread.getThreadInstance(zsc.getAuthtokenAccountId(), true);
                        status = thread.getStatus();
                    }
                    if (status != BulkProvisioningThread.iSTATUS_IDLE) {
                        throw BulkProvisionException.BP_IMPORT_ALREADY_RUNNING();
                    }
                    thread.setSourceAccounts(sourceEntries);
                    thread.start();
                    response.addElement(AdminExtConstants.E_status).setText(Integer.toString(thread.getStatus()));
                } else {
                    throw BulkProvisionException.BP_NO_ACCOUNTS_TO_IMPORT();
                }
            }
        }

        if (ZimbraBulkProvisionExt.OP_ABORT_IMPORT.equalsIgnoreCase(op)) {
            BulkProvisioningThread thread = BulkProvisioningThread.getThreadInstance(zsc.getAuthtokenAccountId(), false);
            if (thread != null) {
                int status = thread.getStatus();
                if (status != BulkProvisioningThread.iSTATUS_FINISHED) {
                    thread.abort();
                    response.addElement(AdminExtConstants.E_status).setText(Integer.toString(thread.getStatus()));
                    response.addElement(AdminExtConstants.E_provisionedCount).setText(
                            Integer.toString(thread.getProvisionedCounter()));
                    response.addElement(AdminExtConstants.E_skippedCount).setText(Integer.toString(thread.getSkippedCounter()));
                    response.addElement(AdminExtConstants.E_totalCount).setText(Integer.toString(thread.getTotalCount()));
                    if (thread.getWithErrors()) {
                        response.addElement(AdminExtConstants.E_errorCount).addText(Integer.toString(thread.getFailCounter()));
                    }
                    status = thread.getStatus();
                    if (status == BulkProvisioningThread.iSTATUS_ABORTED) {
                        BulkProvisioningThread.deleteThreadInstance(zsc.getAuthtokenAccountId());
                    }
                } else {
                    response.addElement(AdminExtConstants.E_status).setText(Integer.toString(status));
                }
            } else {
                response.addElement(AdminExtConstants.E_status).setText(
                        Integer.toString(BulkProvisioningThread.iSTATUS_NOT_RUNNING));
            }
        } else if (ZimbraBulkProvisionExt.OP_GET_STATUS.equalsIgnoreCase(op)) {
            BulkProvisioningThread thread = BulkProvisioningThread.getThreadInstance(zsc.getAuthtokenAccountId(), false);
            if (thread != null) {
                int status = thread.getStatus();
                response.addElement(AdminExtConstants.E_status).setText(Integer.toString(status));
                response.addElement(AdminExtConstants.E_provisionedCount).setText(
                        Integer.toString(thread.getProvisionedCounter()));
                response.addElement(AdminExtConstants.E_skippedCount).setText(Integer.toString(thread.getSkippedCounter()));
                response.addElement(AdminExtConstants.E_totalCount).setText(Integer.toString(thread.getTotalCount()));
                if (thread.getWithErrors()) {
                    response.addElement(AdminExtConstants.E_errorCount).addText(Integer.toString(thread.getFailCounter()));
                }
                if (status == BulkProvisioningThread.iSTATUS_FINISHED || status == BulkProvisioningThread.iSTATUS_ABORTED
                        || status == BulkProvisioningThread.iSTATUS_ERROR) {
                    String fileToken = Double.toString(Math.random() * 100);
                    String outSuccessFileName = String.format("%s%s_bulk_report_%s_%s.csv", LC.zimbra_tmp_directory.value(),
                            File.separator, zsc.getAuthtokenAccountId(), fileToken);
                    FileOutputStream outReport = null;
                    CSVWriter reportWriter = null;
                    try {
                        outReport = new FileOutputStream(outSuccessFileName);
                        reportWriter = new CSVWriter(new OutputStreamWriter(outReport));
                        for (String completedAccount : thread.getCompletedAccounts().keySet()) {
                            String[] line = new String[2];
                            line[0] = completedAccount; // account name
                            line[1] = thread.getCompletedAccounts().get(completedAccount); // account password
                            reportWriter.writeNext(line);
                        }
                        reportWriter.close();
                    } catch (FileNotFoundException e) {
                        throw ServiceException.FAILURE("Failed to create CSV file with a list of provisioned accounts", e);
                    } catch (IOException e) {
                        throw ServiceException.FAILURE("Failed to create CSV file with a list of provisioned accounts", e);
                    } finally {
                        if (reportWriter != null) {
                            try {
                                reportWriter.close();
                            } catch (IOException e) {
                                ZimbraLog.extensions.error(e);
                            }
                        }

                        if (outReport != null) {
                            try {
                                outReport.close();
                            } catch (IOException e) {
                                ZimbraLog.extensions.error(e);
                            }
                        }
                    }
                    response.addElement(AdminExtConstants.E_reportFileToken).addText(fileToken);
                    /**
                     * if thread is done for whichever reason and there are
                     * errors, generate an error report
                     */
                    if (thread.getWithErrors()) {
                        FileOutputStream out = null;
                        CSVWriter errorWriter = null;
                        try {
                            String outErrorsFileName = String.format("%s%s_bulk_errors_%s_%s.csv",
                                    LC.zimbra_tmp_directory.value(), File.separator, zsc.getAuthtokenAccountId(), fileToken);
                            out = new FileOutputStream(outErrorsFileName);
                            errorWriter = new CSVWriter(new OutputStreamWriter(out));
                            for (String failedAccount : thread.getfailedAccounts().keySet()) {
                                String[] line = new String[2];
                                line[0] = failedAccount;
                                line[1] = thread.getfailedAccounts().get(failedAccount).getMessage();
                                errorWriter.writeNext(line);
                            }
                            errorWriter.close();
                        } catch (FileNotFoundException e) {
                            throw ServiceException.FAILURE("Failed to create CSV file with error report", e);
                        } catch (IOException e) {
                            throw ServiceException.FAILURE("Failed to create CSV file with error report", e);
                        } finally {
                            if (errorWriter != null) {
                                try {
                                    errorWriter.close();
                                } catch (IOException e) {
                                    ZimbraLog.extensions.error(e);
                                }
                            }
                            if (out != null) {
                                try {
                                    out.close();
                                } catch (IOException e) {
                                    ZimbraLog.extensions.error(e);
                                }
                            }
                        }
                    }
                    BulkProvisioningThread.deleteThreadInstance(zsc.getAuthtokenAccountId());
                }
            } else {
                response.addElement(AdminExtConstants.E_status).setText(
                        Integer.toString(BulkProvisioningThread.iSTATUS_NOT_RUNNING));
            }
        }
        return response;
    }

    private static char[] pwdChars = "abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~!@#$%^&*().,;:`<>?-+|}{[]'\""
            .toCharArray();

    private static int getIntFromByte(byte[] bytes) {
        int returnNumber = 0;
        int pos = 0;
        returnNumber += byteToInt(bytes[pos++]) << 24;
        returnNumber += byteToInt(bytes[pos++]) << 16;
        returnNumber += byteToInt(bytes[pos++]) << 8;
        returnNumber += byteToInt(bytes[pos++]) << 0;
        return returnNumber;
    }

    private static int byteToInt(byte b) {
        return b & 0xFF;
    }

    public static char[] generateStrongPassword(int length) {
        char[] pwd = new char[length];
        try {
            java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG");

            byte[] intbytes = new byte[4];

            for (int i = 0; i < length; i++) {
                random.nextBytes(intbytes);
                pwd[i] = pwdChars[Math.abs(getIntFromByte(intbytes) % pwdChars.length)];
            }
        } catch (Exception ex) {
            // Don't really worry, we won't be using this if we can't use securerandom anyway
        }
        return pwd;
    }

    /**
     * The account limits are decided by the following factors: 1) Hard limit:
     * MAX_ACCOUNTS_LIMIT or accountLimit - License Account Limit (whichever is
     * smaller) 2) zimbraDomainMaxAccounts
     *
     * @param allEntries
     * @throws ServiceException
     */
    private void checkAccountLimits(List<String[]> allEntries, ZimbraSoapContext zsc, Provisioning prov) throws ServiceException {
        ZimbraLog.extensions.debug("Check the account limits ...");
        int numberOfEntries = allEntries.size();

        // check against zimbraDomainMaxAccounts
        Hashtable<String, Integer> h = new Hashtable<String, Integer>();

        for (int i = 0; i < numberOfEntries; i++) {
            String[] entry = allEntries.get(i);
            String accountName = null;
            String parts[] = null;
            String domainName = null;

            if (entry != null) {
                accountName = entry[0];
            }
            if (accountName != null) {
                parts = accountName.trim().split("@");
            }
            if (parts != null && parts.length > 0) {
                domainName = parts[1];
            }
            if (domainName != null) {
                int count = 0;
                if (h.containsKey(domainName)) {
                    count = h.get(domainName).intValue();
                }
                h.put(domainName, count + 1);
            }
        }

        for (Enumeration<String> keys = h.keys(); keys.hasMoreElements();) {
            String domainName = keys.nextElement();
            Domain domain = prov.get(Key.DomainBy.name, domainName);
            if (domain != null) {
                String domainMaxAccounts = domain.getAttr(Provisioning.A_zimbraDomainMaxAccounts);
                if (domainMaxAccounts != null && domainMaxAccounts.length() > 0) {
                    int limit = Integer.parseInt(domainMaxAccounts);
                    int used = 0;
                    Provisioning.CountAccountResult result = prov.countAccount(domain);
                    for (Provisioning.CountAccountResult.CountAccountByCos c : result.getCountAccountByCos()) {
                        used += c.getCount();
                    }

                    int newAccounts = h.get(domainName).intValue();
                    int available = limit - used;
                    /*
                     * ZimbraLog.extensions.debug("For domain " + domainName +
                     * " : csv entry = " + newAccounts +
                     * ", zimbraDomainMaxAccounts = " + limit +
                     * ", used accounts = " + used) ;
                     */
                    if (newAccounts > available) {
                        throw BulkProvisionException
                                .BP_TOO_MANY_ACCOUNTS("the maximum accounts you can bulk provisioning for domain: " + domainName
                                        + " is " + available + "\n");
                    }
                }
            }
        }
    }

    private boolean validEntry(String[] entries, ZimbraSoapContext lc) throws ServiceException {
        Provisioning prov = Provisioning.getInstance();
        String errorMsg = "";
        if (entries.length != 6) {
            errorMsg = "Invalid number of columns.";
            throw ServiceException.PARSE_ERROR(errorMsg, new Exception(errorMsg));
        }

        String accountName = entries[0];

        // 1. account name is specified and can be accessed by current
        // admin/domain admin user
        if (accountName == null || accountName.length() <= 0) {
            throw ServiceException.PARSE_ERROR(ERROR_INVALID_ACCOUNT_NAME, new Exception(ERROR_INVALID_ACCOUNT_NAME));
        }
        accountName = accountName.trim();
        String parts[] = accountName.split("@");

        if (parts.length != 2) {
            throw ServiceException.PARSE_ERROR(ERROR_INVALID_ACCOUNT_NAME, new Exception(ERROR_INVALID_ACCOUNT_NAME));
        }

        return true;
    }

    private Domain createMissingDomain(String name, ZimbraSoapContext zsc, Map<String, Object> context) throws ServiceException {
        //
        // TODO: check permission has to be consolidated with the one in
        // CraeteDomain
        //

        // check permission
        if (name.indexOf('.') == -1) {
            // is a top domain
            checkRight(zsc, context, null, Admin.R_createTopDomain);
        } else {
            // go up the domain hierarchy see if any of the parent domains
            // exist.
            // If yes, check the createSubDomain right on the lowest existing
            // parent domain.
            // If not, allow it if the admin has both the createTopDomain on
            // globalgrant; and
            // use a pseudo Domain object as the target to check the
            // createSubDomain right
            // (because createSubDomain is a domain right, we cannot use
            // globalgrant for the target).
            String domainName = name;
            Domain parentDomain = null;
            while (parentDomain == null) {
                int nextDot = domainName.indexOf('.');
                if (nextDot == -1) {
                    // reached the top, check if the admin has the
                    // createTopDomain right on globalgrant
                    checkRight(zsc, context, null, Admin.R_createTopDomain);

                    // then create a pseudo domain for checking the
                    // createSubDomain right
                    parentDomain = PseudoTarget.createPseudoDomain(Provisioning.getInstance());
                    break;
                } else {
                    domainName = domainName.substring(nextDot + 1);
                    parentDomain = Provisioning.getInstance().get(DomainBy.name, domainName);
                }
            }
            checkRight(zsc, context, parentDomain, Admin.R_createSubDomain);
        }

        // create domain
        Map<String, Object> attrs = new HashMap<String, Object>();
        StringUtil.addToMultiMap(attrs, Provisioning.A_zimbraGalMode, "zimbra");
        StringUtil.addToMultiMap(attrs, Provisioning.A_zimbraAuthMech, "zimbra");
        StringUtil.addToMultiMap(attrs, Provisioning.A_zimbraGalMaxResults, "100");
        StringUtil.addToMultiMap(attrs, Provisioning.A_zimbraNotes, "automatically created by bulk provisioning");
        checkSetAttrsOnCreate(zsc, TargetType.domain, name, attrs);
        Domain domain = Provisioning.getInstance().createDomain(name, attrs);
        String acctValue = String.format("%s@%s", "galsync", name);

        // create galsync account
        Map<String, Object> accountAttrs = new HashMap<String, Object>();
        StringUtil.addToMultiMap(accountAttrs, Provisioning.A_zimbraIsSystemResource, LdapConstants.LDAP_TRUE);
        StringUtil.addToMultiMap(accountAttrs, Provisioning.A_zimbraHideInGal, LdapConstants.LDAP_TRUE);
        StringUtil.addToMultiMap(accountAttrs, Provisioning.A_zimbraContactMaxNumEntries, "0");
        checkSetAttrsOnCreate(zsc, TargetType.account, acctValue, accountAttrs);
        Account galSyncAccount = Provisioning.getInstance().createAccount(acctValue, null, accountAttrs);

        String acctId = galSyncAccount.getId();
        HashSet<String> galAcctIds = new HashSet<String>();
        galAcctIds.add(acctId);
        domain.setGalAccountId(galAcctIds.toArray(new String[0]));

        // create folder if not already exists.
        String folder = "/_zimbra";
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(galSyncAccount);
        Folder contactFolder = null;
        try {
            contactFolder = mbox.getFolderByPath(null, folder);
        } catch (MailServiceException.NoSuchItemException e) {
            Folder.FolderOptions fopt = new Folder.FolderOptions().setDefaultView(MailItem.Type.CONTACT);
            contactFolder = mbox.createFolder(null, folder, fopt);
        }

        int folderId = contactFolder.getId();

        mbox.grantAccess(null, folderId, domain.getId(), ACL.GRANTEE_DOMAIN, ACL.stringToRights("r"), null);

        // create datasource
        Map<String, Object> dsAttrs = new HashMap<String, Object>();
        try {
            dsAttrs.put(Provisioning.A_zimbraGalType, GalMode.zimbra.name());
            dsAttrs.put(Provisioning.A_zimbraDataSourcePollingInterval, "1d");
            dsAttrs.put(Provisioning.A_zimbraDataSourceFolderId, "" + folderId);
            dsAttrs.put(Provisioning.A_zimbraDataSourceEnabled, LdapConstants.LDAP_TRUE);
            dsAttrs.put(Provisioning.A_zimbraGalStatus, "enabled");
            Provisioning.getInstance().createDataSource(galSyncAccount, DataSourceType.gal, "zimbra", dsAttrs);
        } catch (ServiceException e) {
            ZimbraLog.extensions.error("error creating datasource for GalSyncAccount", e);
            throw e;
        }
        return domain;
    }

    @Override
    public void docRights(List<AdminRight> relatedRights, List<String> notes) {
        relatedRights.add(Admin.R_createAccount);
        relatedRights.add(Admin.R_listAccount);
        relatedRights.add(Admin.R_createTopDomain);
        relatedRights.add(Admin.R_createSubDomain);

        notes.add("Only accounts on which the authed admin has " + Admin.R_listAccount.getName() + " right will be provisioned.");
        notes.add(Admin.R_createTopDomain + " right is required in order to automatically create top level domains.");
        notes.add(Admin.R_createSubDomain + " right is required in order to automatically create sub-domains.");
    }
}